PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分
话说查询“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进行语义分析和查询重写的调用序列图。
Postgres服务进程简查之语义分析和查询重写调用序列图
上图红色方框中显示了对parsetree进行语义分析和查询重写的方法调用过程,在parse_analyze方法中对parsetree进行语义分析,生成querytree,在pg_rewrite_query方法中对前面生成的querytree进一步进行修改,最后把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),cnamevarchar(30)); create table test2 (ID numeric(10),compvarchar(30)); select cname,test2 wheretest1.id=test2.id; 上面的图《例子里查询语句对应的querytree结构图》就是SQL语句“select cname,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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- SQLLite (三):sqlite3_prepare_v2,sqlite3_step
- c# – Mono missing System.Numerics.BigInteger
- XML Schema类型别名?
- JQeury form插件的ajaxForm方法和ajaxSubmit方法
- phoenix_interface接口测试中XmlParserUtil工具演
- React+webpack开发环境的搭建_0
- 如何指定用于Doctrine 2.2 / Symfony 2.2和Postg
- c – 将字符串时间转换为unix时间,反之亦然
- c# – 使用Onedrive SDK/API(或任何API)进行身份
- PostgreSQL的日志系统