news 2026/9/24 17:53:45

SQLGlot 变更日志深度解读:从 v20 到 v30 的演进脉络与 v30.0.0 迁移指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQLGlot 变更日志深度解读:从 v20 到 v30 的演进脉络与 v30.0.0 迁移指南
  • 后端
  • 数据库

【免费下载链接】sqlglot

Python SQL Parser and Transpiler

项目地址:https://gitcode.com/gh_mirrors/sq/sqlglot
点击查看免费下载

SQLGlot 是一个用 Python 编写的 SQL 解析器与转译器(transpiler),支持 20+ 种方言的解析、转译与优化。本文以仓库根目录的 CHANGELOG.md 为骨架,系统梳理 SQLGlot 从 v20 到 v30 的版本演进节奏、变更内容分类体系,并重点深入解读 v30.0.0 这一"里程碑式"大版本中官方公布的 7 条迁移指南——涵盖 mypyc 编译加速、Rust tokenizer 移除、表达式模块包化等直接影响使用者代码的破坏性变更。读完本文,你将掌握如何阅读该变更日志、如何应对 v30 升级带来的 API 变化,以及如何在纯 Python 版与编译加速版sqlglot[c]之间做出选择。


一、CHANGELOG 文档概览:281 个版本、1.5 万行的演进档案

CHANGELOG.md是 SQLGlot 项目最完整、最权威的版本演进档案,全文共 15718 行,按"版本号 + 发布日期"组织章节(如## [v30.18.0] - 2026-09-03),共记录了281 个发布版本,覆盖从 2024 年 1 月的 v20.6.0 到 2026 年 9 月的 v30.18.0 的完整演进过程。

每个版本章节内部,变更被划分为统一的语义化分类(emoji 前缀),统计全文各分类出现的次数,可以直观看出项目各维度的活跃程度:

分类(章节标题)含义全文出现次数
### :boom: BREAKING CHANGES破坏性变更(可能影响既有使用者代码)155
### :sparkles: New Features新功能194
### :bug: Bug Fixes缺陷修复231
### :recycle: Refactors代码重构75
### :wrench: Chores工程杂项(依赖升级、CI、工具链)150
### :zap: Performance Improvements性能优化11
### :white_check_mark: Tests测试相关6

从统计可以看出,SQLGlot 的迭代以"高频小步快跑"为特征:Bug Fixes 与 New Features 数量领先,说明项目在持续扩展方言支持的同时也在快速修复兼容性问题;BREAKING CHANGES 高达 155 次,提示使用者升级版本时需要留意行为变化,尤其是各 major 版本(v26、v27、v28、v29、v30)。

文档中每条变更以 commit hash 为锚点,注明所属模块(如**executor****optimizer****parser****postgres****bigquery**等)、关联 PR 编号与贡献者,部分条目还通过fixes issue #xxxx/addresses issue #xxxx标注其解决的 GitHub Issue。对想要深入追踪某次具体变更的用户而言,这是一种可回溯、可验证的记录方式。


二、版本节奏与最近版本:v30.18.0 带来了什么

CHANGELOG 的开头即最新版本## [v30.18.0] - 2026-09-03。以该版本为例,可以完整看到一份"标准版本章节"的结构:

2.1 破坏性变更(BREAKING CHANGES)

v30.18.0 的破坏性变更全部集中在PostgreSQL 相关类型标注(annotate)与若干解析/生成行为调整上:

  • Postgres 函数类型标注:为decodeLeftReverseOverlayRightRpadSplitPartTo_HexFormatNormalizeToNumbermaketimeregexpreplacemake_timestampbit_orbit_xorlocaltimestamp等一系列 Postgres 函数补齐了返回类型标注。这些标注的实现可以在 sqlglot/typing/postgres.py 中找到对应代码。
  • JSONB_CONTAINS映射为@>运算符:修复了 Postgres 方言下 JSONB 包含关系的表达方式,并新增JSONBContainsTopKey表达式。
  • BTRIM解析为TRIM:Postgres 方言中的BTRIM不再作为独立函数保留,而是统一解析为标准TRIM表达式。
  • 标识符规范化调整:不再规范化"命名数据而非引用"的标识符,避免在优化过程中误改数据内容。
  • ANALYZE/DROP支持多表:解析器允许一条语句中列出多张表。
  • MOD改为乘除级优先级解析MOD运算符的解析优先级被调整到乘除(multiplicative)层级,并同步修正了生成时的括号处理。

2.2 新功能(New Features)

  • executor 模块持续扩充:实现了DPIPE管道操作符(sqlglot/executor/python.py 为核心执行实现)、REVERSE函数加入 ENV、支持OFFSET子句、支持执行优化器拒绝重写的子查询。executor 相关代码位于 sqlglot/executor/(含context.pyenv.pypython.pytable.py)。
  • 方言能力扩展:Dremio 支持 4 参数REGEXP_SPLIT;ClickHouse 将trimLeft/trimRight/trimBoth解析进Trim表达式、支持view()表函数;BigQuery 支持数字前缀字段名;Postgres 支持LOCK语句;Teradata 支持mod()函数语法。
  • explode(map)支持:表值函数explode现在可以作用于 map 类型。

2.3 缺陷修复(Bug Fixes)

v30.18.0 的修复覆盖多个方言,例如:

  • Trino:带时区的TIME字面量解析。
  • DuckDBJSON_VALUE箭头提取在父表达式需要时正确加括号。
  • SQLiteRegexpLike渲染为REGEXP运算符;CONCAT生成||时保留COALESCE包裹;窗口帧RANGE CURRENT ROW的显式结束边界。
  • MySQL%x%r日期格式说明符的映射;CREATE TABLE列定义支持KEY
  • Snowflakefilter_sql匿名函数处理、位置列引用解析、OBJECT_CONSTRUCT_KEEP_NULL中的限定通配符。
  • ClickHouse:VALUES 元组包裹幂等性、保留带引号的参数化关系、生成原生lag/lead替代lagInFrame/leadInFrame
  • optimizer:不将 WHERE 谓词下推入后续被 RIGHT/FULL JOIN 空值扩展的源;不剪除 GROUP BY/HAVING/QUALIFY 引用的列;_traverse_union中抛OptimizeError而非破坏作用域图(sqlglot/optimizer/scope.py)。
  • parserGRANT/REVOKE无权限列表时不再抛ValueError

这类细节正是 CHANGELOG 的价值所在:升级 SQLGlot 前,扫描目标版本与当前版本之间的 Bug Fixes 列表,即可预判哪些 SQL 行为可能发生变化。


三、v30.0.0 迁移指南详解:性能优先的大版本重构

在整个 CHANGELOG 中,## [v30.0.0] - 2026-03-16(第 1902 行起)是一个特殊的版本章节——它不仅罗列变更,还附带了完整的Migration Guide(迁移指南)。该版本的核心目标是性能与编译:库的多个核心组件开始支持由 mypyc 编译,安装[c]extra 后可获得显著加速,但这要求重构若干内部模块,从而对依赖内部 API、子类化 Parser 或从内部路径导入的用户引入了破坏性变更。

官方同时给出了清晰的适用范围说明:如果只使用公共 APIsqlglot.parsesqlglot.parse_onesqlglot.transpilesqlglot.exp.*sqlglot.optimizer.*),绝大多数代码无需改动即可升级。

3.1 Rust tokenizer 移除:用[c]替代[rs]

v30 之前项目曾提供 Rust 编写的 tokenizer(sqlglotrs),v29 起被移除,替换为 mypyc 编译的 C 扩展(sqlglotc):

# 之前 pip install "sqlglot[rs]" # 之后 pip install "sqlglot[c]"

其中[rs]extra 仍然可以安装,但已退化为废弃的 no-op 桩。被移除的 API 包括:

  • Tokenizer上的use_rs_tokenizer参数与属性
  • RsTokenizerRsTokenizerSettingsRsTokenTypeSettings导入
  • tokens.py中的USE_RS_TOKENIZER常量

这一点在当前仓库的 setup.py 中有直接印证:extras_require"rs"extra 被注释为 "Deprecated: the Rust tokenizer has been replaced by sqlglotc",其内容为["sqlglotrs==0.13.0", f"sqlglotc=={version}; python_version >= '3.10'"];而"c"extra 则为[f"sqlglotc=={version}; python_version >= '3.10'"]。注意:sqlglotc需要在用户机器上从源码编译,且要求 Python 3.10+;在 Python 3.9 上pip install sqlglot[c]是 no-op,只会得到纯 Python 版。独立的编译分发目录见 sqlglotc/(内含 pyproject.toml 与 setup.py)。

3.2expressions.py拆分为包

原来单文件的sqlglot/expressions.py被拆分为sqlglot/expressions/包,按职责划分出 15 个子模块。该拆分在当前仓库的 sqlglot/expressions/ 目录中即可直接验证:

模块内容
core.pyExprExpressionConditionFuncAggFuncColumnLiteral
datatypes.pyDataTypeDTypeDataTypeParamInterval
query.pySelectQuerySetOperationUDTFSubquery
ddl.pyCreateAlterDrop等 DDL 语句
dml.pyInsertUpdateDeleteMerge
properties.py所有*Property类、PropertiesLocation
constraints.py所有*ColumnConstraint
math.py算术运算符(AddSubMulDiv等)
string.py字符串函数(ConcatLengthUpper等)
temporal.py日期/时间函数(DateAddDateDiff等)
aggregate.py聚合函数(CountSumAvg等)
array.py数组函数(ArrayAggExplode等)
json.pyJSON 函数(JSONExtract等)
functions.py其他函数(CoalesceIfCaseCast等)
builders.pyBuilder 辅助函数(select()from_()condition()等)

向后兼容性from sqlglot.expressions import *from sqlglot import expressions as exp仍然可用,因为所有符号都从expressions/__init__.py重新导出。但如果你依赖sqlglot.expressions是单文件这一事实(例如检查__file__属性),该行为会被打破。

3.3Parser.expression()不再接受**kwargs

该变更影响所有子类化Parser或在自定义 parse 方法中调用self.expression()的代码。调用方式从"传 kwargs"改为"直接构造表达式实例":

# 之前 self.expression(exp.Select, distinct=True, expressions=cols) # 之后 self.expression(exp.Select(distinct=True, expressions=cols))

变更动机是消除**kwargs字典分配的开销——这与 v30 整体的性能优化目标一致。解析器的基类定义位于 sqlglot/parser.py,各方言解析器位于 sqlglot/parsers/。

3.4 作用域遍历:bfs参数移除

Scope相关遍历函数的bfs参数被删除,遍历方式固定为深度优先(DFS):

# 之前 scope.walk(bfs=True) scope.find(exp.Column, bfs=False) walk_in_scope(expr, bfs=True) # 之后 scope.walk() scope.find(exp.Column) walk_in_scope(expr)

行为变化:旧版本默认是bfs=True,现在统一为 DFS,因此依赖 BFS 顺序的代码会得到不同顺序的结果。受影响函数包括:Scope.walk()Scope.find()Scope.find_all()walk_in_scope()find_in_scope()find_all_in_scope()。作用域分析的核心实现在 sqlglot/optimizer/scope.py。

3.5 Dialect 元类不再修改 Parser token 集合

旧版_Dialect元类会在类创建时根据方言标志(如SUPPORTS_SEMI_ANTI_JOIN)动态修改解析器的 token 集合(ID_VAR_TOKENSTABLE_ALIAS_TOKENSNO_PAREN_FUNCTIONS)。这些动态修改已被移除,每个 parser 现在静态声明自己的 token 集合。具体变化:

  • Dialect.SUPPORTS_SEMI_ANTI_JOIN已删除。
  • SHOW_TRIE/SET_TRIE不再由SHOW_PARSERS/SET_PARSERS自动计算。

方言与解析器的基类分别在 sqlglot/dialects/dialect.py 与 sqlglot/parsers/base.py。

3.6 用Expr替代Expression做通用isinstance检查

FuncConditionBinary等 trait 基类现在直接继承自Expr而非Expression,因此isinstance(node, exp.Expression)不再能匹配这些 trait 类。若代码需要判断"是否为任意 AST 节点",应改用exp.Expr

# 之前 isinstance(node, exp.Expression) # 之后 isinstance(node, exp.Expr)

3.7 编译类无法被子类化(使用[c]时)

安装sqlglot[c]后,大量核心类经由 mypyc 编译。编译后的类不能在运行时被继承——类定义本身不会报错,但实例化时会抛出TypeError: interpreted classes cannot inherit from compiled。官方给出的受影响清单如下:

被编译(不可子类化):

是否可子类化
所有 parser(BigQueryParserSnowflakeParser等)
Parser(基类)
ExpressionExpr及所有 AST 节点(SelectColumnFunc等)
MappingSchemaAbstractMappingSchema
Scope
优化器规则(scope.pyqualify.pyqualify_columns.py等)

未被编译(仍可子类化):

是否可子类化
Generator及所有方言生成器
Tokenizer及所有方言 tokenizer
Dialect及所有方言类

选择建议:如果需要子类化 parser、表达式或 schema 等编译类,请安装纯 Python 版;如果需要更高执行性能且不涉及子类化,则安装编译版:

pip install sqlglot # 纯 Python —— 完整子类化支持 pip install "sqlglot[c]" # 编译版 —— 更快,但不可子类化

四、从 CHANGELOG 反推项目架构演进

CHANGELOG 不仅是版本记录,也是理解项目架构演进的线索。结合仓库目录结构,可以交叉验证几个重要结论:

  1. 表达式体系包化:v30.0.0 描述的expressions拆分已完整落地于 sqlglot/expressions/,且从aggregate.pyarray.pyjson.pytemporal.py等子模块可以看出,表达式按函数族(聚合、数组、JSON、时间)做了职责分离。

  2. 类型标注成为一等公民:v30 多个版本中反复出现的 "annotate xxx for postgres / mysql / spark" 变更,对应仓库中独立的 sqlglot/typing/ 目录,其中按方言组织了 13 个类型标注模块(postgres.pymysql.pyspark.pybigquery.pysnowflake.py等)。这解释了为何 CHANGELOG 中 annotate 类 PR 如此密集——类型推断能力是 SQLGlot 优化与执行链路的基础。

  3. executor 模块快速成长:v30.18.0 中**executor**前缀的变更(DPIPE、OFFSET、REVERSE、子查询求值、NULL 语义修正)表明 SQLGlot 正在把"解析-优化"链路延伸到"执行"能力,对应 sqlglot/executor/ 的实现。

  4. 方言覆盖广度:CHANGELOG 中出现的方言模块(trino、duckdb、mysql、clickhouse、bigquery、snowflake、sqlite、postgres、dremio、teradata、starrocks 等)与 sqlglot/dialects/、sqlglot/parsers/、sqlglot/generators/ 三组目录一一对应,每个方言都是"解析器 + 生成器 + 方言定义"三位一体的结构。

  5. 优化器规则演进:CHANGELOG 中大量涉及谓词下推、投影剪除、join 优化、作用域修正的变更,都能在 sqlglot/optimizer/ 中找到对应的规则模块(如pushdown_predicates.pypushdown_projections.pyoptimize_joins.pyqualify.pyeliminate_subqueries.py)。


五、如何在实际工作中用好这份 CHANGELOG

5.1 定位行为变化

升级 SQLGlot 前,重点查看从当前版本到目标版本之间所有### :boom: BREAKING CHANGES章节。从 155 次的出现频率看,任何跨 minor/major 的升级都应检查该列表。同时注意标注了fixes issue #xxxx的条目——这些通常是真实用户报告并修复的边界情况,可能与你的 SQL 场景直接相关。

5.2 按模块筛选关注点

每个条目都带模块前缀,例如**optimizer****executor****postgres****bigquery**。如果你只关心某个方言或某个子系统的行为,可以按前缀聚焦阅读,再结合对应源码目录(如 sqlglot/dialects/postgres.py、sqlglot/optimizer/)验证具体实现。

5.3 验证安装方式与版本前提

阅读 CHANGELOG 中涉及安装方式的内容时,应以当前仓库的 setup.py 为准:devextra 包含 duckdb、pandas、pdoc、pre-commit、ruff 等开发依赖;cextra 安装sqlglotc(需 Python 3.10+);rsextra 已废弃。版本号由 setuptools_scm 从 git 标签生成(version = get_version(local_scheme="no-local-version")),与 CHANGELOG 的版本章节一一对应。

5.4 追踪测试佐证

CHANGELOG 记录的方言级行为变化,大多能在 tests/dialects/ 下的方言测试(如 test_postgres.py、test_clickhouse.py)以及 tests/ 的优化器/执行器测试中找到对应用例。需要深入验证某次修复时,可以沿"CHANGELOG 条目 → 方言测试 → 解析器/生成器实现"的路径层层下钻。


结语

CHANGELOG.md之于 SQLGlot,既是发布日志,也是架构演进史与技术决策文档。它以 281 个版本、155 次破坏性变更和数百次方言级修复,完整记录了项目从纯解析/转译走向"解析 + 优化 + 类型推断 + 执行"一体化平台的过程。其中 v30.0.0 的迁移指南尤其值得细读——它揭示了当前版本在性能(mypyc 编译)与灵活性(子类化能力)之间的明确取舍,也为所有基于 SQLGlot 二次开发的用户提供了升级路径的行动清单。

  • 后端
  • 数据库

【免费下载链接】sqlglot

Python SQL Parser and Transpiler

项目地址:https://gitcode.com/gh_mirrors/sq/sqlglot
点击查看免费下载
上一篇:Rust模板引擎对比:为什么Handlebars-rust是你的最佳选择?
下一篇:开源项目安装与配置指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 17:53:39

4G/5G弱网环境怎么模拟?网络损伤仪选型与应用测试方案

做4G/5G应用弱网测试,网络损伤仪要能复现的不只是“网速慢”,还包括上下行不对称、拥塞排队,以及覆盖变化后的降速与恢复。需要把这些条件编成可重复场景时,网准通 NetAccura 混沌之桥 ChaosBridge 的 DPDK 方案值得优先考虑&…

作者头像 李华
网站建设 2026/9/24 17:52:49

第 09 篇:重排——Rerank 与 RRF

第 09 篇:重排——Rerank 与 RRF第 08 篇结尾把一件事按下了:“名单怎么从候选变成上下文,是拿到名单以后的事。” 这一篇就把它打开。夹在检索与生成之间的那一步叫重排, 它回答的是同一个问题的两半:几十条候选里&am…

作者头像 李华
网站建设 2026/9/24 17:52:40

基于 Java Spring Boot 的幼儿早教微信小程序设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 引言 随着移动互联网的普及和微信生态的快速发展,微信小程序凭借其即用即走、无需下载安装、传播便捷等优势,已成为教育服务领域的重要载体。…

作者头像 李华
网站建设 2026/9/24 17:52:00

2026短视频配音工具怎么选?实用功能才是关键

打开应用商店搜"配音",跳出来的工具没有一百也有八十。榜单天天变,"第一名"月月换,但说实话,选配音工具跟选手机一个道理——参数表再漂亮,不如看实用功能对不对得上你的活儿。2026年的AI配音早已…

作者头像 李华
网站建设 2026/9/24 17:51:58

云原生Serverless架构挑战及解决方案

云原生 Serverless,核心是事件驱动、按需弹性、按调用计费、平台托管底层资源,开发者只写业务代码,不用管理服务器 / 容器节点。主流形态:FaaS函数即服务,AWS Lambda、阿里云函数计算、腾讯云 SCF,也包含 B…

作者头像 李华
网站建设 2026/9/24 17:51:09

秋分时节, 与团队文化的平衡之道

快乐能量体验式培训公司 新媒体专栏 秋分时节,与团队文化的平衡之道 把效率与人性,放进同一架天平 传播快乐 拓展潜能 有活力,更能有成绩秋分时节与团队文化的平衡之道 秋分,把一年的光阴,轻轻地分成了两半。…

作者头像 李华