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

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

        话说查询“selectcname, 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进行语义分析和查询重写的调用序列图。


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

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

 

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

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

 


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

 

 

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

把这个例子再重复一下:

create table test1 (ID numeric(10), cnamevarchar(30));

create table test2 (ID numeric(10), compvarchar(30));

select cname,comp from test1,test2 wheretest1.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