Repository: AfterShip/clickhouse-sql-parser (go)

Issue:
Failed to parse query with $ in column name
The following query throws error **_line 0:30 <EOF> or ';' was expected, but got: "$"_**

```sql
SELECT service$$name FROM test_table
```

On the other hand, this works
```sql
SELECT `service$$name` FROM test_table
```

When we run `SELECT service$$name FROM test_table`, CH automatically add "``" to such columns. The parser should recognise that and not throw an error.

Pull request description:
Fix dollar sign should be a valid part of the identifier
This closes #144 

Patch:
diff --git a/parser/helper.go b/parser/helper.go
index d251b8e..72d1f57 100644
--- a/parser/helper.go
+++ b/parser/helper.go
@@ -13,5 +13,5 @@ func IsIdentStart(c byte) bool {
 }
 
 func IsIdentPart(c byte) bool {
-	return '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_'
+	return '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '$'
 }
diff --git a/parser/lexer.go b/parser/lexer.go
index b0a227b..7c676a4 100644
--- a/parser/lexer.go
+++ b/parser/lexer.go
@@ -188,7 +188,7 @@ func (l *Lexer) consumeIdent(_ Pos) error {
 
 	i := 0
 	if quoteType == Unquoted {
-		if l.peekN(i) == '$' {
+		if l.peekOk(i) && l.peekN(i) == '$' {
 			i++
 		}
 		for l.peekOk(i) && IsIdentPart(l.peekN(i)) {


Test patch:
diff --git a/parser/testdata/query/format/select_column_alias_string.sql b/parser/testdata/query/format/select_column_alias_string.sql
index ebae210..c3db404 100644
--- a/parser/testdata/query/format/select_column_alias_string.sql
+++ b/parser/testdata/query/format/select_column_alias_string.sql
@@ -1,5 +1,9 @@
 -- Origin SQL:
 SELECT 'abc' as "value2";
 
+SELECT $abc, a$$bc, abc$$;
+
+
 -- Format SQL:
 SELECT 'abc' AS "value2";
+SELECT $abc, a$$bc, abc$$;
diff --git a/parser/testdata/query/output/select_column_alias_string.sql.golden.json b/parser/testdata/query/output/select_column_alias_string.sql.golden.json
index 271bc77..30279be 100644
--- a/parser/testdata/query/output/select_column_alias_string.sql.golden.json
+++ b/parser/testdata/query/output/select_column_alias_string.sql.golden.json
@@ -36,5 +36,59 @@
     "UnionAll": null,
     "UnionDistinct": null,
     "Except": null
+  },
+  {
+    "SelectPos": 27,
+    "StatementEnd": 52,
+    "With": null,
+    "Top": null,
+    "SelectItems": [
+      {
+        "Expr": {
+          "Name": "$abc",
+          "QuoteType": 1,
+          "NamePos": 34,
+          "NameEnd": 38
+        },
+        "Modifiers": [],
+        "Alias": null
+      },
+      {
+        "Expr": {
+          "Name": "a$$bc",
+          "QuoteType": 1,
+          "NamePos": 40,
+          "NameEnd": 45
+        },
+        "Modifiers": [],
+        "Alias": null
+      },
+      {
+        "Expr": {
+          "Name": "abc$$",
+          "QuoteType": 1,
+          "NamePos": 47,
+          "NameEnd": 52
+        },
+        "Modifiers": [],
+        "Alias": null
+      }
+    ],
+    "From": null,
+    "ArrayJoin": null,
+    "Window": null,
+    "Prewhere": null,
+    "Where": null,
+    "GroupBy": null,
+    "WithTotal": false,
+    "Having": null,
+    "OrderBy": null,
+    "LimitBy": null,
+    "Limit": null,
+    "Settings": null,
+    "Format": null,
+    "UnionAll": null,
+    "UnionDistinct": null,
+    "Except": null
   }
 ]
\ No newline at end of file
diff --git a/parser/testdata/query/select_column_alias_string.sql b/parser/testdata/query/select_column_alias_string.sql
index 53bfe9a..ac0601f 100644
--- a/parser/testdata/query/select_column_alias_string.sql
+++ b/parser/testdata/query/select_column_alias_string.sql
@@ -1,1 +1,3 @@
-SELECT 'abc' as "value2";
\ No newline at end of file
+SELECT 'abc' as "value2";
+
+SELECT $abc, a$$bc, abc$$;