对PostgreSQL源代码中的build_jion_rel的理解

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介:

其代码结构:

复制代码
/*
 * build_join_rel
 *      Returns relation entry corresponding to the union of two given rels,
 *      creating a new relation entry if none already exists.
 *
 * 'joinrelids' is the Relids set that uniquely identifies the join
 * 'outer_rel' and 'inner_rel' are relation nodes for the relations to be
 *        joined
 * 'sjinfo': join context info
 * 'restrictlist_ptr': result variable.  If not NULL, *restrictlist_ptr
 *        receives the list of RestrictInfo nodes that apply to this
 *        particular pair of joinable relations.
 *
 * restrictlist_ptr makes the routine's API a little grotty, but it saves
 * duplicated calculation of the restrictlist...
 */
RelOptInfo *
build_join_rel(PlannerInfo *root,
               Relids joinrelids,
               RelOptInfo *outer_rel,
               RelOptInfo *inner_rel,
               SpecialJoinInfo *sjinfo,
               List **restrictlist_ptr)
{
    RelOptInfo *joinrel;
    List       *restrictlist;

    /*
     * See if we already have a joinrel for this set of base rels.
     */
    joinrel = find_join_rel(root, joinrelids);

    if (joinrel)
    {
        /*
         * Yes, so we only need to figure the restrictlist for this particular
         * pair of component relations.
         */
        if (restrictlist_ptr)
            *restrictlist_ptr = build_joinrel_restrictlist(root,
                                                           joinrel,
                                                           outer_rel,
                                                           inner_rel);
        return joinrel;
    }

    /*
     * Nope, so make one.
     */
    joinrel = makeNode(RelOptInfo);
    joinrel->reloptkind = RELOPT_JOINREL;
    joinrel->relids = bms_copy(joinrelids);
    joinrel->rows = 0;
    joinrel->width = 0;
    joinrel->reltargetlist = NIL;
    joinrel->pathlist = NIL;
    joinrel->ppilist = NIL;
    joinrel->cheapest_startup_path = NULL;
    joinrel->cheapest_total_path = NULL;
    joinrel->cheapest_unique_path = NULL;
    joinrel->cheapest_parameterized_paths = NIL;
    joinrel->relid = 0;            /* indicates not a baserel */
    joinrel->rtekind = RTE_JOIN;
    joinrel->min_attr = 0;
    joinrel->max_attr = 0;
    joinrel->attr_needed = NULL;
    joinrel->attr_widths = NULL;
    joinrel->indexlist = NIL;
    joinrel->pages = 0;
    joinrel->tuples = 0;
    joinrel->allvisfrac = 0;
    joinrel->subplan = NULL;
    joinrel->subroot = NULL;
    joinrel->fdwroutine = NULL;
    joinrel->fdw_private = NULL;
    joinrel->baserestrictinfo = NIL;
    joinrel->baserestrictcost.startup = 0;
    joinrel->baserestrictcost.per_tuple = 0;
    joinrel->joininfo = NIL;
    joinrel->has_eclass_joins = false;

    /*
     * Create a new tlist containing just the vars that need to be output from
     * this join (ie, are needed for higher joinclauses or final output).
     *
     * NOTE: the tlist order for a join rel will depend on which pair of outer
     * and inner rels we first try to build it from.  But the contents should
     * be the same regardless.
     */
    build_joinrel_tlist(root, joinrel, outer_rel);
    build_joinrel_tlist(root, joinrel, inner_rel);
    add_placeholders_to_joinrel(root, joinrel);

    /*
     * Construct restrict and join clause lists for the new joinrel. (The
     * caller might or might not need the restrictlist, but I need it anyway
     * for set_joinrel_size_estimates().)
     */
    restrictlist = build_joinrel_restrictlist(root, joinrel,
                                              outer_rel, inner_rel);
    if (restrictlist_ptr)
        *restrictlist_ptr = restrictlist;
    build_joinrel_joinlist(joinrel, outer_rel, inner_rel);

    /*
     * This is also the right place to check whether the joinrel has any
     * pending EquivalenceClass joins.
     */
    joinrel->has_eclass_joins = has_relevant_eclass_joinclause(root, joinrel);

    /*
     * Set estimates of the joinrel's size.
     */
    set_joinrel_size_estimates(root, joinrel, outer_rel, inner_rel,
                               sjinfo, restrictlist);

    /*
     * Add the joinrel to the query's joinrel list, and store it into the
     * auxiliary hashtable if there is one.  NB: GEQO requires us to append
     * the new joinrel to the end of the list!
     */
    root->join_rel_list = lappend(root->join_rel_list, joinrel);

    if (root->join_rel_hash)
    {
        JoinHashEntry *hentry;
        bool        found;

        hentry = (JoinHashEntry *) hash_search(root->join_rel_hash,
                                               &(joinrel->relids),
                                               HASH_ENTER,
                                               &found);
        Assert(!found);
        hentry->join_rel = joinrel;
    }

    /*
     * Also, if dynamic-programming join search is active, add the new joinrel
     * to the appropriate sublist.    Note: you might think the Assert on number
     * of members should be for equality, but some of the level 1 rels might
     * have been joinrels already, so we can only assert <=.
     */
    if (root->join_rel_level)
    {
        Assert(root->join_cur_level > 0);
        Assert(root->join_cur_level <= bms_num_members(joinrel->relids));
        root->join_rel_level[root->join_cur_level] =
            lappend(root->join_rel_level[root->join_cur_level], joinrel);
    }

    return joinrel;
}
复制代码

其中:

build_joinrel_tlist: 就是targetlist (table 名集合)

restrictlist: 两个table各自的where条件

build_joinrel_jionlist: jion条件集合





本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2013/06/13/3134009.html,如需转载请自行联系原作者

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
XML 关系型数据库 Linux
从小白到专家 PG技术大讲堂 - Part 2:PostgreSQL源代码安装
Part 2:PG源代码安装 步骤1 创建用户与环境配置 步骤2 系统内核参数配置 步骤3 PostgreSQL 安装
299 1
从小白到专家 PG技术大讲堂 - Part 2:PostgreSQL源代码安装
|
存储 SQL Oracle
源代码编译安装 MySQL 和多实例| 学习笔记
快速学习源代码编译安装 MySQL 和多实例
|
关系型数据库 C++ PostgreSQL
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 17 章 在Windows上从源代码安装
第 17 章 在Windows上从源代码安装 目录 17.1. 使用Visual C++或Microsoft Windows SDK构建 17.1.1. 要求 17.1.2. 针对64位Windows的特殊考虑 17.1.3. 构建 17.1.4. 清理和安装 17.1.5. 运行回归测试 17.1.6. 构建文档 对于大部分用户,推荐下载Windows的二进制发布,它在PostgreSQL 的网站上作为一个图形化安装包可供下载。
1354 0
|
关系型数据库 开发工具 C++
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 17 章 在Windows上从源代码安装_17.1. 使用Visual C++或Microsoft Windows SDK构建
17.1. 使用Visual C++或Microsoft Windows SDK构建 17.1.1. 要求 17.1.2. 针对64位Windows的特殊考虑 17.1.3. 构建 17.1.4. 清理和安装 17.1.5. 运行回归测试 17.1.6. 构建文档 PostgreSQL可以使用来自微软的Visual C++编译器套件构建。
1592 0
|
关系型数据库 Unix C++
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.7. 平台相关的说明
16.7. 平台相关的说明 16.7.1. AIX 16.7.2. Cygwin 16.7.3. HP-UX 16.7.4. MinGW/原生 Windows 16.7.5. Solaris 这一节提供了考虑 PostgreSQL 安装和设置的附加平台相关的话题。
1523 0
|
关系型数据库 Unix 测试技术
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.6. 平台支持
16.6. 平台支持 如果代码包含规定要工作在一个平台(即一种 CPU 架构和操作系统的结合)上并且它最近已经被验证能在该平台上编译并通过其回归测试,PostgreSQL开发社区才会认为该平台是被支持的。
1328 0
|
关系型数据库 Unix Shell
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.5. 安装后设置
16.5. 安装后设置 16.5.1. 共享库 16.5.2. 环境变量 16.5.1. 共享库 在一些有共享库的系统里,你需要告诉你的系统如何找到新安装的共享库。那些并不是必须做这个工作的系统包括 FreeBSD、HP-UX、Linux、NetBSD、OpenBSD和Solaris。
1395 0
|
关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.3. 获取源码
16.3. 获取源码 PostgreSQL 10.1 源代码可以从我们的官方网站 https://www.postgresql.org/download/的下载区中获得。你将得到一个名为postgresql-10.1.tar.gz或postgresql-10.1.tar.bz2的文件。
1329 0
|
关系型数据库 PostgreSQL Python
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.2. 要求
16.2. 要求 一般说来,一个现代的与 Unix 兼容的平台应该就能运行PostgreSQL。 到发布为止已经明确测试过的平台的列表在 第 16.6 节中列出。在发布的doc子目录里面有许多平台相关的 FAQ文档,如果你碰到问题你可能会需要参考它们。
1418 0
|
关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.1. 简单版
16.1. 简单版 ./configure make su make install adduser postgres mkdir /usr/local/pgsql/data chown postgres /usr/local/pgsql/data su - postgres /usr/loc.
1209 0