Skip to content

Commit

Permalink
Fix(snowflake, bigquery): parse COLLATE as a func instead of a binary…
Browse files Browse the repository at this point in the history
… operator (#2343)

* Fix(snowflake): parse COLLATE as a func instead of a binary operator

* BigQuery also has the COLLATE function
  • Loading branch information
georgesittas authored Sep 28, 2023
1 parent bcd342a commit 79c208a
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 1 deletion.
1 change: 1 addition & 0 deletions sqlglot/dialects/bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ class Generator(generator.Generator):
ESCAPE_LINE_BREAK = True
NVL2_SUPPORTED = False
UNNEST_WITH_ORDINALITY = False
COLLATE_IS_FUNC = True

TRANSFORMS = {
**generator.Generator.TRANSFORMS,
Expand Down
1 change: 1 addition & 0 deletions sqlglot/dialects/snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ class Generator(generator.Generator):
QUERY_HINTS = False
AGGREGATE_FILTER_SUPPORTED = False
SUPPORTS_TABLE_COPY = False
COLLATE_IS_FUNC = True

TRANSFORMS = {
**generator.Generator.TRANSFORMS,
Expand Down
2 changes: 1 addition & 1 deletion sqlglot/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4279,7 +4279,7 @@ class CastToStrType(Func):
arg_types = {"this": True, "to": True}


class Collate(Binary):
class Collate(Binary, Func):
pass


Expand Down
5 changes: 5 additions & 0 deletions sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ class Generator:
# Whether or not parentheses are required around the table sample's expression
TABLESAMPLE_REQUIRES_PARENS = True

# Whether or not COLLATE is a function instead of a binary operator
COLLATE_IS_FUNC = False

TYPE_MAPPING = {
exp.DataType.Type.NCHAR: "CHAR",
exp.DataType.Type.NVARCHAR: "VARCHAR",
Expand Down Expand Up @@ -2321,6 +2324,8 @@ def currentdate_sql(self, expression: exp.CurrentDate) -> str:
return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE"

def collate_sql(self, expression: exp.Collate) -> str:
if self.COLLATE_IS_FUNC:
return self.function_fallback_sql(expression)
return self.binary(expression, "COLLATE")

def command_sql(self, expression: exp.Command) -> str:
Expand Down
1 change: 1 addition & 0 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ class Parser(metaclass=_Parser):
TRIM_TYPES = {"LEADING", "TRAILING", "BOTH"}

FUNC_TOKENS = {
TokenType.COLLATE,
TokenType.COMMAND,
TokenType.CURRENT_DATE,
TokenType.CURRENT_DATETIME,
Expand Down
7 changes: 7 additions & 0 deletions tests/dialects/test_snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ def test_snowflake(self):
self.validate_all("CAST(x AS CHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS CHARACTER VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS NCHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all(
"SELECT COLLATE('B', 'und:ci')",
write={
"bigquery": "SELECT COLLATE('B', 'und:ci')",
"snowflake": "SELECT COLLATE('B', 'und:ci')",
},
)
self.validate_all(
"SELECT * FROM x START WITH a = b CONNECT BY c = PRIOR d",
read={
Expand Down

0 comments on commit 79c208a

Please sign in to comment.