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 6a8b53349..8091af490 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 @@ -133,7 +133,7 @@ functionsReturningBoolean orderByClause: ORDER BY orderByItem (',' orderByItem)* ; -orderByItem: singleValuedObjectPathExpression (ASC | DESC)? ; +orderByItem: (singleValuedObjectPathExpression | simpleSubpath) (ASC | DESC)? ; groupByClause: GROUP BY groupByItem (',' groupByItem)* ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlOrderParameter.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlOrderParameter.java index c14ee85a8..55b5aa6c6 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlOrderParameter.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlOrderParameter.java @@ -37,6 +37,10 @@ public void setAttribute(SoqlAttribute attribute) { } public String getOrderByPart(String rootVariable) { + if (getAsParam(rootVariable).equals(rootVariable)) { + // Ordering by the entity identifier + return SoqlConstants.ASC.equals(orderingBy) ? rootVariable + " " : orderingBy + "(" + rootVariable + ") "; + } String param = attribute.requiresFilter() ? getAsParam(rootVariable).substring(1) : attribute.getValue().substring(1); return orderingBy + "(?" + param + ") "; } 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 0d258636b..f7a5dd759 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 @@ -437,7 +437,9 @@ private SoqlNode linkObjectPathExpression(ParserRuleContext ctx) { } setIris(firstNode); if (currentNode.getIri().isEmpty()) { - currentNode.getParent().clearChildren(); + if (currentNode.getParent() != null) { + currentNode.getParent().clearChildren(); + } this.isInObjectIdentifierExpression = true; } return firstNode; diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java index 6176ed9a9..1cddf1a33 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java @@ -999,4 +999,24 @@ void parseQueryHandlesVariableCorrespondingToEntityIdentifier() { " . ?personUri " + strUri(Vocabulary.p_p_username) + " ?username . }"; parseAndAssertEquality(expectedSparql, soql); } + + /** + * Bug #439 + */ + @Test + void parseQuerySupportsOrderingByEntityIdentifier() { + final String soql = "SELECT p FROM Person p ORDER BY p.uri"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_Person) + " . } ORDER BY ?x"; + parseAndAssertEquality(expectedSparql, soql); + } + + /** + * Bug #439 - alternative syntax + */ + @Test + void parseQuerySupportsOrderingByEntity() { + final String soql = "SELECT p FROM Person p ORDER BY p"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_Person) + " . } ORDER BY ?x"; + parseAndAssertEquality(expectedSparql, soql); + } }