@clickhouse/parser

中文文档
0.3.0发布于 2026/07/10Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 11.3万

用于 ClickHouse SQL 的脚本解析器

中文使用文档
文档目录12 节
  1. 安装
  2. 使用量
  3. 分析 SQL 到 AST
  4. 将 AST 格式化为 SQL
  5. EXPLAIN 输出
  6. 处理错误
  7. 支持的 SQL
  8. 限制
  9. 与 ClickHouse 参考 AST 的区别
  10. 发展
  11. 检查输出
  12. 根据预期产出进行疏导

@ 点击之家/ parser

用于 ClickHouse SQL 的 TypeScript 解析器。 将 ClickHouse SQL 转换为已键入的 AST,支持格式化回SQL.

探索解析器输出 游乐场。 。 。 .

说明: 这是α级克洛德软件。 API和AST格式可能会被改变.

安装

npm install @clickhouse/parser

使用量

分析 SQL 到 AST

import { parse } from '@clickhouse/parser';

const ast = parse('SELECT id, name FROM users WHERE active = 1 ORDER BY name');

parse() 接受包含一个或多个 ClickHouse SQL 语句的字符串,并返回 a Statement[] 阵列.

以上查询的 AST:

[
  {
    "type": "SelectWithUnionQuery",
    "selects": [
      {
        "type": "SelectQuery",
        "select": [
          { "type": "Identifier", "name": "id" },
          { "type": "Identifier", "name": "name" }
        ],
        "from": {
          "type": "TablesInSelectQuery",
          "children": [
            {
              "type": "TablesInSelectQueryElement",
              "table_expression": {
                "type": "TableExpression",
                "database_and_table_name": {
                  "type": "TableIdentifier",
                  "name": "users"
                }
              }
            }
          ]
        },
        "where": {
          "type": "Function",
          "name": "equals",
          "arguments": [
            { "type": "Identifier", "name": "active" },
            { "type": "Literal", "value_type": "UInt64", "value": "1" }
          ],
          "is_operator": true
        },
        "order_by": [
          {
            "type": "OrderByElement",
            "expression": { "type": "Identifier", "name": "name" },
            "direction": "ASC"
          }
        ]
      }
    ]
  }
]

每个节点都有 type 反映 ClickHouse 本地 AST 的歧视性领域. 见 资产 所有节点类型和他们的Zod计划.

分析选项

parse() 接受可选第二个参数:

parse(sql, {
  // Attach a `location` (line/column/offset source range) to every node.
  // Set to false for a leaner, fully JSON-serializable AST. Default: true.
  locations: true,

  // Set a `parent` reference on every node. This introduces circular
  // references, which break `JSON.stringify`. Default: false.
  setParents: false,
});

启用位置( 默认) 每个 AST节点带一个 location这样 这是一个 所需经费 财产——无 | undefined,没有 !数字 :

const ast = parse(sql); // Statement[]
ast[0].location.start.offset; // ✓ SourceLocation (always present)

何时 locations: false 以文为传, parse() 返回时 WithoutLocations<Statement>[] - 一个类型与 location 递归去除,所以 读取 .location 是编译时间错误 :

const ast = parse(sql, { locations: false });
ast[0].location; // ✗ type error: property does not exist

AST消耗性职能—— format, (中文(简体) ), formatExplain, (中文(简体) ), formatNode,以及 transformNodes 接受 WithoutLocations<…> 投入。 因为一个定位AST是 在无位置的对应方,他们透明地接受AST 有无所住地.

将 AST 格式化为 SQL

import { parse, format } from '@clickhouse/parser';

const ast = parse('SELECT id, name FROM users WHERE active = 1 ORDER BY name');
const sql = format(ast);

上述产出的格式:

SELECT
    id,
    name
FROM users
WHERE active = 1
ORDER BY name ASC;

format() 将 AST 转换为正常的,可读的 SQL 。 解析和格式化是圆通安全——解析格式化输出产生一个相同的AST.

EXPLAIN 输出

import { parse, formatExplain } from '@clickhouse/parser';

const ast = parse('SELECT a + b FROM t WHERE x = 1');
const explain = formatExplain(ast);

formatExplain() 生成匹配 ClickHouse 的树形代表 EXPLAIN AST 输出 :

SelectWithUnionQuery (children 1)
 ExpressionList (children 1)
  SelectQuery (children 3)
   ExpressionList (children 1)
    Function plus (children 1)
     ExpressionList (children 2)
      Identifier a
      Identifier b
   TablesInSelectQuery (children 1)
    TablesInSelectQueryElement (children 1)
     TableExpression (children 1)
      TableIdentifier t
   Function equals (children 1)
    ExpressionList (children 2)
     Identifier x
     Literal UInt64_1

处理错误

当分析失败时, parse() 丢出一个 ParseError 包含关于分析失败地点和原因的结构性信息.

import { parse, ParseError } from '@clickhouse/parser';

try {
  parse('SELECT ???');
} catch (e) {
  if (e instanceof ParseError) {
    e.message; // Human-readable error message
    e.location; // { start: { line, column, offset }, end: { line, column, offset } }
    e.expected; // What the parser expected (e.g. literals, token classes)
    e.found; // What was found instead (string | null)
  }
}

支持的 SQL

解析器目标为全覆盖 ClickHouse SQL 表面并经过验证 参考查询文件 官方 ClickHouse 仓库. 每个参考文献,AST,格式化SQL, 财务报告和审定财务报表 EXPLAIN AST 完全匹配 ClickHouse 自己的输出.

限制

  • 只点击之家 这不是一个一般的 SQL 解析器。 来自其他方言的语法,ClickHouse不支持的语法不会解析.
  • KQL 语言 ——Kusto查询语言语法不支持.
  • 插入的数值 未解析 - AST 不包括正插入表格的字面值.

与 ClickHouse 参考 AST 的区别

由此库解析的 AST 是由 ClickHouse 推出的 JSON AST 的超级集 这里其他财产说明如下.

位置元数据

每个节点都有一个 location: { start, end } 记录其来源 区域在原始 SQL,其中 start编号 :end 为: { offset, line, column } (与小猪相容) LocationRange) (中文(简体) ). 默认列入地点; 通过 { locations: false } 改为 parse() 省略(参见 分析选项) (中文(简体) ).

父元数据

可以选择,每个节点都可以用 parent 参考其所附节点。 通过 options: { setParents: true } 参数到 parse() 以启用此功能。 这样可以向上 倒倒出树来. 它创造了循环参考,所以在序列化或比较时将其排除在外 aST (英语).

注释数据

注释作为全部源文本的数组附于最近的节点 (包括 --, (中文(简体) ), #,或 /* */ 分隔符 :

  • leadingComments 在节点前出现的评论.
  • trailingComments ——在与节点末端相同的行上内置注释.

不参考的语义字段 AST

这些字段带有语义信息,引用 JSON AST 丢弃但 那个 format() 需要忠实地复制源.

  • nonfinite - 发现在 Literal 财务报告和审定财务报表 LiteralElement 节点,这是歧视者 页:1 Float64 当地人的价值 value 浮体不能在序列化的 JSON 中代表 . 非无限值inf, (中文(简体) ), -inf, (中文(简体) ), nan, (中文(简体) ), -nan每次崩溃到 null 可能会是 用这面旗帜恢复.
  • QueryParameter 节点 - 代表查询参数( n){name:type} 语法)在源, 参考文献 " ClickHouse JSON AST " 中未反映这些内容.

用于解释格式的非语义字段

这些字段没有语义意义,而且 仅限 读取方式 formatExplain()。 。 。 . 它们的存在是因为ClickHouse的 EXPLAIN AST 曝光内置的儿科医生订单 与结构化的JSON AST丢弃的重复. 就像语义场 因此,他们不在AST的参考文献中 formatExplainJson() 剥去它们.

  • with_trailing 标记 a WITH 选项 之后 页:1 选择机构而不是摆在其面前(a) WITH 在附件前写 INSERT,或传播到最左侧 UNION编号 :INTERSECT 成员。 这个 参考 AST 存储相同 with 字段在两个位置,所以旗帜是 唯一记录的跟踪位置.
  • agg_repeat - 标记合成者 SelectQuery 降低时生产 expr op ANY/ALL (subquery)。点击之家的文本堆放会发出此节点 预测和表格的两次SelectQuery (children 4)); 参考 AST 保存单个副本,与用户写的无法区分 (SELECT agg(*) FROM (sub))。 。 。 .
  • settings_before_format - 记录 SETTINGS 前一个 FORMAT 输入 来源. format() 允许 FORMAT ... SETTINGS ...; 旗帜允许 解释的投影复制了原始的孩子顺序.
  • settings_after_order_by - 记录一个存储器 SETTINGS 条款出现 在来源的最后一个条款之前. format() 把它变成 需要最后位置; 旗帜保存原始位置 Set 儿童秩序.
  • no_parens ——记录一个编解码器/引擎函数没有写入 括号(例如:. Delta 对 Delta()) (中文(简体) ). format() {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}把小说变成 空派形式;旗下再现了ClickHouse的字节精确AST.

过滤存储设置

当点击之家发出时 EXPLAIN AST json=1过滤 a CREATE TABLE编号 :CREATE DATABASE ... SETTINGS 条款下至仅设置 属于目标引擎自身的注册(版本-和) 引擎专用集). 写入到会话或查询级别设置 条款——例如:. log_queries, (中文(简体) ), allow_suspicious_low_cardinality_types,或 use_hive_partitioning 在一张桌子上,或 distributed_ddl_task_timeout 编号 数据库——从 Storage > Set changes 地图,如果没有 整个 Storage编号 :settings 节点被放弃 .

这个图书馆的确是 没有 复制引擎专用登记册:保存 每个 条款中的规定 format() 能够重置原始 SQL 忠诚地。 因此,AST图书馆可能额外携带 Storage 设置 引用 AST 省略.

发展

npm run build           # Regenerate parser from grammar + build dist/
npm test                # Run test suite

检查输出

parse, (中文(简体) ), format,以及 explain 打印此库的输出。 每人取一个生的 SQL 通过字符串 --sql,或来自 tests/clickhouse-reference/ 联合国 .sql 文件名 — 后缀是可选的 — 一个逗号分隔列表, 或 glob :

npm run parse   -- --sql "SELECT 1"   # AST as JSON
npm run format  -- --sql "SELECT 1"   # re-formatted SQL
npm run explain -- --sql "SELECT 1"   # EXPLAIN AST output

npm run format  -- 00001_select_1     # output for a reference case
npm run explain -- '00001_*'          # output for every matching case

根据预期产出进行疏导

diff:ast, (中文(简体) ), diff:format,以及 diff:explain 显示此库的输出, 即预期 投入的产出 tests/clickhouse-reference/,在它们之间有一个微分——用于 调试引用测试失败 。 它们采用相同的参考选择器(文件名, 逗号分隔列表, 或 glob :

npm run diff:format  -- 00001_select_1            # actual, expected, and diff
npm run diff:ast     -- '0001*' --diff-only       # just the diff
npm run diff:explain -- 00001_select_1,00002_count_visits --only-diffs

旗帜 : --diff-only, (中文(简体) ), --actual-only, (中文(简体) ), --expected-only, (中文(简体) ), --only-diffs, (中文(简体) ), --no-color。 。 。 . 过 -h 用于任何脚本.

解析器以 佩吉 (PEG语法),并生成经验证的 AST 佐德语Name 计划 所有AST型被导出用于下游工具.

版本与发布记录

@clickhouse/parser 共发布 3 个版本,首次发布于 2026/06/08;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/07/104 个月前
0.2.12026/06/095 个月前
0.1.02026/06/085 个月前

关于 @clickhouse/parser 的常见问题

@clickhouse/parser 是什么?

用于 ClickHouse SQL 的脚本解析器

如何安装 @clickhouse/parser?

在项目目录运行 npm install @clickhouse/parser,或使用 pnpm add / yarn add / bun add。

@clickhouse/parser 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@clickhouse/parser 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@clickhouse/parser 可以商用吗?

@clickhouse/parser 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@clickhouse/parser 的下载量有多少?

根据 npm 官方下载统计,@clickhouse/parser 在 2026/10/10 – 2026/11/08 这 30 天内被下载 113,235 次,日均约 3,775 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@clickhouse/parser 还在维护吗?

最新版本 0.3.0 发布于 2026/07/10(4 个月前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/06/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。