PostgreSQL服务过程中的那些事二: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进行语义分析和查询重写的调用序列图。



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结构图。



例子里查询语句对应的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

猜你在找的Postgre SQL相关文章