Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

52.3. 解析器阶段 #

52.3.1. 解析器
52.3.2. 转换过程

解析器阶段由两部分组成

52.3.1. 解析器 #

解析器必须检查查询字符串(以纯文本形式到达)的语法是否有效。如果语法正确,则构建一个 解析树 并将其返回;否则,返回一个错误。解析器和词法分析器使用众所周知的 Unix 工具 bisonflex 实现。

词法分析器在文件 scan.l 中定义,负责识别 标识符SQL 关键字 等。对于找到的每个关键字或标识符,都会生成一个 标记 并将其传递给解析器。

解析器在文件 gram.y 中定义,包含一组 语法规则动作,每当触发一个规则时就会执行这些动作。动作的代码(实际上是 C 代码)用于构建解析树。

文件 scan.l 使用程序 flex 转换为 C 源文件 scan.cgram.y 使用 bison 转换为 gram.c。在这些转换完成后,可以使用一个普通的 C 编译器来创建解析器。切勿对生成的 C 文件进行任何更改,因为下次调用 flexbison 时它们将被覆盖。

注意

提到的转换和编译通常使用 PostgreSQL 源代码分发中附带的 makefile 自动完成。

bisongram.y 中给出的语法规则的详细描述超出了本手册的范围。有许多关于 flexbison 的书籍和文档。在开始学习 gram.y 中给出的语法之前,你应该熟悉 bison,否则你将无法理解那里发生的情况。

52.3.2. 转换过程 #

解析器阶段仅使用有关 SQL 语法结构的固定规则创建解析树。它不会在系统目录中进行任何查找,因此无法理解所请求操作的详细语义。在解析器完成之后,转换过程 将解析器返回的树作为输入,并执行语义解释以理解查询引用的哪些表、函数和运算符。用于表示此信息的数据结构称为 查询树

将原始解析与语义分析分开的目的是,系统目录查找只能在事务中完成,而我们不希望在收到查询字符串时立即启动事务。原始解析阶段足以识别事务控制命令(BEGINROLLBACK 等),然后可以正确执行这些命令,而无需任何进一步的分析。一旦我们知道正在处理实际查询(例如 SELECTUPDATE),如果我们尚未处于事务中,则可以启动事务。只有这样才能调用转换过程。

转换过程创建的查询树在大多数地方的结构与原始解析树类似,但它在细节上有很多不同。例如,解析树中的 FuncCall 节点表示语法上类似于函数调用的内容。这可能会根据引用的名称是普通函数还是聚合函数而转换为 FuncExprAggref 节点。此外,有关列和表达式结果的实际数据类型的信息将添加到查询树中。