diff options
| author | Bruce Momjian <bruce@momjian.us> | 2001-03-22 04:01:46 +0000 |
|---|---|---|
| committer | Bruce Momjian <bruce@momjian.us> | 2001-03-22 04:01:46 +0000 |
| commit | 9e1552607a9dc6bc23e43d46770a9063ade4f3f0 (patch) | |
| tree | 6a230d81917ebc004e40cd46c48f2aa27eec153e /src/backend/optimizer/plan | |
| parent | 6cf8707b828b14b5c2336076ce358b18b67829d6 (diff) | |
| download | postgresql-9e1552607a9dc6bc23e43d46770a9063ade4f3f0.tar.gz | |
pgindent run. Make it all clean.
Diffstat (limited to 'src/backend/optimizer/plan')
| -rw-r--r-- | src/backend/optimizer/plan/createplan.c | 96 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 134 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/planmain.c | 16 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/planner.c | 215 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 34 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/subselect.c | 46 |
6 files changed, 292 insertions, 249 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 738b696306..8c3b00289d 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.103 2001/01/24 19:42:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.104 2001/03/22 03:59:36 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -42,19 +42,19 @@ static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path, static TidScan *create_tidscan_plan(TidPath *best_path, List *tlist, List *scan_clauses); static SubqueryScan *create_subqueryscan_plan(Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static NestLoop *create_nestloop_plan(NestPath *best_path, List *tlist, - List *joinclauses, List *otherclauses, - Plan *outer_plan, List *outer_tlist, - Plan *inner_plan, List *inner_tlist); + List *joinclauses, List *otherclauses, + Plan *outer_plan, List *outer_tlist, + Plan *inner_plan, List *inner_tlist); static MergeJoin *create_mergejoin_plan(MergePath *best_path, List *tlist, - List *joinclauses, List *otherclauses, - Plan *outer_plan, List *outer_tlist, - Plan *inner_plan, List *inner_tlist); + List *joinclauses, List *otherclauses, + Plan *outer_plan, List *outer_tlist, + Plan *inner_plan, List *inner_tlist); static HashJoin *create_hashjoin_plan(HashPath *best_path, List *tlist, - List *joinclauses, List *otherclauses, - Plan *outer_plan, List *outer_tlist, - Plan *inner_plan, List *inner_tlist); + List *joinclauses, List *otherclauses, + Plan *outer_plan, List *outer_tlist, + Plan *inner_plan, List *inner_tlist); static List *fix_indxqual_references(List *indexquals, IndexPath *index_path); static List *fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam, Form_pg_index index); @@ -72,20 +72,20 @@ static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid, static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tideval); static NestLoop *make_nestloop(List *tlist, - List *joinclauses, List *otherclauses, - Plan *lefttree, Plan *righttree, - JoinType jointype); + List *joinclauses, List *otherclauses, + Plan *lefttree, Plan *righttree, + JoinType jointype); static HashJoin *make_hashjoin(List *tlist, - List *joinclauses, List *otherclauses, - List *hashclauses, - Plan *lefttree, Plan *righttree, - JoinType jointype); + List *joinclauses, List *otherclauses, + List *hashclauses, + Plan *lefttree, Plan *righttree, + JoinType jointype); static Hash *make_hash(List *tlist, Node *hashkey, Plan *lefttree); static MergeJoin *make_mergejoin(List *tlist, - List *joinclauses, List *otherclauses, - List *mergeclauses, - Plan *lefttree, Plan *righttree, - JoinType jointype); + List *joinclauses, List *otherclauses, + List *mergeclauses, + Plan *lefttree, Plan *righttree, + JoinType jointype); /* * create_plan @@ -313,8 +313,8 @@ create_append_plan(Query *root, AppendPath *best_path) foreach(subpaths, best_path->subpaths) { - Path *subpath = (Path *) lfirst(subpaths); - + Path *subpath = (Path *) lfirst(subpaths); + subplans = lappend(subplans, create_plan(root, subpath)); } @@ -344,7 +344,7 @@ create_seqscan_plan(Path *best_path, List *tlist, List *scan_clauses) /* there should be exactly one base rel involved... */ Assert(length(best_path->parent->relids) == 1); - Assert(! best_path->parent->issubquery); + Assert(!best_path->parent->issubquery); scan_relid = (Index) lfirsti(best_path->parent->relids); @@ -386,7 +386,7 @@ create_indexscan_plan(Query *root, /* there should be exactly one base rel involved... */ Assert(length(best_path->path.parent->relids) == 1); - Assert(! best_path->path.parent->issubquery); + Assert(!best_path->path.parent->issubquery); baserelid = lfirsti(best_path->path.parent->relids); @@ -496,7 +496,7 @@ create_tidscan_plan(TidPath *best_path, List *tlist, List *scan_clauses) /* there should be exactly one base rel involved... */ Assert(length(best_path->path.parent->relids) == 1); - Assert(! best_path->path.parent->issubquery); + Assert(!best_path->path.parent->issubquery); scan_relid = (Index) lfirsti(best_path->path.parent->relids); @@ -737,21 +737,22 @@ create_mergejoin_plan(MergePath *best_path, best_path->innersortkeys); /* - * The executor requires the inner side of a mergejoin to support "mark" - * and "restore" operations. Not all plan types do, so we must be careful - * not to generate an invalid plan. If necessary, an invalid inner plan - * can be handled by inserting a Materialize node. + * The executor requires the inner side of a mergejoin to support + * "mark" and "restore" operations. Not all plan types do, so we must + * be careful not to generate an invalid plan. If necessary, an + * invalid inner plan can be handled by inserting a Materialize node. * - * Since the inner side must be ordered, and only Sorts and IndexScans can - * create order to begin with, you might think there's no problem --- but - * you'd be wrong. Nestloop and merge joins can *preserve* the order of - * their inputs, so they can be selected as the input of a mergejoin, - * and that won't work in the present executor. + * Since the inner side must be ordered, and only Sorts and IndexScans + * can create order to begin with, you might think there's no problem + * --- but you'd be wrong. Nestloop and merge joins can *preserve* + * the order of their inputs, so they can be selected as the input of + * a mergejoin, and that won't work in the present executor. * * Doing this here is a bit of a kluge since the cost of the Materialize - * wasn't taken into account in our earlier decisions. But Materialize - * is hard to estimate a cost for, and the above consideration shows that - * this is a rare case anyway, so this seems an acceptable way to proceed. + * wasn't taken into account in our earlier decisions. But + * Materialize is hard to estimate a cost for, and the above + * consideration shows that this is a rare case anyway, so this seems + * an acceptable way to proceed. * * This check must agree with ExecMarkPos/ExecRestrPos in * executor/execAmi.c! @@ -1015,6 +1016,7 @@ static Node * fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, Oid *opclass) { + /* * Remove any binary-compatible relabeling of the indexkey */ @@ -1025,8 +1027,8 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, * We represent index keys by Var nodes having the varno of the base * table but varattno equal to the index's attribute number (index * column position). This is a bit hokey ... would be cleaner to use - * a special-purpose node type that could not be mistaken for a regular - * Var. But it will do for now. + * a special-purpose node type that could not be mistaken for a + * regular Var. But it will do for now. */ if (IsA(node, Var)) { @@ -1062,7 +1064,7 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, * the returned varattno must be 1. */ - Assert(is_funcclause(node)); /* not a very thorough check, but easy */ + Assert(is_funcclause(node));/* not a very thorough check, but easy */ /* indclass[0] is the only class of a functional index */ *opclass = index->indclass[0]; @@ -1493,7 +1495,7 @@ make_sort_from_pathkeys(List *tlist, Plan *lefttree, List *pathkeys) return make_sort(sort_tlist, lefttree, numsortkeys); } -Material * +Material * make_material(List *tlist, Plan *lefttree) { Material *node = makeNode(Material); @@ -1734,10 +1736,10 @@ make_limit(List *tlist, Plan *lefttree, copy_plan_costsize(plan, lefttree); /* - * If offset/count are constants, adjust the output rows count and costs - * accordingly. This is only a cosmetic issue if we are at top level, - * but if we are building a subquery then it's important to report - * correct info to the outer planner. + * If offset/count are constants, adjust the output rows count and + * costs accordingly. This is only a cosmetic issue if we are at top + * level, but if we are building a subquery then it's important to + * report correct info to the outer planner. */ if (limitOffset && IsA(limitOffset, Const)) { diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 1025a9b7f6..2b2ebf238f 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.57 2001/02/16 03:16:57 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.58 2001/03/22 03:59:36 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -35,11 +35,11 @@ static void mark_baserels_for_outer_join(Query *root, Relids rels, - Relids outerrels); + Relids outerrels); static void distribute_qual_to_rels(Query *root, Node *clause, - bool ispusheddown, - bool isouterjoin, - Relids qualscope); + bool ispusheddown, + bool isouterjoin, + Relids qualscope); static void add_join_info_to_rels(Query *root, RestrictInfo *restrictinfo, Relids join_relids); static void add_vars_to_targetlist(Query *root, List *vars); @@ -57,7 +57,7 @@ static void check_hashjoinable(RestrictInfo *restrictinfo); * build_base_rel_tlists * Creates rel nodes for every relation mentioned in the target list * 'tlist' (if a node hasn't already been created) and adds them to - * root->base_rel_list. Creates targetlist entries for each var seen + * root->base_rel_list. Creates targetlist entries for each var seen * in 'tlist' and adds them to the tlist of the appropriate rel node. */ void @@ -118,6 +118,7 @@ add_missing_rels_to_query(Query *root, Node *jtnode) if (IsA(jtnode, RangeTblRef)) { int varno = ((RangeTblRef *) jtnode)->rtindex; + /* This call to get_base_rel does the primary work... */ RelOptInfo *rel = get_base_rel(root, varno); @@ -160,7 +161,7 @@ add_missing_rels_to_query(Query *root, Node *jtnode) * distribute_quals_to_rels * Recursively scan the query's join tree for WHERE and JOIN/ON qual * clauses, and add these to the appropriate RestrictInfo and JoinInfo - * lists belonging to base RelOptInfos. New base rel entries are created + * lists belonging to base RelOptInfos. New base rel entries are created * as needed. Also, base RelOptInfos are marked with outerjoinset * information, to aid in proper positioning of qual clauses that appear * above outer joins. @@ -169,7 +170,7 @@ add_missing_rels_to_query(Query *root, Node *jtnode) * be evaluated at the lowest level where all the variables it mentions are * available. However, we cannot push a qual down into the nullable side(s) * of an outer join since the qual might eliminate matching rows and cause a - * NULL row to be incorrectly emitted by the join. Therefore, rels appearing + * NULL row to be incorrectly emitted by the join. Therefore, rels appearing * within the nullable side(s) of an outer join are marked with * outerjoinset = list of Relids used at the outer join node. * This list will be added to the list of rels referenced by quals using such @@ -228,14 +229,14 @@ distribute_quals_to_rels(Query *root, Node *jtnode) List *qual; /* - * Order of operations here is subtle and critical. First we recurse - * to handle sub-JOINs. Their join quals will be placed without - * regard for whether this level is an outer join, which is correct. - * Then, if we are an outer join, we mark baserels contained within - * the nullable side(s) with our own rel list; this will restrict - * placement of subsequent quals using those rels, including our own - * quals and quals above us in the join tree. - * Finally we place our own join quals. + * Order of operations here is subtle and critical. First we + * recurse to handle sub-JOINs. Their join quals will be placed + * without regard for whether this level is an outer join, which + * is correct. Then, if we are an outer join, we mark baserels + * contained within the nullable side(s) with our own rel list; + * this will restrict placement of subsequent quals using those + * rels, including our own quals and quals above us in the join + * tree. Finally we place our own join quals. */ leftids = distribute_quals_to_rels(root, j->larg); rightids = distribute_quals_to_rels(root, j->rarg); @@ -261,9 +262,10 @@ distribute_quals_to_rels(Query *root, Node *jtnode) isouterjoin = true; break; case JOIN_UNION: + /* - * This is where we fail if upper levels of planner haven't - * rewritten UNION JOIN as an Append ... + * This is where we fail if upper levels of planner + * haven't rewritten UNION JOIN as an Append ... */ elog(ERROR, "UNION JOIN is not implemented yet"); break; @@ -338,12 +340,12 @@ distribute_qual_to_rels(Query *root, Node *clause, bool can_be_equijoin; restrictinfo->clause = (Expr *) clause; - restrictinfo->eval_cost = -1; /* not computed until needed */ + restrictinfo->eval_cost = -1; /* not computed until needed */ restrictinfo->subclauseindices = NIL; restrictinfo->mergejoinoperator = InvalidOid; restrictinfo->left_sortop = InvalidOid; restrictinfo->right_sortop = InvalidOid; - restrictinfo->left_pathkey = NIL; /* not computable yet */ + restrictinfo->left_pathkey = NIL; /* not computable yet */ restrictinfo->right_pathkey = NIL; restrictinfo->hashjoinoperator = InvalidOid; restrictinfo->left_dispersion = -1; /* not computed until needed */ @@ -358,7 +360,7 @@ distribute_qual_to_rels(Query *root, Node *clause, * Cross-check: clause should contain no relids not within its scope. * Otherwise the parser messed up. */ - if (! is_subseti(relids, qualscope)) + if (!is_subseti(relids, qualscope)) elog(ERROR, "JOIN qualification may not refer to other relations"); /* @@ -377,14 +379,14 @@ distribute_qual_to_rels(Query *root, Node *clause, * This ensures that the clause will be evaluated exactly at the level * of joining corresponding to the outer join. * - * For a non-outer-join qual, we can evaluate the qual as soon as - * (1) we have all the rels it mentions, and (2) we are at or above any - * outer joins that can null any of these rels and are below the syntactic - * location of the given qual. To enforce the latter, scan the base rels - * listed in relids, and merge their outer-join lists into the clause's - * own reference list. At the time we are called, the outerjoinset list - * of each baserel will show exactly those outer joins that are below the - * qual in the join tree. + * For a non-outer-join qual, we can evaluate the qual as soon as (1) we + * have all the rels it mentions, and (2) we are at or above any outer + * joins that can null any of these rels and are below the syntactic + * location of the given qual. To enforce the latter, scan the base + * rels listed in relids, and merge their outer-join lists into the + * clause's own reference list. At the time we are called, the + * outerjoinset list of each baserel will show exactly those outer + * joins that are below the qual in the join tree. */ if (isouterjoin) { @@ -396,19 +398,24 @@ distribute_qual_to_rels(Query *root, Node *clause, Relids newrelids = relids; List *relid; - /* We rely on set_unioni to be nondestructive of its input lists... */ + /* + * We rely on set_unioni to be nondestructive of its input + * lists... + */ can_be_equijoin = true; foreach(relid, relids) { RelOptInfo *rel = get_base_rel(root, lfirsti(relid)); if (rel->outerjoinset && - ! is_subseti(rel->outerjoinset, relids)) + !is_subseti(rel->outerjoinset, relids)) { newrelids = set_unioni(newrelids, rel->outerjoinset); + /* - * Because application of the qual will be delayed by outer - * join, we mustn't assume its vars are equal everywhere. + * Because application of the qual will be delayed by + * outer join, we mustn't assume its vars are equal + * everywhere. */ can_be_equijoin = false; } @@ -419,10 +426,11 @@ distribute_qual_to_rels(Query *root, Node *clause, } /* - * Mark the qual as "pushed down" if it can be applied at a level below - * its original syntactic level. This allows us to distinguish original - * JOIN/ON quals from higher-level quals pushed down to the same joinrel. - * A qual originating from WHERE is always considered "pushed down". + * Mark the qual as "pushed down" if it can be applied at a level + * below its original syntactic level. This allows us to distinguish + * original JOIN/ON quals from higher-level quals pushed down to the + * same joinrel. A qual originating from WHERE is always considered + * "pushed down". */ restrictinfo->ispusheddown = ispusheddown || !sameseti(relids, qualscope); @@ -458,10 +466,10 @@ distribute_qual_to_rels(Query *root, Node *clause, * the relid list. Set additional RestrictInfo fields for * joining. * - * We don't bother setting the merge/hashjoin info if we're not - * going to need it. We do want to know about mergejoinable ops - * in any potential equijoin clause (see later in this routine), - * and we ignore enable_mergejoin if isouterjoin is true, because + * We don't bother setting the merge/hashjoin info if we're not going + * to need it. We do want to know about mergejoinable ops in any + * potential equijoin clause (see later in this routine), and we + * ignore enable_mergejoin if isouterjoin is true, because * mergejoin is the only implementation we have for full and right * outer joins. */ @@ -485,6 +493,7 @@ distribute_qual_to_rels(Query *root, Node *clause, } else { + /* * 'clause' references no rels, and therefore we have no place to * attach it. Shouldn't get here if callers are working properly. @@ -493,12 +502,12 @@ distribute_qual_to_rels(Query *root, Node *clause, } /* - * If the clause has a mergejoinable operator, and is not an outer-join - * qualification nor bubbled up due to an outer join, then the two sides - * represent equivalent PathKeyItems for path keys: any path that is - * sorted by one side will also be sorted by the other (as soon as the - * two rels are joined, that is). Record the key equivalence for future - * use. + * If the clause has a mergejoinable operator, and is not an + * outer-join qualification nor bubbled up due to an outer join, then + * the two sides represent equivalent PathKeyItems for path keys: any + * path that is sorted by one side will also be sorted by the other + * (as soon as the two rels are joined, that is). Record the key + * equivalence for future use. */ if (can_be_equijoin && restrictinfo->mergejoinoperator != InvalidOid) add_equijoined_keys(root, restrictinfo); @@ -569,15 +578,16 @@ process_implied_equality(Query *root, Node *item1, Node *item2, Expr *clause; /* - * Currently, since check_mergejoinable only accepts Var = Var clauses, - * we should only see Var nodes here. Would have to work a little - * harder to locate the right rel(s) if more-general mergejoin clauses - * were accepted. + * Currently, since check_mergejoinable only accepts Var = Var + * clauses, we should only see Var nodes here. Would have to work a + * little harder to locate the right rel(s) if more-general mergejoin + * clauses were accepted. */ Assert(IsA(item1, Var)); irel1 = ((Var *) item1)->varno; Assert(IsA(item2, Var)); irel2 = ((Var *) item2)->varno; + /* * If both vars belong to same rel, we need to look at that rel's * baserestrictinfo list. If different rels, each will have a @@ -593,6 +603,7 @@ process_implied_equality(Query *root, Node *item1, Node *item2, restrictlist = joininfo->jinfo_restrictinfo; } + /* * Scan to see if equality is already known. */ @@ -611,6 +622,7 @@ process_implied_equality(Query *root, Node *item1, Node *item2, (equal(item2, left) && equal(item1, right))) return; /* found a matching clause */ } + /* * This equality is new information, so construct a clause * representing it to add to the query data structures. @@ -620,6 +632,7 @@ process_implied_equality(Query *root, Node *item1, Node *item2, eq_operator = compatible_oper("=", ltype, rtype, true); if (!HeapTupleIsValid(eq_operator)) { + /* * Would it be safe to just not add the equality to the query if * we have no suitable equality operator for the combination of @@ -629,6 +642,7 @@ process_implied_equality(Query *root, Node *item1, Node *item2, typeidTypeName(ltype), typeidTypeName(rtype)); } pgopform = (Form_pg_operator) GETSTRUCT(eq_operator); + /* * Let's just make sure this appears to be a compatible operator. */ @@ -641,21 +655,21 @@ process_implied_equality(Query *root, Node *item1, Node *item2, clause = makeNode(Expr); clause->typeOid = BOOLOID; clause->opType = OP_EXPR; - clause->oper = (Node *) makeOper(oprid(eq_operator), /* opno */ - InvalidOid, /* opid */ - BOOLOID); /* operator result type */ + clause->oper = (Node *) makeOper(oprid(eq_operator), /* opno */ + InvalidOid, /* opid */ + BOOLOID); /* operator result type */ clause->args = makeList2(item1, item2); ReleaseSysCache(eq_operator); /* * Note: we mark the qual "pushed down" to ensure that it can never be - * taken for an original JOIN/ON clause. We also claim it is an outer- - * join clause, which it isn't, but that keeps distribute_qual_to_rels - * from examining the outerjoinsets of the relevant rels (which are no - * longer of interest, but could keep the qual from being pushed down - * to where it should be). It'll also save a useless call to - * add_equijoined keys... + * taken for an original JOIN/ON clause. We also claim it is an + * outer- join clause, which it isn't, but that keeps + * distribute_qual_to_rels from examining the outerjoinsets of the + * relevant rels (which are no longer of interest, but could keep the + * qual from being pushed down to where it should be). It'll also + * save a useless call to add_equijoined keys... */ distribute_qual_to_rels(root, (Node *) clause, true, true, diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index d196e755d6..b2b362e84a 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.63 2001/01/24 19:42:59 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.64 2001/03/22 03:59:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,7 +33,7 @@ static Plan *subplanner(Query *root, List *flat_tlist, - double tuple_fraction); + double tuple_fraction); /*-------------------- @@ -82,7 +82,7 @@ query_planner(Query *root, /* * If the query has an empty join tree, then it's something easy like - * "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly. + * "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly. */ if (root->jointree->fromlist == NIL) { @@ -213,9 +213,9 @@ subplanner(Query *root, foreach(brel, root->base_rel_list) { RelOptInfo *baserel = (RelOptInfo *) lfirst(brel); - int relid = lfirsti(baserel->relids); + int relid = lfirsti(baserel->relids); - if (! ptrMember(baserel, joined_rels)) + if (!ptrMember(baserel, joined_rels)) elog(ERROR, "Internal error: no jointree entry for rel %s (%d)", rt_fetch(relid, root->rtable)->eref->relname, relid); } @@ -334,9 +334,9 @@ subplanner(Query *root, /* * Nothing for it but to sort the cheapest-total-cost path --- but we * let the caller do that. grouping_planner has to be able to add a - * sort node anyway, so no need for extra code here. (Furthermore, the - * given pathkeys might involve something we can't compute here, such - * as an aggregate function...) + * sort node anyway, so no need for extra code here. (Furthermore, + * the given pathkeys might involve something we can't compute here, + * such as an aggregate function...) */ root->query_pathkeys = cheapestpath->pathkeys; resultplan = create_plan(root, cheapestpath); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 9faf6b95e8..c5bd439587 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.101 2001/01/27 04:42:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.102 2001/03/22 03:59:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,9 +33,9 @@ /* Expression kind codes for preprocess_expression */ -#define EXPRKIND_TARGET 0 +#define EXPRKIND_TARGET 0 #define EXPRKIND_WHERE 1 -#define EXPRKIND_HAVING 2 +#define EXPRKIND_HAVING 2 static Node *pull_up_subqueries(Query *parse, Node *jtnode); @@ -68,16 +68,16 @@ planner(Query *parse) /* * The planner can be called recursively (an example is when - * eval_const_expressions tries to pre-evaluate an SQL function). - * So, these global state variables must be saved and restored. + * eval_const_expressions tries to pre-evaluate an SQL function). So, + * these global state variables must be saved and restored. * - * These vars cannot be moved into the Query structure since their - * whole purpose is communication across multiple sub-Queries. + * These vars cannot be moved into the Query structure since their whole + * purpose is communication across multiple sub-Queries. * * Note we do NOT save and restore PlannerPlanId: it exists to assign - * unique IDs to SubPlan nodes, and we want those IDs to be unique - * for the life of a backend. Also, PlannerInitPlan is saved/restored - * in subquery_planner, not here. + * unique IDs to SubPlan nodes, and we want those IDs to be unique for + * the life of a backend. Also, PlannerInitPlan is saved/restored in + * subquery_planner, not here. */ save_PlannerQueryLevel = PlannerQueryLevel; save_PlannerParamVar = PlannerParamVar; @@ -150,6 +150,7 @@ subquery_planner(Query *parse, double tuple_fraction) */ parse->jointree = (FromExpr *) pull_up_subqueries(parse, (Node *) parse->jointree); + /* * If so, we may have created opportunities to simplify the jointree. */ @@ -170,26 +171,26 @@ subquery_planner(Query *parse, double tuple_fraction) /* * A HAVING clause without aggregates is equivalent to a WHERE clause - * (except it can only refer to grouped fields). Transfer any agg-free - * clauses of the HAVING qual into WHERE. This may seem like wasting - * cycles to cater to stupidly-written queries, but there are other - * reasons for doing it. Firstly, if the query contains no aggs at all, - * then we aren't going to generate an Agg plan node, and so there'll be - * no place to execute HAVING conditions; without this transfer, we'd - * lose the HAVING condition entirely, which is wrong. Secondly, when - * we push down a qual condition into a sub-query, it's easiest to push - * the qual into HAVING always, in case it contains aggs, and then let - * this code sort it out. + * (except it can only refer to grouped fields). Transfer any + * agg-free clauses of the HAVING qual into WHERE. This may seem like + * wasting cycles to cater to stupidly-written queries, but there are + * other reasons for doing it. Firstly, if the query contains no aggs + * at all, then we aren't going to generate an Agg plan node, and so + * there'll be no place to execute HAVING conditions; without this + * transfer, we'd lose the HAVING condition entirely, which is wrong. + * Secondly, when we push down a qual condition into a sub-query, it's + * easiest to push the qual into HAVING always, in case it contains + * aggs, and then let this code sort it out. * * Note that both havingQual and parse->jointree->quals are in * implicitly-ANDed-list form at this point, even though they are - * declared as Node *. Also note that contain_agg_clause does not + * declared as Node *. Also note that contain_agg_clause does not * recurse into sub-selects, which is exactly what we need here. */ newHaving = NIL; foreach(lst, (List *) parse->havingQual) { - Node *havingclause = (Node *) lfirst(lst); + Node *havingclause = (Node *) lfirst(lst); if (contain_agg_clause(havingclause)) newHaving = lappend(newHaving, havingclause); @@ -201,30 +202,32 @@ subquery_planner(Query *parse, double tuple_fraction) /* * Do the main planning. If we have an inherited target relation, - * that needs special processing, else go straight to grouping_planner. + * that needs special processing, else go straight to + * grouping_planner. */ if (parse->resultRelation && - (lst = expand_inherted_rtentry(parse, parse->resultRelation)) != NIL) + (lst = expand_inherted_rtentry(parse, parse->resultRelation)) != NIL) plan = inheritance_planner(parse, lst); else plan = grouping_planner(parse, tuple_fraction); /* - * If any subplans were generated, or if we're inside a subplan, - * build subPlan, extParam and locParam lists for plan nodes. + * If any subplans were generated, or if we're inside a subplan, build + * subPlan, extParam and locParam lists for plan nodes. */ if (PlannerPlanId != saved_planid || PlannerQueryLevel > 1) { (void) SS_finalize_plan(plan); + /* - * At the moment, SS_finalize_plan doesn't handle initPlans - * and so we assign them to the topmost plan node. + * At the moment, SS_finalize_plan doesn't handle initPlans and so + * we assign them to the topmost plan node. */ plan->initPlan = PlannerInitPlan; /* Must add the initPlans' extParams to the topmost node's, too */ foreach(lst, plan->initPlan) { - SubPlan *subplan = (SubPlan *) lfirst(lst); + SubPlan *subplan = (SubPlan *) lfirst(lst); plan->extParam = set_unioni(plan->extParam, subplan->plan->extParam); @@ -266,44 +269,47 @@ pull_up_subqueries(Query *parse, Node *jtnode) Query *subquery = rte->subquery; /* - * Is this a subquery RTE, and if so, is the subquery simple enough - * to pull up? (If not, do nothing at this node.) + * Is this a subquery RTE, and if so, is the subquery simple + * enough to pull up? (If not, do nothing at this node.) */ if (subquery && is_simple_subquery(subquery)) { - int rtoffset; - Node *subjointree; - List *subtlist; - List *l; + int rtoffset; + Node *subjointree; + List *subtlist; + List *l; /* - * First, recursively pull up the subquery's subqueries, - * so that this routine's processing is complete for its - * jointree and rangetable. NB: if the same subquery is - * referenced from multiple jointree items (which can't happen - * normally, but might after rule rewriting), then we will invoke - * this processing multiple times on that subquery. OK because + * First, recursively pull up the subquery's subqueries, so + * that this routine's processing is complete for its jointree + * and rangetable. NB: if the same subquery is referenced + * from multiple jointree items (which can't happen normally, + * but might after rule rewriting), then we will invoke this + * processing multiple times on that subquery. OK because * nothing will happen after the first time. We do have to be * careful to copy everything we pull up, however, or risk * having chunks of structure multiply linked. */ subquery->jointree = (FromExpr *) pull_up_subqueries(subquery, (Node *) subquery->jointree); + /* - * Append the subquery's rangetable to mine (currently, - * no adjustments will be needed in the subquery's rtable). + * Append the subquery's rangetable to mine (currently, no + * adjustments will be needed in the subquery's rtable). */ rtoffset = length(parse->rtable); parse->rtable = nconc(parse->rtable, copyObject(subquery->rtable)); + /* - * Make copies of the subquery's jointree and targetlist - * with varnos adjusted to match the merged rangetable. + * Make copies of the subquery's jointree and targetlist with + * varnos adjusted to match the merged rangetable. */ subjointree = copyObject(subquery->jointree); OffsetVarNodes(subjointree, rtoffset, 0); subtlist = copyObject(subquery->targetList); OffsetVarNodes((Node *) subtlist, rtoffset, 0); + /* * Replace all of the top query's references to the subquery's * outputs with copies of the adjusted subtlist items, being @@ -316,16 +322,18 @@ pull_up_subqueries(Query *parse, Node *jtnode) parse->havingQual = ResolveNew(parse->havingQual, varno, 0, subtlist, CMD_SELECT, 0); + /* * Pull up any FOR UPDATE markers, too. */ foreach(l, subquery->rowMarks) { - int submark = lfirsti(l); + int submark = lfirsti(l); parse->rowMarks = lappendi(parse->rowMarks, submark + rtoffset); } + /* * Miscellaneous housekeeping. */ @@ -345,9 +353,7 @@ pull_up_subqueries(Query *parse, Node *jtnode) List *l; foreach(l, f->fromlist) - { lfirst(l) = pull_up_subqueries(parse, lfirst(l)); - } } else if (IsA(jtnode, JoinExpr)) { @@ -370,6 +376,7 @@ pull_up_subqueries(Query *parse, Node *jtnode) static bool is_simple_subquery(Query *subquery) { + /* * Let's just make sure it's a valid subselect ... */ @@ -379,12 +386,14 @@ is_simple_subquery(Query *subquery) subquery->into != NULL || subquery->isPortal) elog(ERROR, "is_simple_subquery: subquery is bogus"); + /* - * Can't currently pull up a query with setops. - * Maybe after querytree redesign... + * Can't currently pull up a query with setops. Maybe after querytree + * redesign... */ if (subquery->setOperations) return false; + /* * Can't pull up a subquery involving grouping, aggregation, sorting, * or limiting. @@ -397,12 +406,13 @@ is_simple_subquery(Query *subquery) subquery->limitOffset || subquery->limitCount) return false; + /* * Hack: don't try to pull up a subquery with an empty jointree. * query_planner() will correctly generate a Result plan for a * jointree that's totally empty, but I don't think the right things - * happen if an empty FromExpr appears lower down in a jointree. - * Not worth working hard on this, just to collapse SubqueryScan/Result + * happen if an empty FromExpr appears lower down in a jointree. Not + * worth working hard on this, just to collapse SubqueryScan/Result * into Result... */ if (subquery->jointree->fromlist == NIL) @@ -443,7 +453,9 @@ resolvenew_in_jointree(Node *jtnode, int varno, List *subtlist) resolvenew_in_jointree(j->rarg, varno, subtlist); j->quals = ResolveNew(j->quals, varno, 0, subtlist, CMD_SELECT, 0); - /* We don't bother to update the colvars list, since it won't be + + /* + * We don't bother to update the colvars list, since it won't be * used again ... */ } @@ -458,13 +470,13 @@ resolvenew_in_jointree(Node *jtnode, int varno, List *subtlist) * * If we succeed in pulling up a subquery then we might form a jointree * in which a FromExpr is a direct child of another FromExpr. In that - * case we can consider collapsing the two FromExprs into one. This is + * case we can consider collapsing the two FromExprs into one. This is * an optional conversion, since the planner will work correctly either * way. But we may find a better plan (at the cost of more planning time) * if we merge the two nodes. * * NOTE: don't try to do this in the same jointree scan that does subquery - * pullup! Since we're changing the jointree structure here, that wouldn't + * pullup! Since we're changing the jointree structure here, that wouldn't * work reliably --- see comments for pull_up_subqueries(). */ static Node * @@ -484,27 +496,29 @@ preprocess_jointree(Query *parse, Node *jtnode) foreach(l, f->fromlist) { - Node *child = (Node *) lfirst(l); + Node *child = (Node *) lfirst(l); /* Recursively simplify the child... */ child = preprocess_jointree(parse, child); /* Now, is it a FromExpr? */ if (child && IsA(child, FromExpr)) { + /* - * Yes, so do we want to merge it into parent? Always do so - * if child has just one element (since that doesn't make the - * parent's list any longer). Otherwise we have to be careful - * about the increase in planning time caused by combining the - * two join search spaces into one. Our heuristic is to merge - * if the merge will produce a join list no longer than - * GEQO_RELS/2. (Perhaps need an additional user parameter?) + * Yes, so do we want to merge it into parent? Always do + * so if child has just one element (since that doesn't + * make the parent's list any longer). Otherwise we have + * to be careful about the increase in planning time + * caused by combining the two join search spaces into + * one. Our heuristic is to merge if the merge will + * produce a join list no longer than GEQO_RELS/2. + * (Perhaps need an additional user parameter?) */ FromExpr *subf = (FromExpr *) child; int childlen = length(subf->fromlist); int myothers = length(newlist) + length(lnext(l)); - if (childlen <= 1 || (childlen+myothers) <= geqo_rels/2) + if (childlen <= 1 || (childlen + myothers) <= geqo_rels / 2) { newlist = nconc(newlist, subf->fromlist); f->quals = make_and_qual(f->quals, subf->quals); @@ -540,6 +554,7 @@ preprocess_jointree(Query *parse, Node *jtnode) static Node * preprocess_expression(Query *parse, Node *expr, int kind) { + /* * Simplify constant expressions. * @@ -551,8 +566,8 @@ preprocess_expression(Query *parse, Node *expr, int kind) expr = eval_const_expressions(expr); /* - * If it's a qual or havingQual, canonicalize it, and convert it - * to implicit-AND format. + * If it's a qual or havingQual, canonicalize it, and convert it to + * implicit-AND format. * * XXX Is there any value in re-applying eval_const_expressions after * canonicalize_qual? @@ -575,10 +590,11 @@ preprocess_expression(Query *parse, Node *expr, int kind) if (kind != EXPRKIND_WHERE && (parse->groupClause != NIL || parse->hasAggs)) { + /* * Check for ungrouped variables passed to subplans. Note we - * do NOT do this for subplans in WHERE (or JOIN/ON); it's legal - * there because WHERE is evaluated pre-GROUP. + * do NOT do this for subplans in WHERE (or JOIN/ON); it's + * legal there because WHERE is evaluated pre-GROUP. */ check_subplans_for_ungrouped_vars(expr, parse); } @@ -635,12 +651,12 @@ preprocess_qual_conditions(Query *parse, Node *jtnode) * inheritance set. * * We have to handle this case differently from cases where a source - * relation is an inheritance set. Source inheritance is expanded at + * relation is an inheritance set. Source inheritance is expanded at * the bottom of the plan tree (see allpaths.c), but target inheritance * has to be expanded at the top. The reason is that for UPDATE, each * target relation needs a different targetlist matching its own column * set. (This is not so critical for DELETE, but for simplicity we treat - * inherited DELETE the same way.) Fortunately, the UPDATE/DELETE target + * inherited DELETE the same way.) Fortunately, the UPDATE/DELETE target * can never be the nullable side of an outer join, so it's OK to generate * the plan this way. * @@ -661,17 +677,17 @@ inheritance_planner(Query *parse, List *inheritlist) foreach(l, inheritlist) { - int childRTindex = lfirsti(l); - Oid childOID = getrelid(childRTindex, parse->rtable); - Query *subquery; - Plan *subplan; + int childRTindex = lfirsti(l); + Oid childOID = getrelid(childRTindex, parse->rtable); + Query *subquery; + Plan *subplan; /* Generate modified query with this rel as target */ subquery = (Query *) adjust_inherited_attrs((Node *) parse, - parentRTindex, parentOID, - childRTindex, childOID); + parentRTindex, parentOID, + childRTindex, childOID); /* Generate plan */ - subplan = grouping_planner(subquery, 0.0 /* retrieve all tuples */); + subplan = grouping_planner(subquery, 0.0 /* retrieve all tuples */ ); subplans = lappend(subplans, subplan); /* Save preprocessed tlist from first rel for use in Append */ if (tlist == NIL) @@ -718,6 +734,7 @@ grouping_planner(Query *parse, double tuple_fraction) if (parse->setOperations) { + /* * Construct the plan for set operations. The result will not * need any work except perhaps a top-level sort and/or LIMIT. @@ -736,17 +753,17 @@ grouping_planner(Query *parse, double tuple_fraction) tlist = postprocess_setop_tlist(result_plan->targetlist, tlist); /* - * Can't handle FOR UPDATE here (parser should have checked already, - * but let's make sure). + * Can't handle FOR UPDATE here (parser should have checked + * already, but let's make sure). */ if (parse->rowMarks) elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT"); /* * We set current_pathkeys NIL indicating we do not know sort - * order. This is correct when the top set operation is UNION ALL, - * since the appended-together results are unsorted even if the - * subplans were sorted. For other set operations we could be + * order. This is correct when the top set operation is UNION + * ALL, since the appended-together results are unsorted even if + * the subplans were sorted. For other set operations we could be * smarter --- room for future improvement! */ current_pathkeys = NIL; @@ -772,22 +789,26 @@ grouping_planner(Query *parse, double tuple_fraction) /* * Add TID targets for rels selected FOR UPDATE (should this be - * done in preprocess_targetlist?). The executor uses the TID - * to know which rows to lock, much as for UPDATE or DELETE. + * done in preprocess_targetlist?). The executor uses the TID to + * know which rows to lock, much as for UPDATE or DELETE. */ if (parse->rowMarks) { List *l; /* - * We've got trouble if the FOR UPDATE appears inside grouping, - * since grouping renders a reference to individual tuple CTIDs - * invalid. This is also checked at parse time, but that's - * insufficient because of rule substitution, query pullup, etc. + * We've got trouble if the FOR UPDATE appears inside + * grouping, since grouping renders a reference to individual + * tuple CTIDs invalid. This is also checked at parse time, + * but that's insufficient because of rule substitution, query + * pullup, etc. */ CheckSelectForUpdate(parse); - /* Currently the executor only supports FOR UPDATE at top level */ + /* + * Currently the executor only supports FOR UPDATE at top + * level + */ if (PlannerQueryLevel > 1) elog(ERROR, "SELECT FOR UPDATE is not allowed in subselects"); @@ -873,9 +894,9 @@ grouping_planner(Query *parse, double tuple_fraction) int32 count = DatumGetInt32(limitc->constvalue); /* - * A NULL-constant LIMIT represents "LIMIT ALL", - * which we treat the same as no limit (ie, - * expect to retrieve all the tuples). + * A NULL-constant LIMIT represents "LIMIT ALL", which + * we treat the same as no limit (ie, expect to + * retrieve all the tuples). */ if (!limitc->constisnull && count > 0) { @@ -902,17 +923,19 @@ grouping_planner(Query *parse, double tuple_fraction) } else { + /* - * COUNT is an expression ... don't know exactly what the - * limit will be, but for lack of a better idea assume - * 10% of the plan's result is wanted. + * COUNT is an expression ... don't know exactly what + * the limit will be, but for lack of a better idea + * assume 10% of the plan's result is wanted. */ tuple_fraction = 0.10; } } /* - * If no LIMIT, check for retrieve-into-portal, ie DECLARE CURSOR. + * If no LIMIT, check for retrieve-into-portal, ie DECLARE + * CURSOR. * * We have no real idea how many tuples the user will ultimately * FETCH from a cursor, but it seems a good bet that he diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 1f2ae69561..e7f8361b9a 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.70 2001/01/24 19:42:59 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.71 2001/03/22 03:59:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -97,16 +97,17 @@ set_plan_references(Plan *plan) fix_expr_references(plan, (Node *) ((IndexScan *) plan)->indxqual); fix_expr_references(plan, - (Node *) ((IndexScan *) plan)->indxqualorig); + (Node *) ((IndexScan *) plan)->indxqualorig); break; case T_TidScan: fix_expr_references(plan, (Node *) plan->targetlist); fix_expr_references(plan, (Node *) plan->qual); break; case T_SubqueryScan: + /* - * We do not do set_uppernode_references() here, because - * a SubqueryScan will always have been created with correct + * We do not do set_uppernode_references() here, because a + * SubqueryScan will always have been created with correct * references to its subplan's outputs to begin with. */ fix_expr_references(plan, (Node *) plan->targetlist); @@ -126,7 +127,7 @@ set_plan_references(Plan *plan) fix_expr_references(plan, (Node *) plan->qual); fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual); fix_expr_references(plan, - (Node *) ((MergeJoin *) plan)->mergeclauses); + (Node *) ((MergeJoin *) plan)->mergeclauses); break; case T_HashJoin: set_join_references((Join *) plan); @@ -134,7 +135,7 @@ set_plan_references(Plan *plan) fix_expr_references(plan, (Node *) plan->qual); fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual); fix_expr_references(plan, - (Node *) ((HashJoin *) plan)->hashclauses); + (Node *) ((HashJoin *) plan)->hashclauses); break; case T_Material: case T_Sort: @@ -148,10 +149,10 @@ set_plan_references(Plan *plan) * targetlists or quals (because they just return their * unmodified input tuples). The optimizer is lazy about * creating really valid targetlists for them. Best to just - * leave the targetlist alone. In particular, we do not want + * leave the targetlist alone. In particular, we do not want * to pull a subplan list for them, since we will likely end - * up with duplicate list entries for subplans that also appear - * in lower levels of the plan tree! + * up with duplicate list entries for subplans that also + * appear in lower levels of the plan tree! */ break; case T_Agg: @@ -175,11 +176,12 @@ set_plan_references(Plan *plan) fix_expr_references(plan, ((Result *) plan)->resconstantqual); break; case T_Append: + /* * Append, like Sort et al, doesn't actually evaluate its - * targetlist or quals, and we haven't bothered to give it - * its own tlist copy. So, don't fix targetlist/qual. - * But do recurse into subplans. + * targetlist or quals, and we haven't bothered to give it its + * own tlist copy. So, don't fix targetlist/qual. But do + * recurse into subplans. */ foreach(pl, ((Append *) plan)->appendplans) set_plan_references((Plan *) lfirst(pl)); @@ -296,7 +298,7 @@ set_uppernode_references(Plan *plan, Index subvarno) subplanTargetList = NIL; outputTargetList = NIL; - foreach (l, plan->targetlist) + foreach(l, plan->targetlist) { TargetEntry *tle = (TargetEntry *) lfirst(l); TargetEntry *subplantle; @@ -306,8 +308,8 @@ set_uppernode_references(Plan *plan, Index subvarno) if (subplantle) { /* Found a matching subplan output expression */ - Resdom *resdom = subplantle->resdom; - Var *newvar; + Resdom *resdom = subplantle->resdom; + Var *newvar; newvar = makeVar(subvarno, resdom->resno, @@ -317,7 +319,7 @@ set_uppernode_references(Plan *plan, Index subvarno) /* If we're just copying a simple Var, copy up original info */ if (subplantle->expr && IsA(subplantle->expr, Var)) { - Var *subvar = (Var *) subplantle->expr; + Var *subvar = (Var *) subplantle->expr; newvar->varnoold = subvar->varnoold; newvar->varoattno = subvar->varoattno; diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 0a7d4926b7..9d47b60430 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.48 2001/01/24 19:42:59 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.49 2001/03/22 03:59:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -82,12 +82,12 @@ replace_var(Var *var) /* * If there's already a PlannerParamVar entry for this same Var, just - * use it. NOTE: in sufficiently complex querytrees, it is - * possible for the same varno/varlevel to refer to different RTEs in - * different parts of the parsetree, so that different fields might - * end up sharing the same Param number. As long as we check the - * vartype as well, I believe that this sort of aliasing will cause no - * trouble. The correct field should get stored into the Param slot at + * use it. NOTE: in sufficiently complex querytrees, it is possible + * for the same varno/varlevel to refer to different RTEs in different + * parts of the parsetree, so that different fields might end up + * sharing the same Param number. As long as we check the vartype as + * well, I believe that this sort of aliasing will cause no trouble. + * The correct field should get stored into the Param slot at * execution in each part of the tree. */ i = 0; @@ -142,10 +142,10 @@ make_subplan(SubLink *slink) elog(ERROR, "make_subplan: invalid expression structure (subquery already processed?)"); /* - * Copy the source Query node. This is a quick and dirty kluge to resolve - * the fact that the parser can generate trees with multiple links to the - * same sub-Query node, but the planner wants to scribble on the Query. - * Try to clean this up when we do querytree redesign... + * Copy the source Query node. This is a quick and dirty kluge to + * resolve the fact that the parser can generate trees with multiple + * links to the same sub-Query node, but the planner wants to scribble + * on the Query. Try to clean this up when we do querytree redesign... */ subquery = (Query *) copyObject(subquery); @@ -183,7 +183,8 @@ make_subplan(SubLink *slink) */ node->plan = plan = subquery_planner(subquery, tuple_fraction); - node->plan_id = PlannerPlanId++; /* Assign unique ID to this SubPlan */ + node->plan_id = PlannerPlanId++; /* Assign unique ID to this + * SubPlan */ node->rtable = subquery->rtable; node->sublink = slink; @@ -191,8 +192,8 @@ make_subplan(SubLink *slink) slink->subselect = NULL; /* cool ?! see error check above! */ /* - * Make parParam list of params that current query level will pass - * to this child plan. + * Make parParam list of params that current query level will pass to + * this child plan. */ foreach(lst, plan->extParam) { @@ -275,7 +276,7 @@ make_subplan(SubLink *slink) tup = SearchSysCache(OPEROID, ObjectIdGetDatum(oper->opno), 0, 0, 0); - if (! HeapTupleIsValid(tup)) + if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for operator %u", oper->opno); opform = (Form_pg_operator) GETSTRUCT(tup); @@ -413,7 +414,7 @@ make_subplan(SubLink *slink) tup = SearchSysCache(OPEROID, ObjectIdGetDatum(oper->opno), 0, 0, 0); - if (! HeapTupleIsValid(tup)) + if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for operator %u", oper->opno); opform = (Form_pg_operator) GETSTRUCT(tup); @@ -614,15 +615,16 @@ SS_finalize_plan(Plan *plan) break; case T_SubqueryScan: + /* - * In a SubqueryScan, SS_finalize_plan has already been run - * on the subplan by the inner invocation of subquery_planner, - * so there's no need to do it again. Instead, just pull out - * the subplan's extParams list, which represents the params - * it needs from my level and higher levels. + * In a SubqueryScan, SS_finalize_plan has already been run on + * the subplan by the inner invocation of subquery_planner, so + * there's no need to do it again. Instead, just pull out the + * subplan's extParams list, which represents the params it + * needs from my level and higher levels. */ results.paramids = set_unioni(results.paramids, - ((SubqueryScan *) plan)->subplan->extParam); + ((SubqueryScan *) plan)->subplan->extParam); break; case T_IndexScan: |
