From 433c6f56a9a1d69f2979a07a9e1446cd44a90f38 Mon Sep 17 00:00:00 2001
From: Denis Smirnov <sd@picodata.io>
Date: Mon, 18 Jul 2022 21:18:50 +0700
Subject: [PATCH] feat(grammar): add ascii non-letter symbols to the values

---
 src/frontend/sql/ir/tests.rs | 19 +++++++++++++++++++
 src/frontend/sql/query.pest  | 18 +++++++++++++++---
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/frontend/sql/ir/tests.rs b/src/frontend/sql/ir/tests.rs
index a7390f7b99..e2e9ae0e3c 100644
--- a/src/frontend/sql/ir/tests.rs
+++ b/src/frontend/sql/ir/tests.rs
@@ -418,3 +418,22 @@ fn front_params3() {
 
     assert_eq!(sql_to_sql(pattern, &params, &no_transform), expected);
 }
+
+// check symbols in values (grammar)
+#[test]
+fn front_params4() {
+    let pattern = r#"SELECT "id" FROM "test_space"
+        WHERE "FIRST_NAME" = '''±!@#$%^&*()_+=-\/><";:,.`~'"#;
+
+    let params = vec![Value::from(r#"''±!@#$%^&*()_+=-\/><";:,.`~"#)];
+    let expected = PatternWithParams::new(
+        format!(
+            "{} {}",
+            r#"SELECT "test_space"."id" as "id" FROM "test_space""#,
+            r#"WHERE ("test_space"."FIRST_NAME") = (?)"#,
+        ),
+        params,
+    );
+
+    assert_eq!(sql_to_sql(pattern, &vec![], &no_transform), expected);
+}
diff --git a/src/frontend/sql/query.pest b/src/frontend/sql/query.pest
index 7506b447b1..c9097c565c 100644
--- a/src/frontend/sql/query.pest
+++ b/src/frontend/sql/query.pest
@@ -13,7 +13,7 @@ Query = _{ UnionAll | Select | Values | Insert }
                 Reference = { (ScanName ~ "." ~ ColumnName) | ColumnName }
                     ColumnName = @{ Name }
                     ScanName = @{ Name }
-                    Name = @{ String | ("\"" ~ String ~ "\"") }
+                    Name = @{ NameString | ("\"" ~ NameString ~ "\"") }
                 Asterisk = @{ "*" }
         Selection = { Expr+ }
         Scan = { (SubQuery | Table) ~ (^"as" ~ ScanName)? }
@@ -59,8 +59,20 @@ Expr = _{  Or | And | Cmp | Primary | Parentheses }
         OrLeft = _{ AndRight }
         OrRight = _{ Or | OrLeft }
 
-String = @{ !(WHITESPACE* ~ Keyword ~ WHITESPACE) ~ ('А' .. 'Я' | 'а' .. 'я' | 'A' .. 'Z' | 'a'..'z' | "-" | "_" | ASCII_DIGIT)+ }
-    Keyword = { ^"union" | ^"where" }
+
+NameString = @{ !(WHITESPACE* ~ Keyword ~ WHITESPACE) ~ ('А' .. 'Я' | 'а' .. 'я' | 'A' .. 'Z' | 'a'..'z' | "-" | "_" | ASCII_DIGIT)+ }
+String = @{ !(WHITESPACE* ~ Keyword ~ WHITESPACE) ~ (Character | ("'" ~ "'") | "\"")+ }
+Keyword = { ^"union" | ^"where" }
+Character = _{ ASCII_ALPHANUMERIC | 'А' .. 'Я' | 'а' .. 'я' | Other | Punctuation | SYMBOL }
+Punctuation = _{
+    CONNECTOR_PUNCTUATION
+    | DASH_PUNCTUATION
+    | OPEN_PUNCTUATION
+    | CLOSE_PUNCTUATION
+    | INITIAL_PUNCTUATION
+    | "." | "?" | "!" | ":" | ";" | ","
+}
+Other = _{ "\\" | "/" | "@" | "%" | "&" | "*" | "#" }
 
 Value = _{ Parameter | Row | True | False | Null | Decimal | Double | Unsigned | Integer | SingleQuotedString }
     True = @{ ^"true" }
-- 
GitLab