上一篇博文我们阅读了postgresql中查询分析模块的源码。查询分析模块对前台送来的命令进行词法分析、语法分析和语义分析后获得对应的查询树(Query)。在获得查询树之后,程序开始对查询树进行查询重写处理。

这一篇文章我们进入查询重写模块源码的阅读。还记得上一篇文章的那张函数调用关系图么?不记得没关系,我再放一遍。

上次的查询分析模块走了1~7这些步骤。而查询重写模块即如上图的标记所示,函数pg_rewrite_query是进行查询重写处理的入口函数。该函数定义在src/backend/tcop/postgres.c中。

函数pg_rewrite_query的参数就是查询分析模块的返回值(Query)。查询重写模块使用规则系统判断是否要对查询树进行重写。如果查询树中每个对象(或者说目标)被定义了转换规则,那么程序就会使用该规则重写查询树。这部分的源码大部分都在src/backend/rewrite文件夹下。

下面将首先介绍查询重写模块中使用的规则系统,在此基础上介绍查询重写源码的调用路径。


1.规则系统

毫不夸张地说,规则系统是查询重写模块的核心内容,该模块正是根据规则系统中描述的规则来决定如何对一个查询树进行重写。规则系统由一些列的规则组成。这些规则都存储在系统表pg_rewrite中。该表的结构如下图所示。每一条记录即为一条规则。

其中每个属性的意义如下:

属性名        类型            描述
oid         oid             行标识符(隐藏属性; 必须明确选择)
rulename    name            规则名称
ev_class    oid             使用这条规则的表名称
ev_type     char            规则适用的事件类型:1 = SELECT, 2 = UPDATE, 3 = INSERT, 4 = DELETE ev_enabled char 控制规则在哪个session_replication_role模块触发。 O = 规则在 "origin""local" 模块触发, D = 规则被禁用, R = 规则在 "replica" 模块触发, A = 规则总是触发。
is_instead  bool            如果该规则是INSTEAD规则,那么为真
ev_qual     pg_node_tree    规则的资格条件的表达式树(以nodeToString()形式存在)
ev_action   pg_node_tree    规则动作的查询树(以nodeToString()形式存在)

由此我