Skip to content

Commit 79f6783

Browse files
fix(snowflake): Wrap DIV0 operands if they're binary expressions (#4393)
* fix(snowflake): Wrap DIV0 operands if they're binary ops * Add _wrap variants * Simplify _wrap --------- Co-authored-by: Jo <[email protected]>
1 parent 37c4809 commit 79f6783

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

sqlglot/dialects/snowflake.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,14 @@ def _builder(args: t.List) -> E:
106106

107107
# https://docs.snowflake.com/en/sql-reference/functions/div0
108108
def _build_if_from_div0(args: t.List) -> exp.If:
109-
cond = exp.EQ(this=seq_get(args, 1), expression=exp.Literal.number(0)).and_(
110-
exp.Is(this=seq_get(args, 0), expression=exp.null()).not_()
109+
lhs = exp._wrap(seq_get(args, 0), exp.Binary)
110+
rhs = exp._wrap(seq_get(args, 1), exp.Binary)
111+
112+
cond = exp.EQ(this=rhs, expression=exp.Literal.number(0)).and_(
113+
exp.Is(this=lhs, expression=exp.null()).not_()
111114
)
112115
true = exp.Literal.number(0)
113-
false = exp.Div(this=seq_get(args, 0), expression=seq_get(args, 1))
116+
false = exp.Div(this=lhs, expression=rhs)
114117
return exp.If(this=cond, true=true, false=false)
115118

116119

sqlglot/expressions.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6972,7 +6972,15 @@ def _combine(
69726972
return this
69736973

69746974

6975-
def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
6975+
@t.overload
6976+
def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
6977+
6978+
6979+
@t.overload
6980+
def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
6981+
6982+
6983+
def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
69766984
return Paren(this=expression) if isinstance(expression, kind) else expression
69776985

69786986

tests/dialects/test_snowflake.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,17 @@ def test_snowflake(self):
605605
"duckdb": "CASE WHEN bar = 0 AND NOT foo IS NULL THEN 0 ELSE foo / bar END",
606606
},
607607
)
608+
self.validate_all(
609+
"DIV0(a - b, c - d)",
610+
write={
611+
"snowflake": "IFF((c - d) = 0 AND NOT (a - b) IS NULL, 0, (a - b) / (c - d))",
612+
"sqlite": "IIF((c - d) = 0 AND NOT (a - b) IS NULL, 0, CAST((a - b) AS REAL) / (c - d))",
613+
"presto": "IF((c - d) = 0 AND NOT (a - b) IS NULL, 0, CAST((a - b) AS DOUBLE) / (c - d))",
614+
"spark": "IF((c - d) = 0 AND NOT (a - b) IS NULL, 0, (a - b) / (c - d))",
615+
"hive": "IF((c - d) = 0 AND NOT (a - b) IS NULL, 0, (a - b) / (c - d))",
616+
"duckdb": "CASE WHEN (c - d) = 0 AND NOT (a - b) IS NULL THEN 0 ELSE (a - b) / (c - d) END",
617+
},
618+
)
608619
self.validate_all(
609620
"ZEROIFNULL(foo)",
610621
write={

0 commit comments

Comments
 (0)