Repository: tobymao/sqlglot

Issue:
Snowflake: Columns Containing $ Symbol Not Parsing
In Snowflake's dialect, column names can contain the `$` symbol. However, SQLGlot is unable to parse queries when containing one. For example, when parsing the query `create table target_table (A$B string)`, I see the error:

```
File "/var/folders/by/xw3fz9wx0sz3nj6mvd941gpm0000gn/T/ipykernel_81232/3309812867.py", line 7, in <module>
    sqlglot.parse_one(query_text, read="snowflake")
  File ".../python3.11/site-packages/sqlglot/__init__.py", line 147, in parse_one
    result = dialect.parse(sql, **opts)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/dialects/dialect.py", line 163, in parse
    return self.parser(**opts).parse(self.tokenize(sql), sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 809, in parse
    return self._parse(
           ^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 872, in _parse
    expressions.append(parse_method(self))
                       ^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 1029, in _parse_statement
    return self.STATEMENT_PARSERS[self._prev.token_type](self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 471, in <lambda>
    TokenType.CREATE: lambda self: self._parse_create(),
                                   ^^^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 1126, in _parse_create
    this = self._parse_schema(this=table_parts)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.11/site-packages/sqlglot/parser.py", line 3026, in _parse_schema
    self._match_r_paren()
  File ".../python3.11/site-packages/sqlglot/parser.py", line 4220, in _match_r_paren
    self.raise_error("Expecting )")
  File ".../python3.11/site-packages/sqlglot/parser.py", line 918, in raise_error
    raise error
sqlglot.errors.ParseError: Expecting ). Line 2, Col: 29.
  
create table target_table (A$B string)
                                               ^
```


Discussion:
can you show the input sql please
Yes, `create table target_table (A$B string)`
I think what is happening is SQLGlot treats `$` as the start of a parameter in Snowflake queries

Resolving patch:
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -272,6 +272,8 @@ class Tokenizer(tokens.Tokenizer):
             "$": TokenType.PARAMETER,
         }
 
+        VAR_SINGLE_TOKENS = {"$"}
+
     class Generator(generator.Generator):
         PARAMETER_TOKEN = "$"
         MATCHED_BY_SOURCE = False
diff --git a/sqlglot/tokens.py b/sqlglot/tokens.py
--- a/sqlglot/tokens.py
+++ b/sqlglot/tokens.py
@@ -442,6 +442,8 @@ class Tokenizer(metaclass=_Tokenizer):
         "#": TokenType.HASH,
     }
 
+    VAR_SINGLE_TOKENS: t.Set[str] = set()
+
     QUOTES: t.List[t.Tuple[str, str] | str] = ["'"]
 
     BIT_STRINGS: t.List[str | t.Tuple[str, str]] = []
@@ -1111,7 +1113,7 @@ def _scan_identifier(self, identifier_end: str) -> None:
     def _scan_var(self) -> None:
         while True:
             char = self._peek.strip()  # type: ignore
-            if char and char not in self.SINGLE_TOKENS:
+            if char and (char in self.VAR_SINGLE_TOKENS or char not in self.SINGLE_TOKENS):
                 self._advance()
             else:
                 break


Test patch:
diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -13,7 +13,8 @@ def test_snowflake(self):
         self.validate_identity("SELECT HLL(DISTINCT t.a)")
         self.validate_identity("SELECT HLL(a, b, c)")
         self.validate_identity("SELECT HLL(DISTINCT a, b, c)")
-        self.validate_identity("$x")
+        self.validate_identity("$x")  # parameter
+        self.validate_identity("a$b")  # valid snowflake identifier
         self.validate_identity("SELECT REGEXP_LIKE(a, b, c)")
         self.validate_identity("PUT file:///dir/tmp.csv @%table")
         self.validate_identity("CREATE TABLE foo (bar FLOAT AUTOINCREMENT START 0 INCREMENT 1)")