PostgreSQL令牌机制解析
PostgreSQL 中的 令牌机制(Tokenization) 是 SQL 查询处理的第一步,属于**词法分析(Lexical Analysis)**阶段。它的核心任务是将输入的 SQL 字符串分解为有意义的语法单元(Tokens),为后续的语法解析(Parsing)做准备。以下是其工作机制详解:
一、什么是 Token(令牌)?
Token 是 SQL 中最小的有语义单位,例如:
输入字符串 | 分解后的 Tokens |
---|---|
SELECT id FROM users; | SELECT (关键词), id (标识符), FROM (关键词), users (标识符), ; (分隔符) |
WHERE price > 100.5 | WHERE (关键词), price (标识符), > (操作符), 100.5 (数字常量) |
二、PostgreSQL 的词法分析器(Lexer)
PostgreSQL 使用 Flex(词法分析器生成器) 实现词法扫描,核心代码在 src/backend/parser/scan.l
。
工作流程:
- 读取输入字符串:逐字符扫描 SQL 文本。
- 匹配正则规则:根据预定义规则(如关键词、标识符、数字等模式)切分 Token。
- 生成 Token 序列:输出
Token + 值 + 位置信息
给语法分析器(Bison)。
三、Token 的分类
PostgreSQL 的 Token 主要分为以下几类:
类型 | 示例 | 说明 |
---|---|---|
关键词 (KEYWORD) | SELECT , INSERT , WHERE | SQL 保留字,有固定语义 |
标识符 (IDENTIFIER) | 表名、列名(如 users , id ) | 用户自定义的名称,需大小写处理(默认转小写) |
常量 (CONSTANT) | 100 , 'text' , 3.14 , TRUE | 数字、字符串、布尔值等字面量 |
操作符 (OPERATOR) | + , > , = , ~~ (LIKE ) | 数学、比较、逻辑运算符 |
分隔符 (DELIMITER) | , , ; , ( , ) | 分隔语句或子句的符号 |
注释 (COMMENT) | -- comment , /* comment */ | 执行时被忽略 |
四、关键处理逻辑
-
大小写折叠 (Case Folding)
- 关键词和标识符默认转为小写(除非用双引号包裹
"MyTable"
)。 - 例如:
SELECT
→select
(内部处理),"SELECT"
→ 保留大写(作为标识符)。
- 关键词和标识符默认转为小写(除非用双引号包裹
-
字符串与转义
- 单引号字符串
'value'
支持转义:E'\\n'
→ 换行符。 - 美元引号(Dollar Quoting)避免转义混乱:
$$This is a 'string' without escaping$$
- 单引号字符串
-
注释处理
- 单行注释 (
-- ...
) 和多行注释 (/* ... */
) 在词法阶段被直接丢弃,不进入语法树。
- 单行注释 (
-
操作符歧义消除
- 字符组合需区分含义(如
--
可能是注释或减法运算符),依赖上下文规则解决。
- 字符组合需区分含义(如
五、示例:Token 生成过程
输入 SQL:
SELECT name FROM "Users" WHERE id = 100 + 1; -- 查询用户
Token 序列:
Token 值 | 类型 | 说明 |
---|---|---|
SELECT | KEYWORD | 关键词 |
name | IDENTIFIER | 标识符(转为小写) |
FROM | KEYWORD | 关键词 |
"Users" | IDENTIFIER | 带引号标识符(保留大小写) |
WHERE | KEYWORD | 关键词 |
id | IDENTIFIER | 标识符 |
= | OPERATOR | 比较操作符 |
100 | CONSTANT | 整数常量 |
+ | OPERATOR | 加法操作符 |
1 | CONSTANT | 整数常量 |
; | DELIMITER | 语句结束符 |
-- 查询用户 | COMMENT | 丢弃 |
六、与后续流程的衔接
生成的 Token 序列会交给 语法分析器(Parser,基于 Bison 实现):
- 语法器根据
gram.y
中的规则构建抽象语法树(AST)。 - 例如:
SELECT ... WHERE ...
→ 生成SelectStmt
语法树节点。
七、高级特性:自定义操作符
PostgreSQL 允许用户自定义操作符(如 !!
),词法器通过 OPERATOR
规则自动识别:
CREATE OPERATOR !! ( ... ); -- 定义后,词法分析器会将 "!!" 识别为操作符 Token
总结
PostgreSQL 的令牌机制是 SQL 执行的基石:
输入字符串 → 词法分析(Tokenization)→ 语法分析(Parsing)→ 语义分析 → 查询优化
理解 Token 的生成逻辑,有助于调试复杂 SQL 或开发数据库扩展(如自定义语法)。