From 16f3b1feb04fb02b5e060162610165e5a1053f32 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Thu, 13 Apr 2023 21:50:54 +0200 Subject: [PATCH] BUG: fix for server#143 --- .../java/org/caosdb/server/query/CQLLexer.g4 | 35 ++++++++++++++----- .../java/org/caosdb/server/query/CQLParser.g4 | 23 ++++++------ .../java/org/caosdb/server/query/POV.java | 6 ++-- .../java/org/caosdb/server/query/POVTest.java | 2 +- .../java/org/caosdb/server/query/TestCQL.java | 24 ++++++++++++- 5 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/caosdb/server/query/CQLLexer.g4 b/src/main/java/org/caosdb/server/query/CQLLexer.g4 index 518d1628..1dc3ad49 100644 --- a/src/main/java/org/caosdb/server/query/CQLLexer.g4 +++ b/src/main/java/org/caosdb/server/query/CQLLexer.g4 @@ -523,30 +523,49 @@ TODAY: ; /** */ -HYPHEN: - '-' +COLON: + ':' +; + +/** Matches signed and unsigned numbers with decimal points, also numbers in scientific notation. */ +DECIMAL_NUMBER: + (HYPHEN_f WHITE_SPACE_f?)? + ( NUM_f? DOT NUM_f WHITE_SPACE_f? E_NOTATION_f? + | NUM_f WHITE_SPACE_f? E_NOTATION_f + ) ; /** */ -COLON: - ':' +HYPHEN: + HYPHEN_f ; /** */ -NUM: +fragment +HYPHEN_f: + '-' +; + +/** Matches only unsigned integer numbers. */ +UNSIGNED_INT: NUM_f - | DOT NUM_f - | NUM_f DOT NUM_f ; /** */ +fragment NUM_f: ('0'..'9')+ ; +/** */ +fragment +E_NOTATION_f: + [Ee] WHITE_SPACE_f? [+-]? WHITE_SPACE_f? NUM_f +; + /** */ TXT: - ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '-' {_input.LA(1) != '>'}? | '+' | '&' | ';' | ',' | '$' | ':' | '%' | '^' | '~' {_input.LA(1) != '='}? | '`' | '´' | 'ö' | 'ä' | 'ß' | 'ü' | 'Ö' | 'Ä' | 'Ü' | '@' | '[' | ']' | '{' | '}' )+ + ('a'..'z' | 'A'..'Z' | NUM_f | '_' | '-' {_input.LA(1) != '>'}? | '+' | '&' | ';' | ',' | '$' | ':' | '%' | '^' | '~' {_input.LA(1) != '='}? | '`' | '´' | 'ö' | 'ä' | 'ß' | 'ü' | 'Ö' | 'Ä' | 'Ü' | '@' | '[' | ']' | '{' | '}' )+ ; /** */ diff --git a/src/main/java/org/caosdb/server/query/CQLParser.g4 b/src/main/java/org/caosdb/server/query/CQLParser.g4 index bcb4645a..f4d4e50d 100644 --- a/src/main/java/org/caosdb/server/query/CQLParser.g4 +++ b/src/main/java/org/caosdb/server/query/CQLParser.g4 @@ -281,20 +281,20 @@ transaction_time returns [String tqp, String op] */ datetime : - NUM // year + UNSIGNED_INT // year ( - HYPHEN NUM // mon + HYPHEN UNSIGNED_INT // mon ( - HYPHEN NUM // day of mon + HYPHEN UNSIGNED_INT // day of mon ( (m=TXT {$m.text.equals("T")}?)?// compliance with iso datetime - NUM // hour + UNSIGNED_INT // hour ( - COLON NUM // minut + COLON UNSIGNED_INT // minut ( - COLON NUM // sec + COLON UNSIGNED_INT // sec ( - DOT NUM // millisec + DOT UNSIGNED_INT // millisec )? )? )? @@ -578,7 +578,7 @@ property returns [Query.Pattern pp, String agg]locals [StringBuffer sb] | like_pattern {$pp = $like_pattern.ep;} | ( double_quoted {$pp = $double_quoted.ep;} ) | ( single_quoted {$pp = $single_quoted.ep;} ) - | ((m=TXT | m=NUM | m=REGEXP_MARKER | m=ENTITY){$sb.append($m.text);})+ {$pp = new Query.Pattern($sb.toString(), Query.Pattern.TYPE_NORMAL);} + | ((m=TXT | m=UNSIGNED_INT | m=UNSIGNED_DECIMAL_NUMBER | m=REGEXP_MARKER | m=ENTITY){$sb.append($m.text);})+ {$pp = new Query.Pattern($sb.toString(), Query.Pattern.TYPE_NORMAL);} ) WHITE_SPACE? ; @@ -610,9 +610,8 @@ value returns [String str] */ number_with_unit : - HYPHEN?? - NUM - (WHITE_SPACE?? unit)? + ( UNSIGNED_INT | DECIMAL_NUMBER ) + (WHITE_SPACE? unit)? ; /** @@ -623,7 +622,7 @@ unit (~(WHITE_SPACE | WHICH | HAS_A | WITH_A | WHERE | DOT | AND | OR | RPAREN )) (~(WHITE_SPACE))* | - NUM SLASH (~(WHITE_SPACE))+ + HYPHEN?? UNSIGNED_INT SLASH (~(WHITE_SPACE))+ ; /** diff --git a/src/main/java/org/caosdb/server/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java index 7c5176b9..7fa1f590 100644 --- a/src/main/java/org/caosdb/server/query/POV.java +++ b/src/main/java/org/caosdb/server/query/POV.java @@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory; public class POV implements EntityFilterInterface { public static final Pattern NUMBER_PATTERN = - Pattern.compile("^((?:-\\s*)?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)\\s*([^-]*)$"); + Pattern.compile("^((?:-\\s*)?[0-9]+(?:\\.[0-9]+)?(?:\\s*[eE]\\s*[+-]?[0-9]+)?)\\s*([^-]*)$"); private SubProperty subp = null; public static int retry = 10; private int retry_count = 0; @@ -123,7 +123,7 @@ public class POV implements EntityFilterInterface { throw new NumberFormatException(); } final String vIntStr = m.group(1); - this.vInt = Integer.parseInt(vIntStr); + this.vInt = Integer.parseInt(vIntStr.replaceAll("\\s", "")); this.unitStr = m.group(2); } catch (final NumberFormatException e) { this.vInt = null; @@ -139,7 +139,7 @@ public class POV implements EntityFilterInterface { } final String vDoubleStr = m.group(1); - this.vDouble = Double.parseDouble(vDoubleStr); + this.vDouble = Double.parseDouble(vDoubleStr.replaceAll("\\s", "")); this.unitStr = m.group(2); } catch (final NumberFormatException e) { this.vDouble = null; diff --git a/src/test/java/org/caosdb/server/query/POVTest.java b/src/test/java/org/caosdb/server/query/POVTest.java index 9f2b9576..bf438a84 100644 --- a/src/test/java/org/caosdb/server/query/POVTest.java +++ b/src/test/java/org/caosdb/server/query/POVTest.java @@ -37,7 +37,7 @@ class POVTest { @ValueSource( strings = { "1e+3", "1E+3", "5e9", "5E9", "16", MAX_INT, MIN_INT, "0", "-0", "1", "- 1", "-1", "2e-323", - "2E-323" + "2E-323", "2 e -23" }) void testNumberPatternMatchDouble(String doubleValue) { diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java index 053a4827..0c6307a5 100644 --- a/src/test/java/org/caosdb/server/query/TestCQL.java +++ b/src/test/java/org/caosdb/server/query/TestCQL.java @@ -7018,7 +7018,22 @@ public class TestCQL { } @ParameterizedTest - @ValueSource(strings = {"1e+23", "1E+23", "5e22", "5E22", "2e-323", "2E-323"}) + @ValueSource( + strings = { + "1e+23", + "1E+23", + "5e22", + "5E22", + "2e-323", + "2E-323", + "-123", + "-1e23", + "2 e -23", + "3E15m^2", + "-3e15m", + "-3e15 1/s", + "3e15 m^2" + }) public void testIssue144(String scientific_notation) { CQLLexer lexer; lexer = new CQLLexer(CharStreams.fromString(this.issue144 + scientific_notation)); @@ -7027,8 +7042,15 @@ public class TestCQL { final CQLParser parser = new CQLParser(tokens); final CqContext sfq = parser.cq(); + for (final Token t : tokens.getTokens()) { + System.out.println(t.toString()); + } + + System.out.println(sfq.toStringTree(parser)); + assertTrue(sfq.filter instanceof POV); POV pov = (POV) sfq.filter; assertEquals("POV(pname,=," + scientific_notation + ")", pov.toString()); + assertTrue(pov.getVDouble() != null || pov.getVInt() != null); } } -- GitLab