diff --git a/CHANGELOG.md b/CHANGELOG.md index fccd7c8ff5d78126d80692728d7941be1d142e29..6cadb57b73f3b6c3c8390f2768cdd98575cf0089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* Bug in the query parser (MR!56) - The parser would throw an error when the + query contains a conjunction or disjunction filter with a first element which + is another disjunction or conjunction and being wrapped into parenthesis. + ### Security ## [0.2] - 2020-09-02 diff --git a/src/main/java/org/caosdb/server/query/CQLParser.g4 b/src/main/java/org/caosdb/server/query/CQLParser.g4 index 8b5e5a94aaea5d62ba60068a1ad652f7b51f1bd4..a168e12931ed721956f2fbd057449d16aa693317 100644 --- a/src/main/java/org/caosdb/server/query/CQLParser.g4 +++ b/src/main/java/org/caosdb/server/query/CQLParser.g4 @@ -312,7 +312,11 @@ conjunction returns [Conjunction c] locals [Conjunction dummy] f1 = filter_expression {$c.add($f1.efi);} | LPAREN - f4 = filter_expression {$c.add($f4.efi);} + ( + f4 = filter_expression {$c.add($f4.efi);} + | disjunction {$c.add($disjunction.d);} + | c3=conjunction {$c.addAll($c3.c);} + ) RPAREN ) ( @@ -344,7 +348,11 @@ disjunction returns [Disjunction d] f1 = filter_expression {$d.add($f1.efi);} | LPAREN - f4 = filter_expression {$d.add($f4.efi);} + ( + f4 = filter_expression {$d.add($f4.efi);} + | conjunction {$d.add($conjunction.c);} + | d3 = disjunction {$d.addAll($d3.d);} + ) RPAREN ) ( diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java index 2264c9f02233c5462339615e142c38e2df4eb033..acd4946d826b7b0ed00c396c71dd84384e4668a4 100644 --- a/src/test/java/org/caosdb/server/query/TestCQL.java +++ b/src/test/java/org/caosdb/server/query/TestCQL.java @@ -241,6 +241,7 @@ public class TestCQL { String referenceByLikePattern = "FIND ENTITY WHICH IS REFERENCED BY *name*"; String emptyTextValue = "FIND ENTITY WITH prop=''"; + String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)"; @Test public void testQuery1() @@ -6417,4 +6418,36 @@ public class TestCQL { final StoredAt storedAt = (StoredAt) sfq.filter; assertEquals("SAT(/data/in0.foo)", storedAt.toString()); } + + /** + * Testing a conjunction which begins with a nested disjunction. The bug was a parsing error which + * was caused by a missing option for a disjunction/conjunction, wrapped into parenthesis as first + * element of a conjunction/disjunction + * + * <p>String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)"; + */ + @Test + public void testMR56() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.queryMR56)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, role, WHICHCLAUSE, EOF + assertEquals(4, sfq.getChildCount()); + assertEquals("WITH((p0=v0ORp1=v1)ANDp2=v2)", sfq.getChild(2).getText()); + assertEquals("ENTITY", sfq.r.toString()); + assertEquals("Conjunction", sfq.filter.getClass().getSimpleName()); + final ParseTree whichclause = sfq.getChild(2); + final ParseTree conjunction = whichclause.getChild(2); + assertEquals("(p0=v0ORp1=v1)ANDp2=v2", conjunction.getText()); + final ParseTree disjunction = conjunction.getChild(1); + assertEquals("p0=v0ORp1=v1", disjunction.getText()); + final ParseTree pov = conjunction.getChild(4); + assertEquals("p2=v2", pov.getText()); + } }