From fed609cd673f5c127f212d12f89dc3e45d2feb28 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Wed, 21 Oct 2020 09:10:14 +0000 Subject: [PATCH] FIX: Queries like WITH (( ... AND ... ) AND ... ) used to fail. Prior to this fix, query parse would throw an error when the query had a form similar to ... WITH ( (...) {AND,OR} ...). The reason were the nested pair of parenthesis in the first element of the disjunction or conjunction. --- CHANGELOG.md | 4 +++ .../java/org/caosdb/server/query/CQLParser.g4 | 12 +++++-- .../java/org/caosdb/server/query/TestCQL.java | 33 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fccd7c8f..6cadb57b 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 8b5e5a94..a168e129 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 2264c9f0..acd4946d 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()); + } } -- GitLab