ITPub博客

首页 > 数据库 > PostgreSQL > PostgreSQL 源码解读(207)- 查询#120(数据结构FromExpr&JoinExpr)

PostgreSQL 源码解读(207)- 查询#120(数据结构FromExpr&JoinExpr)

原创 PostgreSQL 作者:husthxd 时间:2019-06-24 15:31:59 0 删除 编辑

本节简单介绍了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

三、跟踪分析


...
(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

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/6906/viewspace-2648538/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
长期从事政务、金融等行业产品研发和架构设计工作,ITPUB数据库版块资深版主,对Oracle、PostgreSQL有深入研究。现就职于广州云图数据技术有限公司,系统架构师。

注册时间:2007-12-28

  • 博文量
    1308
  • 访问量
    3785513