加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-13 17:41:29 所属栏目:百科 来源:网络整理
导读:话说查询“ selectcname,comp from test1,test2 where test1.id=test2.id; ” 发送到服务器端,走查询分支exec_simple_query,先调用start_xact_command初始化了事务管理相关对象和资源,接着调用pg_parse_query,通过Lex和Yacc对传入SQL语句进行词法语法解

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读