`

PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分析重写成querytree

阅读更多

 

话说 查询“ select cname, comp from test1, test2 where test1.id=test2.id; 发送到服务器端, 走查询分支 exec_simple_query ,先调用 start_xact_command 初始化了事务管理相关对象和资源,接着调用 pg_parse_query ,通过 Lex Yacc 对传入 SQL 语句进行词法语法解析,生成解析树。下来调用 GetTransactionSnapshot 方法做内存快照,然后调用 pg_analyze_and_rewrite 方法,进行语义分析把 parsetree 转换成 querytree ,然后对该 querytree 进行重写。

 

1

下面是对 parseetree 进行语义分析和查询重写的调用序列图。



 

 

Postgres 服务进程简查之语义分析和查询重写调用序列图

 

       上图红色方框中显示了对 parsetree 进行语义分析和查询重写的方法调用过程,在 parse_analyze 方法中对 parsetree 进行语义分析,生成 querytree ,在 pg_rewrite_query 方法中对前面生成的 q uerytree 进一步进行修改,最后把 querytree 返回给 exec_simple_query 。在 parse_analyze 方法中根据这个例子中语句生成的 节点类型 T_SelectStmt transformSelectStmt 分支,分别调用 transformFromClause transformTargetList transformWhereClause 方法处理 from 、目标属性、 where 子句。处理完后把目标传到 pg_rewrite_query 方法,在 pg_rewrite_query 方法里利用规则 /rule querytree 中对应的目标进行重写,规则是查询重写处理的关键, pg 的规则中 pg_write 系统表中。规则和触发器相似,都可以在某种条件下激活,可执行原命令之外的动作,区别是触发器多涉及到每个元组都执行一次,而规则对整个查询树 querytree 进行修改或额外的查询。一个语句如果涉及多个元组,规则一般比触发器效率高,但触发器更容易理解。

       这部分内容涉及到结构和处理及代码量相当多,在这就不列举了,有兴趣的根据方法调用流程图看源码吧,下面给出处理完的结果 querytree 结构图。

 



 

 

例子里查询语句对应的 querytree 结构图

把这个例子再重复一下:

create table test1 (ID numeric(10), cname varchar(30));

create table test2 (ID numeric(10), comp varchar(30));

select cname,comp from test1,test2 where test1.id=test2.id;

上面的图《例子里查询语句对应的 querytree 结构图》就是 SQL 语句“ select cname,comp from test1,test2 where test1.id=test2.id ”在 pg 里产生的 querytree

 

pg 输出的 querytree 如下:

2011-11-23 06:57:39 HKT DETAIL:  (

          {QUERY

          :commandType 1

          :querySource 0

          :canSetTag true

          :utilityStmt <>

          :resultRelation 0

          :intoClause <>

          :hasAggs false

          :hasWindowFuncs false

          :hasSubLinks false

          :hasDistinctOn false

          :hasRecursive false

          :hasModifyingCTE false

          :hasForUpdate false

          :cteList <>

          :rtable (

             {RTE

             :alias <>

             :eref

                {ALIAS

                 :aliasname test1

                :colnames ("id" "cname")

                }

             :rtekind 0

             :relid 16394

             :relkind r

             :inh true

             :inFromCl true

             :requiredPerms 2

             :checkAsUser 0

             :selectedCols (b 9 10)

             :modifiedCols (b)

             }

             {RTE

             :alias <>

             :eref

                {ALIAS

                :aliasname test2

                :colnames ("id" "comp")

                }

             :rtekind 0

             :relid 16397

             :relkind r

             :inh true

             :inFromCl true

             :requiredPerms 2

             :checkAsUser 0

             :selectedCols (b 9 10)

             :modifiedCols (b)

             }

          )

          :jointree

             {FROMEXPR

             :fromlist (

                {RANGETBLREF

                :rtindex 1

                }

                {RANGETBLREF

                :rtindex 2

                }

             )

             :quals

                {OPEXPR

                :opno 1752

                :opfuncid 1718

                :opresulttype 16

                :opretset false

                :opcollid 0

                :inputcollid 0

                :args (

                    {VAR

                   :varno 1

                   :varattno 1

                   :vartype 1700

                   :vartypmod 655364

                   :varcollid 0

                   :varlevelsup 0

                   :varnoold 1

                   :varoattno 1

                   :location 41

                   }

                   {VAR

                   :varno 2

                   :varattno 1

                   :vartype 1700

                   :vartypmod 655364

                   :varcollid 0

                   :varlevelsup 0

                   :varnoold 2

                   :varoattno 1

                    :location 50

                   }

                )

                :location 49

                }

             }

          :targetList (

             {TARGETENTRY

             :expr

                {VAR

                :varno 1

                :varattno 2

                :vartype 1043

                :vartypmod 34

                :varcollid 100

                :varlevelsup 0

                :varnoold 1

                :varoattno 2

                :location 7

                }

             :resno 1

             :resname cname

             :ressortgroupref 0

             :resorigtbl 16394

             :resorigcol 2

             :resjunk false

             }

             {TARGETENTRY

             :expr

                {VAR

                :varno 2

                :varattno 2

                :vartype 1043

                :vartypmod 34

                :varcollid 100

                :varlevelsup 0

                :varnoold 2

                :varoattno 2

                :location 13

                }

             :resno 2

             :resname comp

             :ressortgroupref 0

             :resorigtbl 16397

             :resorigcol 2

             :resjunk false

             }

          )

          :returningList <>

          :groupClause <>

          :havingQual <>

          :windowClause <>

          :distinctClause <>

          :sortClause <>

          :limitOffset <>

          :limitCount <>

          :rowMarks <>

          :setOperations <>

          :constraintDeps <>

          }

       )

就到这儿吧。

 




------------
转载请注明出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com

  • 大小: 144.6 KB
  • 大小: 246.6 KB
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics