Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions sqlglot/dialects/snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ def _build_if_from_div0(args: t.List) -> exp.If:
return exp.If(this=cond, true=true, false=false)


# https://docs.snowflake.com/en/sql-reference/functions/div0null
def _build_if_from_div0null(args: t.List) -> exp.If:
lhs = exp._wrap(seq_get(args, 0), exp.Binary)
rhs = exp._wrap(seq_get(args, 1), exp.Binary)

cond = exp.EQ(this=rhs, expression=exp.Literal.number(0)).and_(
exp.Is(this=lhs, expression=exp.null()).not_()
)
true = exp.null()
false = exp.Div(this=lhs, expression=rhs)
return exp.If(this=cond, true=true, false=false)


# https://docs.snowflake.com/en/sql-reference/functions/zeroifnull
def _build_if_from_zeroifnull(args: t.List) -> exp.If:
cond = exp.Is(this=seq_get(args, 0), expression=exp.Null())
Expand Down Expand Up @@ -746,6 +759,7 @@ class Parser(parser.Parser):
"DATEDIFF": _build_datediff,
"DAYOFWEEKISO": exp.DayOfWeekIso.from_arg_list,
"DIV0": _build_if_from_div0,
"DIV0NULL": _build_if_from_div0null,
"EDITDISTANCE": lambda args: exp.Levenshtein(
this=seq_get(args, 0), expression=seq_get(args, 1), max_dist=seq_get(args, 2)
),
Expand Down
22 changes: 22 additions & 0 deletions tests/dialects/test_snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,28 @@ def test_snowflake(self):
"duckdb": "CASE WHEN (c - d) = 0 AND NOT (a - b) IS NULL THEN 0 ELSE (a - b) / (c - d) END",
},
)
self.validate_all(
"DIV0NULL(foo, bar)",
write={
"snowflake": "IFF(bar = 0 AND NOT foo IS NULL, NULL, foo / bar)",
"sqlite": "IIF(bar = 0 AND NOT foo IS NULL, NULL, CAST(foo AS REAL) / bar)",
"presto": "IF(bar = 0 AND NOT foo IS NULL, NULL, CAST(foo AS DOUBLE) / bar)",
"spark": "IF(bar = 0 AND NOT foo IS NULL, NULL, foo / bar)",
"hive": "IF(bar = 0 AND NOT foo IS NULL, NULL, foo / bar)",
"duckdb": "CASE WHEN bar = 0 AND NOT foo IS NULL THEN NULL ELSE foo / bar END",
},
)
self.validate_all(
"DIV0NULL(a - b, c - d)",
write={
"snowflake": "IFF((c - d) = 0 AND NOT (a - b) IS NULL, NULL, (a - b) / (c - d))",
"sqlite": "IIF((c - d) = 0 AND NOT (a - b) IS NULL, NULL, CAST((a - b) AS REAL) / (c - d))",
"presto": "IF((c - d) = 0 AND NOT (a - b) IS NULL, NULL, CAST((a - b) AS DOUBLE) / (c - d))",
"spark": "IF((c - d) = 0 AND NOT (a - b) IS NULL, NULL, (a - b) / (c - d))",
"hive": "IF((c - d) = 0 AND NOT (a - b) IS NULL, NULL, (a - b) / (c - d))",
"duckdb": "CASE WHEN (c - d) = 0 AND NOT (a - b) IS NULL THEN NULL ELSE (a - b) / (c - d) END",
},
)
self.validate_all(
"ZEROIFNULL(foo)",
write={
Expand Down
16 changes: 16 additions & 0 deletions tests/fixtures/optimizer/annotate_functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,22 @@ BINARY;
DECOMPRESS_STRING('compressed_data', 'ZSTD');
VARCHAR;

# dialect: snowflake
DIV0(10, 0);
DOUBLE;

# dialect: snowflake
DIV0(tbl.double_col, tbl.double_col);
DOUBLE;

# dialect: snowflake
DIV0NULL(10, 0);
DOUBLE;

# dialect: snowflake
DIV0NULL(tbl.double_col, tbl.double_col);
DOUBLE;

# dialect: snowflake
LPAD('Hello', 10, '*');
VARCHAR;
Expand Down