Search in sources :

Example 1 with I_VariableDefinition

use of org.ehrbase.aql.definition.I_VariableDefinition in project ehrbase by ehrbase.

the class OrderByField method merge.

public Statements merge() {
    // add order by fields as HIDDEN variables
    if (!containsOrderBy())
        return statements;
    for (OrderAttribute orderAttribute : statements.getOrderAttributes()) {
        I_VariableDefinition orderAttributeVariable = orderAttribute.getVariableDefinition();
        if (!isSelectVariable(orderAttributeVariable)) {
            // add it to the statement as an hidden variable
            I_VariableDefinition orderVariable = orderAttributeVariable.duplicate();
            orderVariable.setHidden(true);
            statements.put(orderVariable);
        }
    }
    return statements;
}
Also used : OrderAttribute(org.ehrbase.aql.compiler.OrderAttribute) I_VariableDefinition(org.ehrbase.aql.definition.I_VariableDefinition)

Example 2 with I_VariableDefinition

use of org.ehrbase.aql.definition.I_VariableDefinition in project ehrbase by ehrbase.

the class SuperQuery method selectAggregate.

@SuppressWarnings({ "deprecation", "unchecked" })
private SelectQuery selectAggregate(SelectQuery selectQuery) {
    List<Field> fields = new ArrayList<>();
    List<String> skipField = new ArrayList<>();
    Iterator<I_VariableDefinition> iterator = variableDefinitions.iterator();
    boolean distinctRequired = false;
    while (iterator.hasNext()) {
        I_VariableDefinition variableDefinition = iterator.next();
        String alias = variableDefinition.getAlias() == null || variableDefinition.getAlias().isEmpty() ? variableDefinition.getPath() : variableDefinition.getAlias();
        if (variableDefinition.isFunction()) {
            skipField.add(alias);
            FunctionExpression functionExpression = new FunctionExpression(variableDefinitions, variableDefinition);
            Field field = DSL.field(functionExpression.toString());
            skipField.addAll(functionExpression.arguments());
            if (variableDefinition.getAlias() != null) {
                field = field.as(alias);
            }
            fields.add(field);
        } else if (variableDefinition.isExtension()) {
        // do nothing... for the time being
        } else {
            // check if this alias is serviced by a function
            // check if this alias requires distinct
            distinctRequired = distinctRequired || variableDefinition.isDistinct();
            if (skipField.contains(alias))
                continue;
            if (variableDefinition.isDistinct())
                fields.add(DSL.fieldByName("DISTINCT " + alias));
            else
                fields.add(DSL.fieldByName(alias));
        }
    }
    selectQuery.addSelect(fields);
    selectQuery.addFrom(query);
    // aggregate return scalar values
    this.outputWithJson = false;
    return selectQuery;
}
Also used : Field(org.jooq.Field) ArrayList(java.util.ArrayList) I_VariableDefinition(org.ehrbase.aql.definition.I_VariableDefinition)

Example 3 with I_VariableDefinition

use of org.ehrbase.aql.definition.I_VariableDefinition in project ehrbase by ehrbase.

the class WhereBinder method bind.

public Condition bind(String templateId, int whereCursor, MultiFieldsMap multiWhereFieldsMap, MultiFieldsMap multiSelectFieldsMap) {
    boolean unresolvedVariable = false;
    if (whereClause.isEmpty())
        return null;
    TaggedStringBuilder taggedBuffer = new TaggedStringBuilder();
    // work on a copy since Exist is destructive
    List<Object> whereItems = new ArrayList<>(whereClause);
    boolean notExists = false;
    boolean inSubqueryOperator = false;
    for (int cursor = 0; cursor < whereItems.size(); cursor++) {
        Object item = whereItems.get(cursor);
        if (item instanceof String) {
            switch(((String) item).trim().toUpperCase()) {
                case OR:
                case XOR:
                case AND:
                    taggedBuffer = new WhereJsQueryExpression(taggedBuffer, requiresJSQueryClosure, isFollowedBySQLConditionalOperator).closure();
                    taggedBuffer.append(" " + item + " ");
                    break;
                case NOT:
                    // check if precedes 'EXISTS'
                    if (whereItems.get(cursor + 1).toString().equalsIgnoreCase(EXISTS))
                        notExists = true;
                    else {
                        taggedBuffer = new WhereJsQueryExpression(taggedBuffer, requiresJSQueryClosure, isFollowedBySQLConditionalOperator).closure();
                        taggedBuffer.append(" " + item + " ");
                    }
                    break;
                case IN:
                case ANY:
                case SOME:
                case ALL:
                    if (((String) item).trim().toUpperCase().matches("ANY|SOME|ALL"))
                        inSubqueryOperator = true;
                    taggedBuffer.append((String) item);
                    break;
                case EXISTS:
                    // add the comparison to null after the variable expression
                    whereItems.add(cursor + 2, notExists ? "IS " : "IS NOT ");
                    whereItems.add(cursor + 3, "NULL");
                    notExists = false;
                    break;
                default:
                    ISODateTime isoDateTime = new ISODateTime(((String) item).replace("'", ""));
                    if (isoDateTime.isValidDateTimeExpression()) {
                        // this to align with epoch_offset in the DB, ignore ms
                        long timestamp = isoDateTime.toTimeStamp() / 1000;
                        int lastValuePos = taggedBuffer.lastIndexOf(VALUETYPE_EXPR_VALUE);
                        if (lastValuePos > 0) {
                            taggedBuffer.replaceLast(VALUETYPE_EXPR_VALUE, "/value,epoch_offset");
                        }
                        isFollowedBySQLConditionalOperator = true;
                        item = hackItem(taggedBuffer, Long.toString(timestamp), "numeric");
                        taggedBuffer.append((String) item);
                    } else {
                        item = hackItem(taggedBuffer, (String) item, null);
                        taggedBuffer.append((String) item);
                    }
                    break;
            }
        } else if (item instanceof Long) {
            item = hackItem(taggedBuffer, item.toString(), null);
            taggedBuffer.append(item.toString());
        } else if (item instanceof I_VariableDefinition) {
            // look ahead and check if followed by a sql operator
            TaggedStringBuilder taggedStringBuilder = new TaggedStringBuilder();
            if (isFollowedBySQLConditionalOperator(cursor)) {
                TaggedStringBuilder encodedVar = encodeWhereVariable(whereCursor, multiWhereFieldsMap, (I_VariableDefinition) item, true, null);
                String expanded = expandForLateral(templateId, encodedVar, (I_VariableDefinition) item, multiSelectFieldsMap);
                if (StringUtils.isNotBlank(expanded))
                    taggedStringBuilder.append(expanded);
                else {
                    unresolvedVariable = true;
                    break;
                }
            } else {
                if (((I_VariableDefinition) item).getPath() != null && isWholeComposition) {
                    // look ahead for name/value condition (used to produce the composition root)
                    if (compositionName == null)
                        compositionName = compositionNameValue(((I_VariableDefinition) item).getIdentifier());
                    if (compositionName != null) {
                        taggedStringBuilder = encodeWhereVariable(whereCursor, multiWhereFieldsMap, (I_VariableDefinition) item, false, compositionName);
                    } else
                        throw new IllegalArgumentException("A composition name/value is required to resolve where statement when querying for a whole composition");
                } else {
                    // if the path contains node predicate expression uses a SQL syntax instead of jsquery
                    if (new VariablePath(((I_VariableDefinition) item).getPath()).hasPredicate()) {
                        String expanded = expandForLateral(templateId, encodeWhereVariable(whereCursor, multiWhereFieldsMap, (I_VariableDefinition) item, true, null), (I_VariableDefinition) item, multiSelectFieldsMap);
                        if (StringUtils.isNotBlank(expanded)) {
                            taggedStringBuilder.append(encodeForSubquery(expanded, inSubqueryOperator));
                            inSubqueryOperator = false;
                        } else {
                            unresolvedVariable = true;
                            break;
                        }
                        isFollowedBySQLConditionalOperator = true;
                        requiresJSQueryClosure = false;
                    } else {
                        String expanded = expandForLateral(templateId, encodeWhereVariable(whereCursor, multiWhereFieldsMap, (I_VariableDefinition) item, true, null), (I_VariableDefinition) item, multiSelectFieldsMap);
                        if (StringUtils.isNotBlank(expanded)) {
                            taggedStringBuilder.append(encodeForSubquery(expanded, inSubqueryOperator));
                            inSubqueryOperator = false;
                        } else {
                            unresolvedVariable = true;
                            break;
                        }
                    }
                }
            }
            if (taggedStringBuilder != null) {
                taggedBuffer.append(taggedStringBuilder.toString());
                taggedBuffer.setTagField(taggedStringBuilder.getTagField());
            }
        } else if (item instanceof List) {
            TaggedStringBuilder taggedStringBuilder = buildWhereCondition(whereCursor, multiWhereFieldsMap, taggedBuffer, (List) item);
            taggedBuffer.append(taggedStringBuilder.toString());
            taggedBuffer.setTagField(taggedStringBuilder.getTagField());
        }
    }
    if (!unresolvedVariable) {
        // termination
        taggedBuffer = new WhereJsQueryExpression(taggedBuffer, requiresJSQueryClosure, isFollowedBySQLConditionalOperator).closure();
        return DSL.condition(taggedBuffer.toString());
    } else
        return DSL.falseCondition();
}
Also used : I_VariableDefinition(org.ehrbase.aql.definition.I_VariableDefinition) ISODateTime(org.ehrbase.aql.sql.queryimpl.value_field.ISODateTime)

Example 4 with I_VariableDefinition

use of org.ehrbase.aql.definition.I_VariableDefinition in project ehrbase by ehrbase.

the class AqlQueryHandler method execute.

@SuppressWarnings("unchecked")
private AqlResult execute(AqlExpression aqlExpression) {
    AuditVariables auditVariables = new AuditVariables();
    Contains contains = new Contains(aqlExpression.getParseTree(), (KnowledgeCacheService) this.getDataAccess().getIntrospectService()).process();
    Statements statements = new Statements(aqlExpression.getParseTree(), contains.getIdentifierMapper(), tsAdapter).process();
    QueryProcessor queryProcessor = new QueryProcessor(this, this.getIntrospectService(), contains, statements, getDataAccess().getServerConfig().getNodename());
    AqlResult aqlResult = queryProcessor.execute();
    // add the variable from statements
    Map<String, String> variables = new LinkedHashMap<>();
    Iterator<I_VariableDefinition> iterator = statements.getVariables().iterator();
    int serial = 0;
    while (iterator.hasNext()) {
        I_VariableDefinition variableDefinition = iterator.next();
        if (auditVariables.isAuditVariable(variableDefinition)) {
            // add the result to the list of audit variables
            auditVariables.addResults(auditResultMap, variableDefinition.getPath(), resultSetForVariable(variableDefinition, aqlResult.getRecords()));
        }
        if (!variableDefinition.isHidden())
            variables.put(variableDefinition.getAlias() == null || variableDefinition.isVoidAlias() ? "#" + serial++ : variableDefinition.getAlias(), StringUtils.isNotBlank(variableDefinition.getPath()) ? "/" + variableDefinition.getPath() : variableDefinition.getIdentifier());
    }
    aqlResult.setVariables(variables);
    aqlResult.setAuditResultMap(auditResultMap);
    return aqlResult;
}
Also used : KnowledgeCacheService(org.ehrbase.service.KnowledgeCacheService) AqlResult(org.ehrbase.aql.sql.AqlResult) I_VariableDefinition(org.ehrbase.aql.definition.I_VariableDefinition) QueryProcessor(org.ehrbase.aql.sql.QueryProcessor)

Example 5 with I_VariableDefinition

use of org.ehrbase.aql.definition.I_VariableDefinition in project ehrbase by ehrbase.

the class InvokeVisitorTest method shouldVisitInvokeExpressionValidateOperation.

@Test
public void shouldVisitInvokeExpressionValidateOperation() {
    // postman request for expansion is: GET https://r4.ontoserver.csiro.au/fhir/ValueSet/$expand?url=http://hl7.org/fhir/ValueSet/surface
    FhirTerminologyServerR4AdaptorImpl mock = mock(FhirTerminologyServerR4AdaptorImpl.class);
    when(mock.validate(any())).thenReturn(true);
    WhereVisitor cut = new WhereVisitor(mock);
    String aql = "SELECT o/data[at0002]/events[at0003] AS systolic " + "FROM EHR [ehr_id/value='1234'] " + "CONTAINS COMPOSITION c " + "CONTAINS OBSERVATION o [openEHR-EHR-OBSERVATION.blood_pressure.v1] " + "WHERE c/archetype_details/template_id/value MATCHES {'Flormidal', TERMINOLOGY('validate','http://hl7.org/fhir/4.0','system=http://snomed.info/sct&code=122298005&url=http://snomed.info/sct?fhir_vs&display=Astrovirus RNA assay'), 'Kloralhidrat'}";
    ParseTree tree = QueryHelper.setupParseTree(aql);
    cut.visit(tree);
    List<Object> whereExpression = cut.getWhereExpression();
    assertThat(whereExpression).size().isEqualTo(9);
    I_VariableDefinition where1 = (I_VariableDefinition) whereExpression.get(0);
    I_VariableDefinition expected1 = I_VariableDefinitionHelper.build("archetype_details/template_id/value", null, "c", false, false, false);
    I_VariableDefinitionHelper.checkEqualWithoutFuncParameters(where1, expected1);
    assertThat(whereExpression.get(1)).isEqualTo(" IN ");
    assertThat(whereExpression.get(2)).isEqualTo("(");
    assertThat(whereExpression.get(3)).isEqualTo("'Flormidal'");
    assertThat(whereExpression.get(4)).isEqualTo(",");
    assertThat(whereExpression.get(5)).isEqualTo(true);
    assertThat(whereExpression.get(6)).isEqualTo(",");
    assertThat(whereExpression.get(7)).isEqualTo("'Kloralhidrat'");
    assertThat(whereExpression.get(8)).isEqualTo(")");
}
Also used : FhirTerminologyServerR4AdaptorImpl(org.ehrbase.service.FhirTerminologyServerR4AdaptorImpl) I_VariableDefinition(org.ehrbase.aql.definition.I_VariableDefinition) ParseTree(org.antlr.v4.runtime.tree.ParseTree) Test(org.junit.Test)

Aggregations

I_VariableDefinition (org.ehrbase.aql.definition.I_VariableDefinition)11 ArrayList (java.util.ArrayList)4 ParseTree (org.antlr.v4.runtime.tree.ParseTree)2 OrderAttribute (org.ehrbase.aql.compiler.OrderAttribute)2 FhirTerminologyServerR4AdaptorImpl (org.ehrbase.service.FhirTerminologyServerR4AdaptorImpl)2 Field (org.jooq.Field)2 Test (org.junit.Test)2 CodePhrase (com.nedap.archie.rm.datatypes.CodePhrase)1 DvCodedText (com.nedap.archie.rm.datavalues.DvCodedText)1 FuncParameter (org.ehrbase.aql.definition.FuncParameter)1 FunctionDefinition (org.ehrbase.aql.definition.FunctionDefinition)1 LateralJoinDefinition (org.ehrbase.aql.definition.LateralJoinDefinition)1 VariableDefinition (org.ehrbase.aql.definition.VariableDefinition)1 AqlResult (org.ehrbase.aql.sql.AqlResult)1 QueryProcessor (org.ehrbase.aql.sql.QueryProcessor)1 LateralJoins (org.ehrbase.aql.sql.binding.LateralJoins)1 ISODateTime (org.ehrbase.aql.sql.queryimpl.value_field.ISODateTime)1 KnowledgeCacheService (org.ehrbase.service.KnowledgeCacheService)1 Comparator (org.jooq.Comparator)1 SelectQuery (org.jooq.SelectQuery)1