From e3009ee661f363a79f11a973d35cff256f2e5fc2 Mon Sep 17 00:00:00 2001 From: luxbe Date: Wed, 18 Dec 2024 17:20:59 +0100 Subject: [PATCH 1/9] Simplify Soql grammar --- .../cz/cvut/kbss/jopa/query/soql/Soql.g4 | 34 ++--- .../jopa/query/soql/SoqlQueryListener.java | 124 ++++++++---------- 2 files changed, 70 insertions(+), 88 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index 4d105890b..7ff4b589d 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -1,21 +1,16 @@ grammar Soql; +start: querySentence EOF ; -querySentence : selectStatement whereClauseWrapper? groupByClause? orderByClause? ; +querySentence: selectStatement ; -selectStatement: typeDef params FROM tables ; +selectStatement: selectClause fromClause whereClause? groupByClause? orderByClause? ; -typeDef: SELECT ; +selectClause: SELECT (DISTINCT)? selectItem (',' selectItem)* ; -params: paramComma* distinctParam ; +selectItem: selectExpression; -paramComma: distinctParam ',' ; - -distinctParam: distinct? selectedParam ; - -selectedParam: param | count; - -count: COUNT '(' param ')' ; +selectExpression: param | count ; param: objWithAttr | objWithOutAttr ; @@ -23,26 +18,21 @@ objWithAttr: object DOT attribute; objWithOutAttr: object ; -distinct: DISTINCT ; - object: IDENTIFICATION_VARIABLE ; +count: COUNT '(' param ')' ; + attribute: IDENTIFICATION_VARIABLE ; joinedParams: object DOT attribute (DOT attribute)+ ; +fromClause: FROM entityName identificationVariable; +entityName: IDENTIFICATION_VARIABLE ; -tables: tableWithName ; - -table: IDENTIFICATION_VARIABLE ; - -tableName: IDENTIFICATION_VARIABLE ; - -tableWithName: table tableName ; - +identificationVariable: IDENTIFICATION_VARIABLE ; -whereClauseWrapper +whereClause : WHERE conditionalExpression ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index eeceee25e..1f18d6d51 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -89,6 +89,16 @@ public SoqlQueryListener(MetamodelImpl metamodel) { this.objectTypes = new HashMap<>(); } + @Override + public void enterStart(SoqlParser.StartContext ctx) { + + } + + @Override + public void exitStart(SoqlParser.StartContext ctx) { + + } + @Override public void enterQuerySentence(SoqlParser.QuerySentenceContext ctx) { } @@ -101,18 +111,41 @@ public void exitQuerySentence(SoqlParser.QuerySentenceContext ctx) { @Override public void enterSelectStatement(SoqlParser.SelectStatementContext ctx) { + } @Override public void exitSelectStatement(SoqlParser.SelectStatementContext ctx) { + + } + + @Override + public void enterSelectClause(SoqlParser.SelectClauseContext ctx) { + this.typeDef = SparqlConstants.SELECT; + + if(ctx.DISTINCT() != null) { + this.isSelectedParamDistinct = true; + } + } + + @Override + public void exitSelectClause(SoqlParser.SelectClauseContext ctx) { + } @Override - public void enterParams(SoqlParser.ParamsContext ctx) { + public void enterSelectItem(SoqlParser.SelectItemContext ctx) { + } @Override - public void exitParams(SoqlParser.ParamsContext ctx) { + public void exitSelectItem(SoqlParser.SelectItemContext ctx) { + + } + + @Override + public void enterSelectExpression(SoqlParser.SelectExpressionContext ctx) { + } @Override @@ -144,27 +177,7 @@ public void exitJoinedParams(SoqlParser.JoinedParamsContext ctx) { } @Override - public void enterParamComma(SoqlParser.ParamCommaContext ctx) { - } - - @Override - public void exitParamComma(SoqlParser.ParamCommaContext ctx) { - } - - @Override - public void enterDistinctParam(SoqlParser.DistinctParamContext ctx) { - } - - @Override - public void exitDistinctParam(SoqlParser.DistinctParamContext ctx) { - } - - @Override - public void enterSelectedParam(SoqlParser.SelectedParamContext ctx) { - } - - @Override - public void exitSelectedParam(SoqlParser.SelectedParamContext ctx) { + public void exitSelectExpression(SoqlParser.SelectExpressionContext ctx) { if (!isSelectedParamCount) { this.projectedVariable = ctx.getText(); } @@ -247,34 +260,6 @@ public void enterAttribute(SoqlParser.AttributeContext ctx) { public void exitAttribute(SoqlParser.AttributeContext ctx) { } - @Override - public void enterTypeDef(SoqlParser.TypeDefContext ctx) { - typeDef = ctx.getChild(0).getText(); - } - - @Override - public void exitTypeDef(SoqlParser.TypeDefContext ctx) { - } - - @Override - public void enterDistinct(SoqlParser.DistinctContext ctx) { - if (SoqlConstants.DISTINCT.equals(ctx.getChild(0).getText())) { - isSelectedParamDistinct = true; - } - } - - @Override - public void exitDistinct(SoqlParser.DistinctContext ctx) { - } - - @Override - public void enterWhereClauseWrapper(SoqlParser.WhereClauseWrapperContext ctx) { - } - - @Override - public void exitWhereClauseWrapper(SoqlParser.WhereClauseWrapperContext ctx) { - } - @Override public void enterConditionalExpression(SoqlParser.ConditionalExpressionContext ctx) { } @@ -437,42 +422,49 @@ private boolean isRootIdentifier(SoqlAttribute attribute) { } @Override - public void enterTables(SoqlParser.TablesContext ctx) { + public void enterFromClause(SoqlParser.FromClauseContext ctx) { + String entityName = ctx.entityName().getText(); + String identificationVariable = ctx.identificationVariable().getText(); + objectTypes.put(identificationVariable, entityName); + SoqlNode node = new AttributeNode(entityName); + setObjectIri(node); + SoqlAttribute myAttr = new SoqlAttribute(node); + pushNewAttribute(myAttr); } @Override - public void exitTables(SoqlParser.TablesContext ctx) { + public void exitFromClause(SoqlParser.FromClauseContext ctx) { + } @Override - public void enterTable(SoqlParser.TableContext ctx) { + public void enterEntityName(SoqlParser.EntityNameContext ctx) { + } @Override - public void exitTable(SoqlParser.TableContext ctx) { + public void exitEntityName(SoqlParser.EntityNameContext ctx) { + } @Override - public void enterTableName(SoqlParser.TableNameContext ctx) { + public void enterIdentificationVariable(SoqlParser.IdentificationVariableContext ctx) { + } @Override - public void exitTableName(SoqlParser.TableNameContext ctx) { + public void exitIdentificationVariable(SoqlParser.IdentificationVariableContext ctx) { + } @Override - public void enterTableWithName(SoqlParser.TableWithNameContext ctx) { - String table = ctx.getChild(0).getChild(0).getText(); - String objectName = ctx.getChild(1).getChild(0).getText(); - objectTypes.put(objectName, table); - SoqlNode node = new AttributeNode(table); - setObjectIri(node); - SoqlAttribute myAttr = new SoqlAttribute(node); - pushNewAttribute(myAttr); + public void enterWhereClause(SoqlParser.WhereClauseContext ctx) { + } @Override - public void exitTableWithName(SoqlParser.TableWithNameContext ctx) { + public void exitWhereClause(SoqlParser.WhereClauseContext ctx) { + } @Override From 846e1525e54a58f3e33b0ddf67e1b742fa46f51d Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 08:55:23 +0100 Subject: [PATCH 2/9] Simplify Soql ORDER BY and GROUP BY clauses --- .../cz/cvut/kbss/jopa/query/soql/Soql.g4 | 26 +++--- .../jopa/query/soql/SoqlQueryListener.java | 86 ++++++++++++------- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index 7ff4b589d..eede645ba 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -6,6 +6,12 @@ querySentence: selectStatement ; selectStatement: selectClause fromClause whereClause? groupByClause? orderByClause? ; +objectPathExpression: simplePath DOT objectField ; + +simplePath: objectField (DOT simplePath)* ; + +objectField: IDENTIFICATION_VARIABLE ; + selectClause: SELECT (DISTINCT)? selectItem (',' selectItem)* ; selectItem: selectExpression; @@ -128,19 +134,13 @@ functionsReturningNumerics | 'FLOOR' '(' simpleArithmeticExpression ')' ; -orderByClause: ORDERBY orderByFullFormComma orderByFullFormComma* ; - -orderByFullFormComma: orderByFullForm ','? ; - -orderByFullForm: orderByParam ORDERING? ; - -orderByParam: object DOT attribute (DOT attribute)* ; +orderByClause: ORDER BY orderByItem (',' orderByItem)* ; -groupByClause: GROUPBY groupByParamComma groupByParamComma* ; +orderByItem: objectPathExpression (ASC | DESC) ; -groupByParamComma: groupByParam ','? ; +groupByClause: GROUP BY groupByItem (',' groupByItem)* ; -groupByParam: object DOT attribute (DOT attribute)* ; +groupByItem: objectPathExpression ; inputParameter: COLON IDENTIFICATION_VARIABLE ; @@ -159,11 +159,11 @@ AND: 'AND' ; OR: 'OR' ; -ORDERBY: 'ORDER BY' ; +BY: 'BY' ; -ORDERING: ASC | DESC ; +ORDER: 'ORDER' ; -GROUPBY: 'GROUP BY' ; +GROUP: 'GROUP' ; ASC: 'ASC' ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index 1f18d6d51..402b71dbe 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -119,6 +119,36 @@ public void exitSelectStatement(SoqlParser.SelectStatementContext ctx) { } + @Override + public void enterObjectPathExpression(SoqlParser.ObjectPathExpressionContext ctx) { + + } + + @Override + public void exitObjectPathExpression(SoqlParser.ObjectPathExpressionContext ctx) { + + } + + @Override + public void enterSimplePath(SoqlParser.SimplePathContext ctx) { + + } + + @Override + public void exitSimplePath(SoqlParser.SimplePathContext ctx) { + + } + + @Override + public void enterObjectField(SoqlParser.ObjectFieldContext ctx) { + + } + + @Override + public void exitObjectField(SoqlParser.ObjectFieldContext ctx) { + + } + @Override public void enterSelectClause(SoqlParser.SelectClauseContext ctx) { this.typeDef = SparqlConstants.SELECT; @@ -565,24 +595,8 @@ public void exitOrderByClause(SoqlParser.OrderByClauseContext ctx) { } @Override - public void enterOrderByFullFormComma(SoqlParser.OrderByFullFormCommaContext ctx) { - } - - @Override - public void exitOrderByFullFormComma(SoqlParser.OrderByFullFormCommaContext ctx) { - } - - @Override - public void enterOrderByFullForm(SoqlParser.OrderByFullFormContext ctx) { - } - - @Override - public void exitOrderByFullForm(SoqlParser.OrderByFullFormContext ctx) { - } - - @Override - public void enterOrderByParam(SoqlParser.OrderByParamContext ctx) { - SoqlNode firstNode = linkContextNodes(ctx); + public void enterOrderByItem(SoqlParser.OrderByItemContext ctx) { + SoqlNode firstNode = linkObjectPathExpression(ctx); String orderingBy = getOrderingBy(ctx.getParent()); SoqlOrderParameter orderParam = new SoqlOrderParameter(firstNode, orderingBy); boolean attrSet = false; @@ -603,28 +617,21 @@ public void enterOrderByParam(SoqlParser.OrderByParamContext ctx) { } @Override - public void exitOrderByParam(SoqlParser.OrderByParamContext ctx) { + public void exitOrderByItem(SoqlParser.OrderByItemContext ctx) { } @Override public void enterGroupByClause(SoqlParser.GroupByClauseContext ctx) { - } - @Override - public void exitGroupByClause(SoqlParser.GroupByClauseContext ctx) { - } - - @Override - public void enterGroupByParamComma(SoqlParser.GroupByParamCommaContext ctx) { } @Override - public void exitGroupByParamComma(SoqlParser.GroupByParamCommaContext ctx) { + public void exitGroupByClause(SoqlParser.GroupByClauseContext ctx) { } @Override - public void enterGroupByParam(SoqlParser.GroupByParamContext ctx) { - SoqlNode firstNode = linkContextNodes(ctx); + public void enterGroupByItem(SoqlParser.GroupByItemContext ctx) { + SoqlNode firstNode = linkObjectPathExpression(ctx); SoqlGroupParameter groupParam = new SoqlGroupParameter(firstNode); boolean attrSet = false; for (SoqlAttribute attr : attributes) { @@ -643,6 +650,11 @@ public void enterGroupByParam(SoqlParser.GroupByParamContext ctx) { groupAttributes.add(groupParam); } + @Override + public void exitGroupByItem(SoqlParser.GroupByItemContext ctx) { + + } + private SoqlNode linkContextNodes(ParserRuleContext ctx) { SoqlNode firstNode = new AttributeNode(getOwnerFromParam(ctx)); SoqlNode currentNode = firstNode; @@ -659,8 +671,20 @@ private SoqlNode linkContextNodes(ParserRuleContext ctx) { return firstNode; } - @Override - public void exitGroupByParam(SoqlParser.GroupByParamContext ctx) { + private SoqlNode linkObjectPathExpression(ParserRuleContext ctx) { + SoqlNode firstNode = new AttributeNode(getOwnerFromParam(ctx)); + SoqlNode currentNode = firstNode; + for (int i = 2; i < ctx.getChild(0).getChildCount(); i += 2) { + SoqlNode prevNode = currentNode; + currentNode = new AttributeNode(prevNode, ctx.getChild(0).getChild(i).getText()); + prevNode.setChild(currentNode); + } + setIris(firstNode); + if (currentNode.getIri().isEmpty()) { + currentNode.getParent().setChild(null); + this.isInObjectIdentifierExpression = true; + } + return firstNode; } @Override From a62b835a848842c86fb7c76b0ddba3d6b135cb58 Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 09:24:14 +0100 Subject: [PATCH 3/9] Replace Soql param with simplePath --- .../cz/cvut/kbss/jopa/query/soql/Soql.g4 | 34 ++-- .../jopa/query/soql/SoqlQueryListener.java | 160 ++++++++---------- 2 files changed, 81 insertions(+), 113 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index eede645ba..d4ded0094 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -16,21 +16,9 @@ selectClause: SELECT (DISTINCT)? selectItem (',' selectItem)* ; selectItem: selectExpression; -selectExpression: param | count ; +selectExpression: simplePath | aggregateExpression ; -param: objWithAttr | objWithOutAttr ; - -objWithAttr: object DOT attribute; - -objWithOutAttr: object ; - -object: IDENTIFICATION_VARIABLE ; - -count: COUNT '(' param ')' ; - -attribute: IDENTIFICATION_VARIABLE ; - -joinedParams: object DOT attribute (DOT attribute)+ ; +aggregateExpression: COUNT '(' (DISTINCT)? simplePath ')'; fromClause: FROM entityName identificationVariable; @@ -62,7 +50,7 @@ simpleConditionalExpression ; inExpression - : whereClauseParam (NOT)? IN '('? (inItem (',' inItem)*) ')'? + : simplePath (NOT)? IN '('? (inItem (',' inItem)*) ')'? ; inItem @@ -79,21 +67,19 @@ likeExpression ; memberOfExpression - : inItem (NOT)? MEMBEROF whereClauseParam + : inItem (NOT)? MEMBER OF simplePath ; comparisonExpression : stringExpression COMPARISON_OPERATOR stringExpression | simpleArithmeticExpression COMPARISON_OPERATOR simpleArithmeticExpression - | whereClauseParam COMPARISON_OPERATOR ( whereClauseParam | whereClauseValue ) + | simplePath COMPARISON_OPERATOR ( simplePath | whereClauseValue ) ; whereClauseValue: (QMARK TEXT QMARK) | inputParameter ; -whereClauseParam: param | joinedParams ; - stringExpression - : whereClauseParam + : simplePath | inputParameter | functionsReturningStrings ; @@ -103,7 +89,7 @@ functionsReturningStrings | 'SUBSTRING' '(' stringExpression ',' simpleArithmeticExpression ',' simpleArithmeticExpression ')' | 'LOWER' '(' stringExpression ')' | 'UPPER' '(' stringExpression ')' - | 'LANG' '(' whereClauseParam ')' + | 'LANG' '(' simplePath ')' ; simpleArithmeticExpression @@ -119,7 +105,7 @@ arithmeticFactor ; arithmeticPrimary - : param + : simplePath | literal | '(' simpleArithmeticExpression ')' | inputParameter @@ -161,6 +147,8 @@ OR: 'OR' ; BY: 'BY' ; +OF: 'OF' ; + ORDER: 'ORDER' ; GROUP: 'GROUP' ; @@ -177,7 +165,7 @@ LIKE: 'LIKE' ; IN: 'IN' ; -MEMBEROF: 'MEMBER OF' ; +MEMBER: 'MEMBER' ; COMPARISON_OPERATOR: '>' | '<' | '>=' | '<=' | '=' | '<>' | '!=' ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index 402b71dbe..e29c6d5e7 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -131,7 +131,58 @@ public void exitObjectPathExpression(SoqlParser.ObjectPathExpressionContext ctx) @Override public void enterSimplePath(SoqlParser.SimplePathContext ctx) { + if(ctx.simplePath() == null) { + return; + } + + if(ctx.getChildCount() == 1) { + return; + } + + // node was already processed by parent + if(ctx.getParent() instanceof SoqlParser.SimplePathContext) { + return; + } + + SoqlNode owner = linkSimplePath(ctx); + + // don't add top level references multiple times + if(!owner.hasChild() && objectTypes.containsKey(owner.getValue())) { + return; + } + + SoqlAttribute newAttr = new SoqlAttribute(owner); + if (owner.hasChild() && isIdentifier(owner, owner.getChild())) { + this.isInObjectIdentifierExpression = true; + if (projectedVariable.equals(owner.getValue()) && currentPointerIsNotAttributeReference()) { + attrPointer.setProjected(true); + } else { + newAttr.setProjected(true); + pushNewAttribute(newAttr); + } + } else { + pushNewAttribute(newAttr); + } + } + private SoqlNode linkSimplePath(ParserRuleContext ctx) { + AttributeNode firstNode = new AttributeNode(getOwnerFromParam(ctx)); + AttributeNode currentNode = firstNode; + + while (ctx.getChildCount() == 3) { + ctx = (ParserRuleContext) ctx.getChild(2); + SoqlNode prevNode = currentNode; + currentNode = new AttributeNode(prevNode, ctx.getChild(0).getText()); + prevNode.setChild(currentNode); + } + setIris(firstNode); + if (currentNode.getIri().isEmpty()) { + this.isInObjectIdentifierExpression = true; + if (projectedVariable != null && projectedVariable.equals(firstNode.getValue()) && currentPointerIsNotAttributeReference()) { + attrPointer.setProjected(true); + } + } + return firstNode; } @Override @@ -146,7 +197,6 @@ public void enterObjectField(SoqlParser.ObjectFieldContext ctx) { @Override public void exitObjectField(SoqlParser.ObjectFieldContext ctx) { - } @Override @@ -178,21 +228,6 @@ public void enterSelectExpression(SoqlParser.SelectExpressionContext ctx) { } - @Override - public void enterParam(SoqlParser.ParamContext ctx) { - } - - @Override - public void exitParam(SoqlParser.ParamContext ctx) { - } - - @Override - public void enterJoinedParams(SoqlParser.JoinedParamsContext ctx) { - SoqlNode firstNode = linkContextNodes(ctx); - SoqlAttribute myAttr = new SoqlAttribute(firstNode); - pushNewAttribute(myAttr); - } - private void pushNewAttribute(SoqlAttribute myAttr) { attributes.add(myAttr); this.attrPointer = myAttr; @@ -202,10 +237,6 @@ private void popAttribute() { this.attrPointer = attributes.remove(attributes.size() - 1); } - @Override - public void exitJoinedParams(SoqlParser.JoinedParamsContext ctx) { - } - @Override public void exitSelectExpression(SoqlParser.SelectExpressionContext ctx) { if (!isSelectedParamCount) { @@ -214,44 +245,22 @@ public void exitSelectExpression(SoqlParser.SelectExpressionContext ctx) { } @Override - public void enterCount(SoqlParser.CountContext ctx) { - isSelectedParamCount = true; - } + public void enterAggregateExpression(SoqlParser.AggregateExpressionContext ctx) { + if(ctx.COUNT() != null) { + isSelectedParamCount = true; + if(ctx.DISTINCT() != null) { + isSelectedParamDistinct = true; + } - @Override - public void exitCount(SoqlParser.CountContext ctx) { - this.projectedVariable = ctx.getChild(2).getText(); + if(ctx.simplePath() != null) { + this.projectedVariable = ctx.simplePath().getText(); + } + } } @Override - public void enterObject(SoqlParser.ObjectContext ctx) { - } + public void exitAggregateExpression(SoqlParser.AggregateExpressionContext ctx) { - @Override - public void exitObject(SoqlParser.ObjectContext ctx) { - } - - @Override - public void enterObjWithAttr(SoqlParser.ObjWithAttrContext ctx) { - String owner = getOwnerFromParam(ctx); - String attribute = getAttributeFromParam(ctx); - // objectNode.attributeNode - SoqlNode objectNode = new AttributeNode(owner); - SoqlNode attributeNode = new AttributeNode(objectNode, attribute); - objectNode.setChild(attributeNode); - setIris(objectNode); - SoqlAttribute newAttr = new SoqlAttribute(objectNode); - if (isIdentifier(objectNode, attributeNode)) { - this.isInObjectIdentifierExpression = true; - if (projectedVariable.equals(objectNode.getValue()) && currentPointerIsNotAttributeReference()) { - attrPointer.setProjected(true); - } else { - newAttr.setProjected(true); - pushNewAttribute(newAttr); - } - } else { - pushNewAttribute(newAttr); - } } private boolean isIdentifier(SoqlNode objectNode, SoqlNode attributeNode) { @@ -270,26 +279,6 @@ private boolean currentPointerIsNotAttributeReference() { return !attrPointer.getFirstNode().hasChild(); } - @Override - public void exitObjWithAttr(SoqlParser.ObjWithAttrContext ctx) { - } - - @Override - public void enterObjWithOutAttr(SoqlParser.ObjWithOutAttrContext ctx) { - } - - @Override - public void exitObjWithOutAttr(SoqlParser.ObjWithOutAttrContext ctx) { - } - - @Override - public void enterAttribute(SoqlParser.AttributeContext ctx) { - } - - @Override - public void exitAttribute(SoqlParser.AttributeContext ctx) { - } - @Override public void enterConditionalExpression(SoqlParser.ConditionalExpressionContext ctx) { } @@ -340,7 +329,7 @@ public void exitInExpression(SoqlParser.InExpressionContext ctx) { pushNewAttribute(createSyntheticAttributeForEntityId()); } final ParseTree value = resolveInExpressionValue(ctx); - if (ctx.getChild(1).getText().equals(SoqlConstants.NOT)) { + if (ctx.NOT() != null) { attrPointer.setOperator(InOperator.notIn()); } else { attrPointer.setOperator(InOperator.in()); @@ -350,17 +339,16 @@ public void exitInExpression(SoqlParser.InExpressionContext ctx) { } private SoqlAttribute createSyntheticAttributeForEntityId() { - return new SoqlAttribute( - attrPointer.getFirstNode().hasChild() ? attrPointer.getFirstNode().getChild() : - new AttributeNode(rootVariable.substring(1))); + if(attrPointer.getFirstNode().hasChild()) { + attrPointer.getFirstNode().getChild().setChild(null); + return new SoqlAttribute(attrPointer.getFirstNode().getChild()); + } + + return new SoqlAttribute(new AttributeNode(rootVariable.substring(1))); } private ParseTree resolveInExpressionValue(SoqlParser.InExpressionContext ctx) { - final ParseTree lastToken = ctx.getChild(ctx.getChildCount() - 1); - if (")".equals(lastToken.getText())) { - return ctx.getChild(ctx.getChildCount() - 2); - } - return lastToken; + return ctx.inItem().get(ctx.inItem().size() - 1); } @Override @@ -505,14 +493,6 @@ public void enterWhereClauseValue(SoqlParser.WhereClauseValueContext ctx) { public void exitWhereClauseValue(SoqlParser.WhereClauseValueContext ctx) { } - @Override - public void enterWhereClauseParam(SoqlParser.WhereClauseParamContext ctx) { - } - - @Override - public void exitWhereClauseParam(SoqlParser.WhereClauseParamContext ctx) { - } - @Override public void enterStringExpression(SoqlParser.StringExpressionContext ctx) { From 806438f6068166e2acfc14b89e1fd20d9cf48a1f Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:03:38 +0100 Subject: [PATCH 4/9] Extend Soql grammar --- .../cz/cvut/kbss/jopa/query/soql/Soql.g4 | 23 +++++++++++++++---- .../jopa/query/soql/SoqlQueryListener.java | 10 ++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index d4ded0094..9106f592e 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -70,10 +70,15 @@ memberOfExpression : inItem (NOT)? MEMBER OF simplePath ; +entityExpression + : IDENTIFICATION_VARIABLE + | inputParameter + ; + comparisonExpression : stringExpression COMPARISON_OPERATOR stringExpression | simpleArithmeticExpression COMPARISON_OPERATOR simpleArithmeticExpression - | simplePath COMPARISON_OPERATOR ( simplePath | whereClauseValue ) + | entityExpression op=(EQUAL | NOT_EQUAL) ( entityExpression ) ; whereClauseValue: (QMARK TEXT QMARK) | inputParameter ; @@ -175,8 +180,20 @@ QMARK: '"' ; COLON: ':' ; +TRUE: 'TRUE'; + +FALSE: 'FALSE'; + IDENTIFICATION_VARIABLE: (LOWERCASE | UPPERCASE | '_') (LOWERCASE | UPPERCASE | DIGIT | '_')* ; +STRING_LITERAL: QMARK TEXT QMARK ; + +INT_LITERAL: DIGIT+; + +FLOAT_LITERAL: DIGIT* '.' DIGIT; + +BOOLEAN_LITERAL: TRUE | FALSE; + TEXT: (LOWERCASE | UPPERCASE | DIGIT)+ ; UPPERCASE: ('A'..'Z'); @@ -185,8 +202,4 @@ LOWERCASE: ('a'..'z'); DIGIT: ('0'..'9'); -NUMBER: DIGIT+ ; - -VALUE: NUMBER ; - WHITESPACE: (' ')+ -> skip; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index e29c6d5e7..c8bc73971 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -401,6 +401,16 @@ public void exitMemberOfExpression(SoqlParser.MemberOfExpressionContext ctx) { this.isInObjectIdentifierExpression = false; } + @Override + public void enterEntityExpression(SoqlParser.EntityExpressionContext ctx) { + + } + + @Override + public void exitEntityExpression(SoqlParser.EntityExpressionContext ctx) { + + } + @Override public void enterComparisonExpression(SoqlParser.ComparisonExpressionContext ctx) { } From 5a4069fc6e30b1f3bac4dee50b6f842b59fdf3a0 Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:10:45 +0100 Subject: [PATCH 5/9] Replace Soql identificationVariable with IDENTIFICATION_VARIABLE --- .../main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 | 4 +--- .../cvut/kbss/jopa/query/soql/SoqlQueryListener.java | 12 +----------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index 9106f592e..34eafab23 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -20,12 +20,10 @@ selectExpression: simplePath | aggregateExpression ; aggregateExpression: COUNT '(' (DISTINCT)? simplePath ')'; -fromClause: FROM entityName identificationVariable; +fromClause: FROM entityName IDENTIFICATION_VARIABLE; entityName: IDENTIFICATION_VARIABLE ; -identificationVariable: IDENTIFICATION_VARIABLE ; - whereClause : WHERE conditionalExpression ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index c8bc73971..bff8eecdc 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -452,7 +452,7 @@ private boolean isRootIdentifier(SoqlAttribute attribute) { @Override public void enterFromClause(SoqlParser.FromClauseContext ctx) { String entityName = ctx.entityName().getText(); - String identificationVariable = ctx.identificationVariable().getText(); + String identificationVariable = ctx.IDENTIFICATION_VARIABLE().getText(); objectTypes.put(identificationVariable, entityName); SoqlNode node = new AttributeNode(entityName); setObjectIri(node); @@ -475,16 +475,6 @@ public void exitEntityName(SoqlParser.EntityNameContext ctx) { } - @Override - public void enterIdentificationVariable(SoqlParser.IdentificationVariableContext ctx) { - - } - - @Override - public void exitIdentificationVariable(SoqlParser.IdentificationVariableContext ctx) { - - } - @Override public void enterWhereClause(SoqlParser.WhereClauseContext ctx) { From 5b56e3557ca6d0a39b0d5e62dcc654b7c6199735 Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:11:03 +0100 Subject: [PATCH 6/9] Align Soql comparisonOperator operation with reference --- .../antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 | 15 ++++++++++++--- .../kbss/jopa/query/soql/SoqlQueryListener.java | 10 ++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index 34eafab23..b0d4323ef 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -74,8 +74,8 @@ entityExpression ; comparisonExpression - : stringExpression COMPARISON_OPERATOR stringExpression - | simpleArithmeticExpression COMPARISON_OPERATOR simpleArithmeticExpression + : stringExpression comparisonOperator stringExpression + | simpleArithmeticExpression comparisonOperator simpleArithmeticExpression | entityExpression op=(EQUAL | NOT_EQUAL) ( entityExpression ) ; @@ -133,6 +133,14 @@ groupByItem: objectPathExpression ; inputParameter: COLON IDENTIFICATION_VARIABLE ; +comparisonOperator + : op=EQUAL + | op='>' + | op='>=' + | op='<' + | op='<=' + | op=NOT_EQUAL + ; SELECT: 'SELECT' ; @@ -170,7 +178,8 @@ IN: 'IN' ; MEMBER: 'MEMBER' ; -COMPARISON_OPERATOR: '>' | '<' | '>=' | '<=' | '=' | '<>' | '!=' ; +EQUAL: '=' ; +NOT_EQUAL: '<>' | '!=' ; DOT: '.' ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index bff8eecdc..6f4c0bb63 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -677,6 +677,16 @@ public void exitInputParameter(SoqlParser.InputParameterContext ctx) { } + @Override + public void enterComparisonOperator(SoqlParser.ComparisonOperatorContext ctx) { + + } + + @Override + public void exitComparisonOperator(SoqlParser.ComparisonOperatorContext ctx) { + + } + @Override public void visitTerminal(TerminalNode terminalNode) { } From 40c5986c600df0f0b3d8e6748d6f816684476aaa Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:20:20 +0100 Subject: [PATCH 7/9] Extend Soql literal --- .../src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index b0d4323ef..bd6816253 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -53,11 +53,15 @@ inExpression inItem : literal - | whereClauseValue + | inputParameter ; literal - : + : STRING_LITERAL + | INT_LITERAL + | FLOAT_LITERAL + | BOOLEAN_LITERAL + | IDENTIFICATION_VARIABLE ; likeExpression From fd7329e89a2e84c12e4e24a79d00379c7c1f849e Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:24:57 +0100 Subject: [PATCH 8/9] Replace Soql whereClauseValue --- .../src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 | 5 ++--- .../cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java | 8 -------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index bd6816253..4ddebc832 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -65,7 +65,7 @@ literal ; likeExpression - : stringExpression (NOT)? LIKE whereClauseValue + : stringExpression (NOT)? LIKE stringExpression ; memberOfExpression @@ -83,10 +83,9 @@ comparisonExpression | entityExpression op=(EQUAL | NOT_EQUAL) ( entityExpression ) ; -whereClauseValue: (QMARK TEXT QMARK) | inputParameter ; - stringExpression : simplePath + | STRING_LITERAL | inputParameter | functionsReturningStrings ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index 6f4c0bb63..626247eac 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -485,14 +485,6 @@ public void exitWhereClause(SoqlParser.WhereClauseContext ctx) { } - @Override - public void enterWhereClauseValue(SoqlParser.WhereClauseValueContext ctx) { - } - - @Override - public void exitWhereClauseValue(SoqlParser.WhereClauseValueContext ctx) { - } - @Override public void enterStringExpression(SoqlParser.StringExpressionContext ctx) { From 00a7dccab1480904669af92e87ad89008b6032f4 Mon Sep 17 00:00:00 2001 From: luxbe Date: Thu, 19 Dec 2024 14:35:34 +0100 Subject: [PATCH 9/9] Align Soql grammar to JPQL --- .../cz/cvut/kbss/jopa/query/soql/Soql.g4 | 24 +++++++++--------- .../jopa/query/soql/SoqlQueryListener.java | 25 ++++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index 4ddebc832..383a8887e 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -6,19 +6,19 @@ querySentence: selectStatement ; selectStatement: selectClause fromClause whereClause? groupByClause? orderByClause? ; -objectPathExpression: simplePath DOT objectField ; +singleValuedObjectPathExpression: simpleSubpath DOT singleValuedObjectField ; -simplePath: objectField (DOT simplePath)* ; +simpleSubpath: singleValuedObjectField (DOT simpleSubpath)* ; -objectField: IDENTIFICATION_VARIABLE ; +singleValuedObjectField: IDENTIFICATION_VARIABLE ; selectClause: SELECT (DISTINCT)? selectItem (',' selectItem)* ; selectItem: selectExpression; -selectExpression: simplePath | aggregateExpression ; +selectExpression: simpleSubpath | aggregateExpression ; -aggregateExpression: COUNT '(' (DISTINCT)? simplePath ')'; +aggregateExpression: COUNT '(' (DISTINCT)? simpleSubpath ')'; fromClause: FROM entityName IDENTIFICATION_VARIABLE; @@ -48,7 +48,7 @@ simpleConditionalExpression ; inExpression - : simplePath (NOT)? IN '('? (inItem (',' inItem)*) ')'? + : simpleSubpath (NOT)? IN '('? (inItem (',' inItem)*) ')'? ; inItem @@ -69,7 +69,7 @@ likeExpression ; memberOfExpression - : inItem (NOT)? MEMBER OF simplePath + : inItem (NOT)? MEMBER OF simpleSubpath ; entityExpression @@ -84,7 +84,7 @@ comparisonExpression ; stringExpression - : simplePath + : simpleSubpath | STRING_LITERAL | inputParameter | functionsReturningStrings @@ -95,7 +95,7 @@ functionsReturningStrings | 'SUBSTRING' '(' stringExpression ',' simpleArithmeticExpression ',' simpleArithmeticExpression ')' | 'LOWER' '(' stringExpression ')' | 'UPPER' '(' stringExpression ')' - | 'LANG' '(' simplePath ')' + | 'LANG' '(' simpleSubpath ')' ; simpleArithmeticExpression @@ -111,7 +111,7 @@ arithmeticFactor ; arithmeticPrimary - : simplePath + : simpleSubpath | literal | '(' simpleArithmeticExpression ')' | inputParameter @@ -128,11 +128,11 @@ functionsReturningNumerics orderByClause: ORDER BY orderByItem (',' orderByItem)* ; -orderByItem: objectPathExpression (ASC | DESC) ; +orderByItem: singleValuedObjectPathExpression (ASC | DESC) ; groupByClause: GROUP BY groupByItem (',' groupByItem)* ; -groupByItem: objectPathExpression ; +groupByItem: singleValuedObjectPathExpression ; inputParameter: COLON IDENTIFICATION_VARIABLE ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index 626247eac..2f3881a22 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -120,18 +120,18 @@ public void exitSelectStatement(SoqlParser.SelectStatementContext ctx) { } @Override - public void enterObjectPathExpression(SoqlParser.ObjectPathExpressionContext ctx) { + public void enterSingleValuedObjectPathExpression(SoqlParser.SingleValuedObjectPathExpressionContext ctx) { } @Override - public void exitObjectPathExpression(SoqlParser.ObjectPathExpressionContext ctx) { + public void exitSingleValuedObjectPathExpression(SoqlParser.SingleValuedObjectPathExpressionContext ctx) { } @Override - public void enterSimplePath(SoqlParser.SimplePathContext ctx) { - if(ctx.simplePath() == null) { + public void enterSimpleSubpath(SoqlParser.SimpleSubpathContext ctx) { + if(ctx.simpleSubpath() == null) { return; } @@ -140,11 +140,11 @@ public void enterSimplePath(SoqlParser.SimplePathContext ctx) { } // node was already processed by parent - if(ctx.getParent() instanceof SoqlParser.SimplePathContext) { + if(ctx.getParent() instanceof SoqlParser.SimpleSubpathContext) { return; } - SoqlNode owner = linkSimplePath(ctx); + SoqlNode owner = linkSimpleSubpath(ctx); // don't add top level references multiple times if(!owner.hasChild() && objectTypes.containsKey(owner.getValue())) { @@ -165,7 +165,7 @@ public void enterSimplePath(SoqlParser.SimplePathContext ctx) { } } - private SoqlNode linkSimplePath(ParserRuleContext ctx) { + private SoqlNode linkSimpleSubpath(ParserRuleContext ctx) { AttributeNode firstNode = new AttributeNode(getOwnerFromParam(ctx)); AttributeNode currentNode = firstNode; @@ -186,17 +186,18 @@ private SoqlNode linkSimplePath(ParserRuleContext ctx) { } @Override - public void exitSimplePath(SoqlParser.SimplePathContext ctx) { + public void exitSimpleSubpath(SoqlParser.SimpleSubpathContext ctx) { } @Override - public void enterObjectField(SoqlParser.ObjectFieldContext ctx) { + public void enterSingleValuedObjectField(SoqlParser.SingleValuedObjectFieldContext ctx) { } @Override - public void exitObjectField(SoqlParser.ObjectFieldContext ctx) { + public void exitSingleValuedObjectField(SoqlParser.SingleValuedObjectFieldContext ctx) { + } @Override @@ -252,8 +253,8 @@ public void enterAggregateExpression(SoqlParser.AggregateExpressionContext ctx) isSelectedParamDistinct = true; } - if(ctx.simplePath() != null) { - this.projectedVariable = ctx.simplePath().getText(); + if(ctx.simpleSubpath() != null) { + this.projectedVariable = ctx.simpleSubpath().getText(); } } }