From 00cac46947b202aec3a9148d6a49d711e4bc2116 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Mon, 16 Oct 2023 12:17:46 +0200
Subject: [PATCH] FIX: parsing of decimal numbers

---
 CHANGELOG.md                                  |  1 +
 README_SETUP.md                               |  3 ++
 .../java/org/caosdb/server/query/CQLLexer.g4  |  8 ++---
 .../java/org/caosdb/server/query/TestCQL.java | 29 +++++++++++++++++++
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4d71f73..67af8491 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * Wrong url returned by FileSystem resource behind proxy.
 * `NullPointerException` in GRPC API converters when executing SELECT query on
   NULL values.
+* Fix parsing of decimal numbers. Fixes https://gitlab.com/linkahead/linkahead-server/-/issues/239
 
 ### Security ###
 
diff --git a/README_SETUP.md b/README_SETUP.md
index acb3a79a..e3b6e3bc 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -163,6 +163,9 @@ sources (if you called `make run` previously).
 
 `$ make test`
 
+You can run single unit test with
+`mvn test -X -Dtest=TestCQL#testDecimalNumber`
+
 
 ## Setup Eclipse
 
diff --git a/src/main/java/org/caosdb/server/query/CQLLexer.g4 b/src/main/java/org/caosdb/server/query/CQLLexer.g4
index be6dcfa9..f21caf26 100644
--- a/src/main/java/org/caosdb/server/query/CQLLexer.g4
+++ b/src/main/java/org/caosdb/server/query/CQLLexer.g4
@@ -433,7 +433,7 @@ WHITE_SPACE_f:
 
 /** */
 WHITE_SPACE:
-    [ \t\n\r]+
+    WHITE_SPACE_f
 ;
 
 /** */
@@ -529,9 +529,9 @@ COLON:
 
 /** Matches signed and unsigned numbers with decimal points, also numbers in scientific notation. */
 DECIMAL_NUMBER:
-    ((HYPHEN_f | PLUS ) WHITE_SPACE_f?)? 
-    ( NUM_f? DOT NUM_f WHITE_SPACE_f? E_NOTATION_f?
-    | NUM_f WHITE_SPACE_f? E_NOTATION_f
+    ((HYPHEN_f | PLUS ) WHITE_SPACE_f?)?
+    ( NUM_f? DOT NUM_f (WHITE_SPACE_f? E_NOTATION_f)?
+    | NUM_f (WHITE_SPACE_f? E_NOTATION_f)?
     )
 ;
 
diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java
index 8d7a7e8f..5cf62325 100644
--- a/src/test/java/org/caosdb/server/query/TestCQL.java
+++ b/src/test/java/org/caosdb/server/query/TestCQL.java
@@ -36,6 +36,7 @@ import java.util.regex.Matcher;
 import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.Vocabulary;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.database.access.Access;
@@ -7103,4 +7104,32 @@ public class TestCQL {
     assertTrue(conj.getFilters().get(0) instanceof POV);
     assertTrue(conj.getFilters().get(1) instanceof POV);
   }
+
+  @Test
+  public void testDecimalNumber() {
+    // This should always be DEC, WHITESPACE, AND  repeat
+    final String text =
+        "1.2123e+3 AND 1.21234E+3 AND 1.21234E-3 AND 1.21234E3 AND 16.0 AND 1.2 AND -1.2 AND +1.2 AND 1.2 AND - 1.2 AND + 1.2 AND 2e-323 AND 2E-323 AND 2E- 323 AND 2 e -323 AND + 1.2123e+323";
+    CQLLexer lexer = new CQLLexer(CharStreams.fromString(text));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+    Vocabulary vocab = lexer.getVocabulary();
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+    int no = 0;
+    for (final Token t : tokens.getTokens()) {
+      if (no % 3 == 0) {
+        assertEquals(vocab.getSymbolicName(t.getType()), "DECIMAL_NUMBER");
+      }
+      if (no % 3 == 1) {
+        if (vocab.getSymbolicName(t.getType()) != "EOF") {
+          assertEquals(vocab.getSymbolicName(t.getType()), "WHITE_SPACE");
+        }
+      }
+      if (no % 3 == 2) {
+        assertEquals(vocab.getSymbolicName(t.getType()), "AND");
+      }
+      no = no + 1;
+    }
+  }
 }
-- 
GitLab