@clickhouse/lexer

中文文档
1.0.1发布于 2026/09/23Apache-2.0TypeScriptES Module零依赖近 30 天下载 2141

ClickHouse's SQL lexer 已编译为 Web Assembly —— 精确的标识器 ClickHouse 本身在~9 KB中使用, 没有依赖性

中文使用文档
文档目录7 节
  1. 安装
  2. 使用量
  3. API 密码
  4. 使用原始的 WASM( 非 JavaScript 主机)
  5. 此寄存器是如何同步的
  6. 手动重建
  7. 许可证

点击之家 SQL 莱克瑟

NPM version

这个 点击之家的实际 SQL 借记器 (单位:千美元)src/Parsers/Lexer.cpp)被编译为WebAssembly:~9 KB,没有依赖性,在浏览器和Node.js中工作. 因为它是服务器使用的确切代码,它给 ClickHouse SQL 的每一个角落都以正确的标记——巢接 /* */ 评论, $heredoc$ 字符串,回击和双引号标识符, 0x编号 :0b 字迹, \G, (中文(简体) ), |>,然后随你.

此模块与在 点击之家网络用户界面 (单位:千美元)play.html)和 ClickHouse 文件。 一个 GitHub 动作从 ClickHouse 同步此寄存器 master 每日出版发行,只要lexer更改.

安装

npm install @clickhouse/lexer

使用量

import {tokenize, TokenType, TOKEN_NAMES, isSignificant, isError} from "@clickhouse/lexer"

const tokens = await tokenize("SELECT count() FROM `events` WHERE user != 'guest' -- filter")

for (const token of tokens)
    console.log(TOKEN_NAMES[token.type], JSON.stringify(token.text))
// BareWord "SELECT"
// Whitespace " "
// BareWord "count"
// OpeningRoundBracket "("
// ...
// StringLiteral "'guest'"
// Whitespace " "
// Comment "-- filter"

// Only keywords/identifiers/literals/operators, no whitespace and comments:
tokens.filter(t => isSignificant(t.type))

// The lexer stops at unlexable input and reports what went wrong:
const bad = await tokenize("SELECT 'unterminated")
isError(bad.at(-1).type) // true
TOKEN_NAMES[bad.at(-1).type] // "ErrorSingleQuoteIsNotClosed"

每个符号是 {type, text, begin, end}. 将输入从头到尾的相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相接相相接相接相接相接相相相相接相相接相相接相接相相相相接相接相接相相接相相相接相相相相接相相相接相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相. begin编号 :end a. 输入查询的UTF-8编码的字节; text 是已解码的符号.

在浏览器中,它的工作原理是相同的——WASM被嵌入为base64,因此没有任何可配置在任何捆绑器中:

<script type="module">
import {tokenize} from "https://esm.sh/@clickhouse/lexer"
console.log(await tokenize("SELECT 1"))
</script>

对于热路, 装入一次并同时表示:

import {loadLexer, tokenizeSync} from "@clickhouse/lexer"

await loadLexer()
const tokens = tokenizeSync(query) // no await, e.g. inside an editor's render path

API 密码

导出说明
tokenize(query, options?)Promise<Token[]>; 将 lexer 装入第一次使用时.
loadLexer()证明WASM模块(专有).
tokenizeSync(query, options?)之后同步符号化 loadLexer()。 。 。 .
lexerIsLoaded()是否为 tokenizeSync 可以调用.
TokenType名称 ~ 数字类型 (TokenType.StringLiteral(......) (中文(简体) ).
TOKEN_NAMES数字类型 名称.
isSignificant(type)不是白空间,也不是评论.
isError(type)一个 Error* 类型.
options.maxQuerySize词典的字节限制; 0 (默认) = 无限.

重要内容: 符号类型值是位置值 TokenType 插入 src/Parsers/Lexer.h,并插入一个符号类型,重新编号之后的一切(这种情况已经发生)。 总是比较 TokenType.* 从此包中,从不与硬码数字相对抗,也从不将一个版本的符号表与另一个版本的WASM相混合. 相同的 ClickHouse 修订版(收录于 upstream/COMMIT) (中文(简体) ).

使用原始的 WASM( 非 JavaScript 主机)

软件包还将平面二进制作为 @clickhouse/lexer/lexer.wasm 用于任何WASM运行时间. 上诉委员会(见 upstream/clickhouse_lexer.h:

extern size_t clickhouse_lexer_size; // size of the lexer state object
void clickhouse_lexer_create(void * ptr, const char * begin, const char * end, size_t max_query_size);
unsigned char clickhouse_lexer_next_token(void * ptr, const char ** out_token_begin, const char ** out_token_end);
int clickhouse_lexer_token_is_significant(unsigned char token);
int clickhouse_lexer_token_is_error(unsigned char token);
int clickhouse_lexer_token_is_end(unsigned char token);

将您的缓冲器( 语法状态、 查询字节和两个出点) 放在 __heap_base 或以上——模块的"阴影堆栈"占据了下方的内存并向下生长,因此更低的缓冲被大查询所腐蚀. 打电话 clickhouse_lexer_next_token 循环到 is_end 或者说 is_error。 。 。 . index.js 在此一揽子方案中是完整的参考执行.

此寄存器是如何同步的

Lexer 源头住在这里 upstream/,从 src/Parsers 联 合 国 点击之家/ 点击之家 (单位:千美元)Lexer.cpp, (中文(简体) ), Lexer.h, (中文(简体) ), LexerStandalone.h, (中文(简体) ), clickhouse_lexer.h(三); upstream/COMMIT 记录主人承诺 他们来自.

这个 同步工作流程 每日运行 :

  1. scripts/sync.sh ——从 ClickHouse 主机获取最新来源; 如果无变化则停止 .
  2. scripts/build.sh ——编译 lexer.wasm 有条纹( c) (--target=wasm32 -nostdlib,与 lexer_wasm 主寄存器中的CMake目标).
  3. scripts/generate.js ——再生 lexer-wasm-base64.js 财务报告和审定财务报表 tokens.js (符号表从 Lexer.h,保持编号与二进制相锁.
  4. 运行测试, 承诺, 撞击补丁版本, 创建 GitHub 发布, 并发布到 npm .

手动重建

所需经费: clang, (中文(简体) ), lld (计: wasm-ld和节点js 18.

npm run sync   # pull the latest lexer sources from ClickHouse master into upstream/
npm run build  # compile lexer.wasm and regenerate the derived JS modules
npm test

同样,从主 ClickHouse 寄存器的检出结果来看,独立的Lexer 构建是:

clang++ -Os -fno-exceptions -fno-rtti -DLEXER_STANDALONE_BUILD --target=wasm32 -flto -nostdlib \
    -I src -Wl,--no-entry -Wl,--export-all \
    src/Parsers/Lexer.cpp -o Lexer.wasm

这是什么 lexer_wasm CMake 目标生成于 build/src/Parsers/Lexer.wasm 配置时 -DENABLE_LEXER_TEST=1。 。 。 .

许可证

Apache 许可证 2.0,与ClickHouse一样。 这个 upstream/ 来源是来自ClickHouse仓库的逐字记录本,仍为“ClickHouse股份有限公司”.

版本与发布记录

@clickhouse/lexer 共发布 1 个版本,首次发布于 2026/09/23;过去 12 个月发布了 1 个版本。

版本发布日期距今
1.0.1latest2026/09/231 个月前

关于 @clickhouse/lexer 的常见问题

@clickhouse/lexer 是什么?

ClickHouse's SQL lexer 已编译为 Web Assembly —— 精确的标识器 ClickHouse 本身在~9 KB中使用, 没有依赖性

如何安装 @clickhouse/lexer?

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

@clickhouse/lexer 支持 TypeScript 吗?

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

@clickhouse/lexer 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@clickhouse/lexer 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@clickhouse/lexer 可以商用吗?

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

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

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

@clickhouse/lexer 还在维护吗?

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