本节简单介绍了PostgreSQL在执行逻辑优化中相关的数据结构,包括FromExpr&JoinExpr.
一、数据结构
FromExpr
表示FROM … WHERE结构
/*---------- * FromExpr - represents a FROM ... WHERE ... construct * 表示FROM ... WHERE结构 * * This is both more flexible than a JoinExpr (it can have any number of * children, including zero) and less so --- we don't need to deal with * aliases and so on. The output column set is implicitly just the union * of the outputs of the children. * 该结构比JoinExpr(有0..n个子节点)更为灵活 -- 不需要处理别名等. * 输出列集合是子集输出的汇总. *---------- */typedef struct FromExpr{ NodeTag type; //连接子树链表 List *fromlist; /* List of join subtrees */ //join中的表达式 Node *quals; /* qualifiers on join, if any */} FromExpr;
JoinExpr
用于SQL JOIN表达式.
/*---------- * JoinExpr - for SQL JOIN expressions * 用于SQL JOIN表达式. * * isNatural, usingClause, and quals are interdependent. The user can write * only one of NATURAL, USING(), or ON() (this is enforced by the grammar). * If he writes NATURAL then parse analysis generates the equivalent USING() * list, and from that fills in "quals" with the right equality comparisons. * If he writes USING() then "quals" is filled with equality comparisons. * If he writes ON() then only "quals" is set. Note that NATURAL/USING * are not equivalent to ON() since they also affect the output column list. * isNatural, usingClause, and quals是相互依赖的. * 用户只可以使用NATURAL, USING(), or ON()(语法限制). * 如果是NATURAL,则解析器会产生相应的USING()链表,并使用正确的等值比较表达式填充quals. * 如果是USING(),则使用正确的等值比较表达式填充quals. * 如果是ON(),则只设置quals字段. * 注意NATURAL/USING与ON()并不相同,因为它们同时影响了输出列链表. * * alias is an Alias node representing the AS alias-clause attached to the * join expression, or NULL if no clause. NB: presence or absence of the * alias has a critical impact on semantics, because a join with an alias * restricts visibility of the tables/columns inside it. * alias表示与join表达式相关的AS别名子句,如无则为NULL. * 注意:别名的存在与否对语义有很大影响,因此有别名的join限制了其中表/列的可见性. * * During parse analysis, an RTE is created for the Join, and its index * is filled into rtindex. This RTE is present mainly so that Vars can * be created that refer to the outputs of the join. The planner sometimes * generates JoinExprs internally; these can have rtindex = 0 if there are * no join alias variables referencing such joins. * 在解析时,RTE在参与Join时解析,编号填充到rtindex中. * 该RTE存在的目的主要是可以创建引用join输出的Vars. * 计划器有时候会在内部生成JoinExprs;如没有join别名变量参考这样的连接,那么rtindex = 0 *---------- */typedef struct JoinExpr{ NodeTag type; //join类型 JoinType jointype; /* type of join */ //自然连接? bool isNatural; /* Natural join? Will need to shape table */ //左树 Node *larg; /* left subtree */ //右树 Node *rarg; /* right subtree */ //USING语句(String链表) List *usingClause; /* USING clause, if any (list of String) */ //join限定符 Node *quals; /* qualifiers on join, if any */ //别名语句 Alias *alias; /* user-written alias clause, if any */ //分配给join的RT编号,或者为0 int rtindex; /* RT index assigned for join, or 0 */} JoinExpr;
二、源码解读
N/A 郑州妇科医院:http://jbk.39.net/yiyuanzaixian/sysdfkyy/
三、跟踪分析
...(gdb) p *(FromExpr *)($rte_sq_rte->subquery->jointree)$44 = {type = T_FromExpr, fromlist = 0x16fda18, quals = 0x16fe0f0}(gdb) set $rtesq2_jointree=(FromExpr *)($rte_sq_rte->subquery->jointree)(gdb) p *$rtesq2_jointree->fromlist$48 = {type = T_List, length = 1, head = 0x16fd9f8, tail = 0x16fd9f8}(gdb) p *(Node *)$rtesq2_jointree->fromlist->head->data.ptr_value$49 = {type = T_JoinExpr}(gdb) set $tmpvar=(JoinExpr *)$rtesq2_jointree->fromlist->head->data.ptr_value(gdb) p *$tmpvar$3 = {type = T_JoinExpr, jointype = JOIN_INNER, isNatural = false, larg = 0x2b68730, rarg = 0x2c215e8, usingClause = 0x0, quals = 0x2c28130, alias = 0x0, rtindex = 5}(gdb) p *$tmpvar->larg$4 = {type = T_JoinExpr}(gdb) p *(JoinExpr *)$tmpvar->larg$5 = {type = T_JoinExpr, jointype = JOIN_INNER, isNatural = false, larg = 0x2c1e848, rarg = 0x2c1ebd8, usingClause = 0x0, quals = 0x2c20c48, alias = 0x0, rtindex = 3}(gdb) p *(JoinExpr *)$tmpvar->rarg$6 = {type = T_RangeTblRef, jointype = JOIN_SEMI, isNatural = 8, larg = 0x2b66de0, rarg = 0x636d7764, usingClause = 0x10, quals = 0x2b66de0, alias = 0xda, rtindex = 46274048}(gdb) p *(JoinExpr *)$tmpvar->quals$7 = {type = T_OpExpr, jointype = 98, isNatural = 67, larg = 0x0, rarg = 0x64, usingClause = 0x2c27fb8, quals = 0xa9, alias = 0x0, rtindex = 0}...
四、参考资料
N/A