求助:如何用sqlglot完成指定SQL函数调用的后缀追加与格式补全?
使用SQLGlot完成SQL函数调用的格式转换
问题背景
需要将SQL语句:
select * from table where date > abc.def(2 * days)
转换为:
select * from table where date > {@abc.def(2 * days).xyz(yyyy)}
已完成部分转换(将abc改为{@abc}),但需要进一步实现def(2 * days)到def(2 * days).xyz(yyyy)}的修改,最终达成目标格式。
解决方案
原表达式中的abc.def(2 * days)是一个函数调用(Call)节点,而非单纯的变量(Var)。需要定位该Call节点,添加链式调用.xyz(yyyy),再将整体包裹到{@...}结构中。完整代码如下:
import sqlglot # 原始SQL查询 query = "select * from table where date > abc.def(2 * days)" tree = sqlglot.parse_one(query) # 定位WHERE子句中大于号表达式的右侧(即abc.def(2 * days)这个Call节点) gt_expr = tree.find(sqlglot.exp.GT) original_call = gt_expr.right # 构造.xyz(yyyy)的Call节点,将原Call作为它的归属对象 xyz_call = sqlglot.exp.Call( this=original_call, name="xyz", args=[sqlglot.exp.Literal(this="yyyy", is_string=True)] ) # 将链式调用结果包裹在{@...}中,替换原大于号表达式的右侧 gt_expr.replace( sqlglot.exp.GT( left=gt_expr.left, right=sqlglot.exp.Var(this="{@" + xyz_call.sql() + "}") ) ) # 输出转换后的SQL print(tree.sql())
代码说明
- 定位目标节点:通过
tree.find(sqlglot.exp.GT)找到WHERE子句中的大于比较表达式,取其右侧即为abc.def(2 * days)对应的Call节点。 - 构造链式调用:创建
xyz(yyyy)的Call节点,将原Call节点赋值给this参数,形成abc.def(...).xyz(yyyy)的链式调用结构。 - 包裹格式标签:将链式调用的SQL字符串拼接进
{@和},作为Var节点的内容,替换原比较表达式的右侧。 - 生成结果:通过
tree.sql()输出最终转换后的SQL语句。
内容的提问来源于stack exchange,提问作者Aman Sharma
相关产品推荐
相关产品推荐

