feat(snowflake)!: Transpilation support for TO_DECIMAL, TO_NUMBER,NUMERIC#7315
feat(snowflake)!: Transpilation support for TO_DECIMAL, TO_NUMBER,NUMERIC#7315fivetran-ashashankar wants to merge 3 commits intomainfrom
Conversation
| join_cols = [col for col in cond.find_all(exp.Column) if col.args.get("join_mark")] | ||
|
|
||
| left_join_table = set(col.table for col in join_cols) | ||
| if not left_join_table: |
There was a problem hiding this comment.
make style formatter modified the transforms.py
sqlglot/dialects/duckdb.py
Outdated
| @@ -4181,6 +4181,84 @@ def strtok_sql(self, expression: exp.Strtok) -> str: | |||
|
|
|||
| return self.function_fallback_sql(expression) | |||
|
|
|||
There was a problem hiding this comment.
Snowflake: TO_NUMBER(expr) defaults to NUMBER(38, 0) -> truncates decimals -> BIGINT
Oracle/others: TO_NUMBER(expr) defaults to NUMBER -> keeps decimals -> DOUBLE
Working on handling this difference. should I use is_snowflake here.
SQLGlot Integration Test ResultsComparing:
By Dialect
Overallmain: 113551 total, 111862 passed (pass rate: 98.5%), sqlglot version: sqlglot:RD-1069319_TO_NUMBER_DECIMAL_NUMERIC: 108302 total, 104092 passed (pass rate: 96.1%), sqlglot version: Transitions: ✅ 1 test(s) passed |
3264deb to
b285974
Compare
There was a problem hiding this comment.
What happened to the rest of the commetns / cases like #7315 (comment) ? (update(edit: no need to resolve these comments for now))
sqlglot/generators/snowflake.py
Outdated
| # Convert CAST to DECIMAL/NUMERIC to TO_NUMBER | ||
| if expression.is_type(exp.DType.DECIMAL): | ||
| # Extract precision and scale from DECIMAL(p, s) | ||
| params = expression.to.expressions or [] | ||
| precision = params[0].this if len(params) >= 1 and isinstance(params[0], exp.DataTypeParam) else None | ||
| scale = params[1].this if len(params) >= 2 and isinstance(params[1], exp.DataTypeParam) else None | ||
|
|
||
| to_number = exp.ToNumber( | ||
| this=expression.this, | ||
| precision=precision, | ||
| scale=scale, | ||
| safe=isinstance(expression, exp.TryCast), | ||
| ) | ||
| return self.tonumber_sql(to_number) |
There was a problem hiding this comment.
Why we added logic here ?
sqlglot/parsers/snowflake.py
Outdated
| def _build_to_number(args: t.List[exp.Expr]) -> exp.ToNumber: | ||
| """Build TO_NUMBER with Snowflake default precision/scale of (38, 0).""" | ||
| expr, arg1, arg2, arg3 = (seq_get(args, i) for i in range(4)) | ||
|
|
||
| # Determine if arg1 is format (string) or precision (number) | ||
| has_format = arg1 and arg1.is_string | ||
| format_arg, precision, scale = (arg1, arg2, arg3) if has_format else (None, arg1, arg2) | ||
|
|
||
| # Set Snowflake defaults when not specified | ||
| if precision is None and scale is None: | ||
| precision, scale = exp.Literal.number(38), exp.Literal.number(0) | ||
| elif precision and scale is None: | ||
| scale = exp.Literal.number(0) | ||
|
|
||
| return exp.ToNumber(this=expr, format=format_arg, precision=precision, scale=scale) |
There was a problem hiding this comment.
Is this function needed ?
we can do precision=seq_get(args, 2) or exp.Literal.number(...) right ? and use this logic directly in the parser dict. (like the previous implementation)
No description provided.