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

你可能感兴趣的:(PostgreSQL)