@ 点击之家/ 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节点,这是歧视者 页:1Float64当地人的价值value浮体不能在序列化的 JSON 中代表 . 非无限值inf, (中文(简体) ),-inf, (中文(简体) ),nan, (中文(简体) ),-nan每次崩溃到null可能会是 用这面旗帜恢复.QueryParameter节点 - 代表查询参数( n){name:type}语法)在源, 参考文献 " ClickHouse JSON AST " 中未反映这些内容.
用于解释格式的非语义字段
这些字段没有语义意义,而且 仅限 读取方式 formatExplain()。 。 。 .
它们的存在是因为ClickHouse的 EXPLAIN AST 曝光内置的儿科医生订单
与结构化的JSON AST丢弃的重复. 就像语义场
因此,他们不在AST的参考文献中 formatExplainJson() 剥去它们.
with_trailing标记 aWITH选项 之后 页: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 用于任何脚本.