Sqlglot转换Snowflake SQL时DATEDIFF函数参数异常问题
解决sqlglot transpile格式化Snowflake SQL时DATEDIFF函数被错误修改的问题
问题场景
使用sqlglot.transpile(query, write="snowflake", pretty=True)[0]对Snowflake SQL进行格式化时,函数结构被篡改:原SQL中的DATEDIFF(day, first_activity_date, CURRENT_TIMESTAMP())被错误转换为DATEDIFF(, first_activity_date, day),参数顺序颠倒且出现前导逗号,导致SQL执行失败。需求仅为格式化美化SQL,无需修改函数语法结构。
输入SQL
WITH first_activity AS ( SELECT USER_ID, MIN(TO_TIMESTAMP(EVENT_DATE)) AS first_activity_date FROM DF.USER_EVENTS GROUP BY USER_ID ) SELECT COUNT(*) AS active_users_count FROM first_activity WHERE DATEDIFF(day, first_activity_date, CURRENT_TIMESTAMP()) > 90
错误输出SQL
WITH first_activity AS ( SELECT USER_ID, MIN(TO_TIMESTAMP(EVENT_DATE)) AS first_activity_date FROM DF.USER_EVENTS GROUP BY USER_ID ) SELECT COUNT(*) AS active_users_count FROM first_activity WHERE DATEDIFF(, first_activity_date, day) > 90
解决方案
- 仅做格式化,不指定目标方言
如果不需要转换方言,仅需美化格式,直接移除write="snowflake"参数,sqlglot会保留原SQL的函数语法:
formatted_sql = sqlglot.transpile(query, pretty=True)[0]
- 明确指定读写方言为Snowflake
若必须指定Snowflake方言,同时设置read="snowflake"和write="snowflake",确保sqlglot正确解析并生成符合Snowflake语法的函数:
formatted_sql = sqlglot.transpile(query, read="snowflake", write="snowflake", pretty=True)[0]
- 升级sqlglot到最新版本
该问题可能是旧版本sqlglot的方言映射bug,升级到最新版本可修复这类问题:
pip install --upgrade sqlglot
原因分析
Snowflake的DATEDIFF语法为DATEDIFF(<date_part>, <start_date>, <end_date>),sqlglot在未明确指定原方言时,可能错误映射为其他方言的参数顺序,甚至出现参数丢失。明确指定读写方言或仅做格式化操作,可避免语法篡改问题。
内容的提问来源于stack exchange,提问作者darshan_r
相关产品推荐
相关产品推荐

