• PostgreSQL在何处处理 sql查询之十二


    接前面,对 subquery_planner,进行进一步的分析:

    /*--------------------
     * subquery_planner
     *      Invokes the planner on a subquery.  We recurse to here for each
     *      sub-SELECT found in the query tree.
     *
     * glob is the global state for the current planner run.
     * parse is the querytree produced by the parser & rewriter.
     * parent_root is the immediate parent Query's info (NULL at the top level).
     * hasRecursion is true if this is a recursive WITH query.
     * tuple_fraction is the fraction of tuples we expect will be retrieved.
     * tuple_fraction is interpreted as explained for grouping_planner, below.
     *
     * If subroot isn't NULL, we pass back the query's final PlannerInfo struct;
     * among other things this tells the output sort ordering of the plan.
     *
     * Basically, this routine does the stuff that should only be done once
     * per Query object.  It then calls grouping_planner.  At one time,
     * grouping_planner could be invoked recursively on the same Query object;
     * that's not currently true, but we keep the separation between the two
     * routines anyway, in case we need it again someday.
     *
     * subquery_planner will be called recursively to handle sub-Query nodes
     * found within the query's expressions and rangetable.
     *
     * Returns a query plan.
     *--------------------
     */
    Plan *
    subquery_planner(PlannerGlobal *glob, Query *parse,
                     PlannerInfo *parent_root,
                     bool hasRecursion, double tuple_fraction,
                     PlannerInfo **subroot)
    {
       ...
    
        /*
         * Do the main planning.  If we have an inherited target relation, that
         * needs special processing, else go straight to grouping_planner.
         */
        if (parse->resultRelation &&
            rt_fetch(parse->resultRelation, parse->rtable)->inh)
            plan = inheritance_planner(root);
        else
        {
            plan = grouping_planner(root, tuple_fraction);
         /* If it's not SELECT, we need a ModifyTable node */
            if (parse->commandType != CMD_SELECT)
            {
                List       *returningLists;
                List       *rowMarks;
            /*
                 * Set up the RETURNING list-of-lists, if needed.
                 */
                if (parse->returningList)
                    returningLists = list_make1(parse->returningList);
                else
                    returningLists = NIL;
            /*
                 * If there was a FOR UPDATE/SHARE clause, the LockRows node will
                 * have dealt with fetching non-locked marked rows, else we need
                 * to have ModifyTable do that.
                 */
                if (parse->rowMarks)
                    rowMarks = NIL;
                else
                    rowMarks = root->rowMarks;
    
                plan = (Plan *) make_modifytable(parse->commandType,
                                                 parse->canSetTag,
                                           list_make1_int(parse->resultRelation),
                                                 list_make1(plan),
                                                 returningLists,
                                                 rowMarks,
                                                 SS_assign_special_param(root));
            }
        }
        ...
        return plan;
    }

     当表所对应的文件不在时,在 grouping_planner处就会报错。

    grouping_planner
  • 相关阅读:
    Typora 使用 Markdown 嵌入 LaTeX 数学公式符号语法
    爬虫常用的 urllib 库知识点
    执行Go程序的三种方式及Go语言关键字
    Win10 安装 MongoDB 3.6.5 失败的问题
    笨办法理解动态规划算法
    EclipseEE的Web开发环境配置(使用Tomcat作为Web服务器)
    二分类神经网络公式推导过程
    B+树在磁盘存储中的应用
    JAVA NIO工作原理及代码示例
    B树和B+树的插入、删除图文详解
  • 原文地址:https://www.cnblogs.com/gaojian/p/3094667.html
Copyright © 2020-2023  润新知