Repository: tobymao/sqlglot
Pull request: Fix(snowflake): apply range parser after colon, if any
Fixes #2798

Problem statement:
ParseError when using LIKE/ILIKE on an element in an object in Snowflake
I'm getting `ParseError: Invalid expression / Unexpected token` when using `LIKE` or `ILIKE` on an element within an object in Snowflake.

Example:
```
import sqlglot
sqlglot.parse(""" select parse_json('{"x": "hello"}'):x like 'hello' """, read="snowflake")
sqlglot.parse(""" select data:x like 'hello' from some_table """, read="snowflake")
```

Both of these cause the parsing error, but both are valid Snowflake statements.

Hints from issue discussion:

Commit message: Fix(snowflake): apply range parser after colon, if any

Patch to review:
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
index ad14e6ee74..ddd36826e3 100644
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -328,6 +328,10 @@ def _parse_colon_get_path(
         if not self._match(TokenType.COLON):
             break
 
+    if self._match_set(self.RANGE_PARSERS):
+        expression = self.RANGE_PARSERS[self._prev.token_type](self, this)
+        this = expression if isinstance(expression, exp.Expression) else this
+
     return this
 
 
diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
index 602bc63027..39963b2817 100644
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -78,6 +78,14 @@ def test_snowflake(self):
         self.validate_identity(
             "SELECT a FROM test PIVOT(SUM(x) FOR y IN ('z', 'q')) AS x TABLESAMPLE (0.1)"
         )
+        self.validate_identity(
+            """SELECT PARSE_JSON('{"x": "hello"}'):x LIKE 'hello'""",
+            """SELECT GET_PATH(PARSE_JSON('{"x": "hello"}'), 'x') LIKE 'hello'""",
+        )
+        self.validate_identity(
+            """SELECT data:x LIKE 'hello' FROM some_table""",
+            """SELECT GET_PATH(data, 'x') LIKE 'hello' FROM some_table""",
+        )
         self.validate_identity(
             "SELECT SUM({ fn CONVERT(123, SQL_DOUBLE) })",
             "SELECT SUM(CAST(123 AS DOUBLE))",


Code review comments:
diff_hunk: @@ -328,6 +328,10 @@ def _parse_colon_get_path(
         if not self._match(TokenType.COLON):
             break
 
+    if self._match_set(self.RANGE_PARSERS):
+        expression = self.RANGE_PARSERS[self._prev.token_type](self, this)
+        this = expression if isinstance(expression, exp.Expression) else this
path: sqlglot/dialects/snowflake.py
text: @user1:
this = expression or this ?