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

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

概述        话说查询“selectcname, comp from test1, test2 where test1.id=test2.id;” 发送到服务器端,走查询分支exec_simple_query,先调用start_xact_command初始化了事务管理相关对象和资源,接着调用pg_parse_query,通过Lex和Yacc对传入SQL语句进行词法语法解析,生成解析树。下来调用G

话说查询“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

总结

以上是内存溢出为你收集整理的PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分析重写成querytree全部内容,希望文章能够帮你解决PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分析重写成querytree所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1178503.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存