Repository: tobymao/sqlglot

Issue:
A table named `case` throws a ParseError in Snowflake ❄️ 
This query works in Snowflake, but fails to get parsed:
```sql
SELECT * 
FROM my_schema.case
```

The following code was used:
```py
parse_one("SELECT * FROM my_schema.case", read=dialects.Snowflake)
```

<details><summary>Here is the tracelog:</summary>
<p>

```python

Traceback (most recent call last):
  File "/Users/florian.ernst/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/231.9011.38/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode
    coro = func()
  File "<input>", line 1, in <module>
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/__init__.py", line 158, in parse_one
    result = dialect.parse(sql, **opts)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/dialects/dialect.py", line 217, in parse
    return self.parser(**opts).parse(self.tokenize(sql), sql)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 856, in parse
    return self._parse(
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 922, in _parse
    expressions.append(parse_method(self))
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 1112, in _parse_statement
    expression = self._parse_set_operations(expression) if expression else self._parse_select()
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 1893, in _parse_select
    from_ = self._parse_from()
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 2031, in _parse_from
    this = self._parse_table()
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 2309, in _parse_table
    this: exp.Expression = self._parse_table_parts(schema=schema)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 2279, in _parse_table_parts
    table = self._parse_table_part(schema=schema)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 2259, in _parse_table_part
    (not schema and self._parse_function())
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 3137, in _parse_function
    return self.NO_PAREN_FUNCTION_PARSERS[token_type](self)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 699, in <lambda>
    TokenType.CASE: lambda self: self._parse_case(),
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 3562, in _parse_case
    self.raise_error("Expected END after CASE", self._prev)
  File "/Users/florian.ernst/Alan/alan-jobs/env/lib/python3.10/site-packages/sqlglot/parser.py", line 966, in raise_error
    raise error
sqlglot.errors.ParseError: Expected END after CASE. Line 1, Col: 28.
  SELECT * FROM my_schema.case

``` 

</p>
</details> 

Don't hesitate to ask if more information is needed 🙏 


Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py
--- a/sqlglot/dialects/clickhouse.py
+++ b/sqlglot/dialects/clickhouse.py
@@ -208,9 +208,14 @@ def _parse_join(self, skip_join_token: bool = False) -> t.Optional[exp.Join]:
             return join
 
         def _parse_function(
-            self, functions: t.Optional[t.Dict[str, t.Callable]] = None, anonymous: bool = False
+            self,
+            functions: t.Optional[t.Dict[str, t.Callable]] = None,
+            anonymous: bool = False,
+            optional_parens: bool = True,
         ) -> t.Optional[exp.Expression]:
-            func = super()._parse_function(functions, anonymous)
+            func = super()._parse_function(
+                functions=functions, anonymous=anonymous, optional_parens=optional_parens
+            )
 
             if isinstance(func, exp.Anonymous):
                 params = self._parse_func_params(func)
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -220,6 +220,7 @@ class Parser(metaclass=_Parser):
         TokenType.AUTO_INCREMENT,
         TokenType.BEGIN,
         TokenType.CACHE,
+        TokenType.CASE,
         TokenType.COLLATE,
         TokenType.COMMAND,
         TokenType.COMMENT,
@@ -2261,7 +2262,7 @@ def _parse_index(
 
     def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
         return (
-            (not schema and self._parse_function())
+            (not schema and self._parse_function(optional_parens=False))
             or self._parse_id_var(any_token=False)
             or self._parse_string_as_identifier()
             or self._parse_placeholder()
@@ -3137,18 +3138,21 @@ def _parse_field(
         )
 
     def _parse_function(
-        self, functions: t.Optional[t.Dict[str, t.Callable]] = None, anonymous: bool = False
+        self,
+        functions: t.Optional[t.Dict[str, t.Callable]] = None,
+        anonymous: bool = False,
+        optional_parens: bool = True,
     ) -> t.Optional[exp.Expression]:
         if not self._curr:
             return None
 
         token_type = self._curr.token_type
 
-        if self._match_set(self.NO_PAREN_FUNCTION_PARSERS):
+        if optional_parens and self._match_set(self.NO_PAREN_FUNCTION_PARSERS):
             return self.NO_PAREN_FUNCTION_PARSERS[token_type](self)
 
         if not self._next or self._next.token_type != TokenType.L_PAREN:
-            if token_type in self.NO_PAREN_FUNCTIONS:
+            if optional_parens and token_type in self.NO_PAREN_FUNCTIONS:
                 self._advance()
                 return self.expression(self.NO_PAREN_FUNCTIONS[token_type])
 


Test patch:
diff --git a/tests/fixtures/identity.sql b/tests/fixtures/identity.sql
--- a/tests/fixtures/identity.sql
+++ b/tests/fixtures/identity.sql
@@ -826,3 +826,7 @@ SELECT PERCENTILE_CONT(x, 0.5 RESPECT NULLS) OVER ()
 SELECT PERCENTILE_CONT(x, 0.5 IGNORE NULLS) OVER ()
 WITH my_cte AS (SELECT 'a' AS desc) SELECT desc AS description FROM my_cte
 WITH my_cte AS (SELECT 'a' AS asc) SELECT asc AS description FROM my_cte
+SELECT * FROM case
+SELECT * FROM schema.case
+SELECT * FROM current_date
+SELECT * FROM schema.current_date