2024年9月26日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

50.3. 解析阶段 #

解析阶段 包含两个部分

  • gram.yscan.l 中定义的 解析器 是使用 Unix 工具 bisonflex 构建的。

  • 转换过程 对解析器返回的数据结构进行修改和增强。

50.3.1. 解析器 #

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

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

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

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

注意

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

bisongram.y 中给出的语法规则的详细描述超出了本手册的范围。有很多书籍和文档涉及 flexbison。在开始研究 gram.y 中给出的语法之前,您应该熟悉 bison,否则您将无法理解那里发生了什么。

50.3.2. 转换过程 #

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

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

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

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。