diff options
Diffstat (limited to 'src/backend/optimizer/prep/prepunion.c')
-rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 189 |
1 files changed, 94 insertions, 95 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index c8e9309354a..dc7d94e1c6c 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.126 2005/08/02 20:27:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.127 2005/10/15 02:49:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -51,19 +51,19 @@ typedef struct } adjust_inherited_attrs_context; static Plan *recurse_set_operations(Node *setOp, PlannerInfo *root, - double tuple_fraction, - List *colTypes, bool junkOK, - int flag, List *refnames_tlist, - List **sortClauses); + double tuple_fraction, + List *colTypes, bool junkOK, + int flag, List *refnames_tlist, + List **sortClauses); static Plan *generate_union_plan(SetOperationStmt *op, PlannerInfo *root, - double tuple_fraction, - List *refnames_tlist, List **sortClauses); + double tuple_fraction, + List *refnames_tlist, List **sortClauses); static Plan *generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root, List *refnames_tlist, List **sortClauses); static List *recurse_union_children(Node *setOp, PlannerInfo *root, - double tuple_fraction, - SetOperationStmt *top_union, - List *refnames_tlist); + double tuple_fraction, + SetOperationStmt *top_union, + List *refnames_tlist); static List *generate_setop_tlist(List *colTypes, int flag, Index varno, bool hack_constants, @@ -117,8 +117,8 @@ plan_set_operations(PlannerInfo *root, double tuple_fraction, Assert(parse->distinctClause == NIL); /* - * Find the leftmost component Query. We need to use its column names - * for all generated tlists (else SELECT INTO won't work right). + * Find the leftmost component Query. We need to use its column names for + * all generated tlists (else SELECT INTO won't work right). */ node = topop->larg; while (node && IsA(node, SetOperationStmt)) @@ -129,10 +129,10 @@ plan_set_operations(PlannerInfo *root, double tuple_fraction, Assert(leftmostQuery != NULL); /* - * Recurse on setOperations tree to generate plans for set ops. The - * final output plan should have just the column types shown as the - * output from the top-level node, plus possibly resjunk working - * columns (we can rely on upper-level nodes to deal with that). + * Recurse on setOperations tree to generate plans for set ops. The final + * output plan should have just the column types shown as the output from + * the top-level node, plus possibly resjunk working columns (we can rely + * on upper-level nodes to deal with that). */ return recurse_set_operations((Node *) topop, root, tuple_fraction, topop->colTypes, true, -1, @@ -187,8 +187,8 @@ recurse_set_operations(Node *setOp, PlannerInfo *root, subplan); /* - * We don't bother to determine the subquery's output ordering - * since it won't be reflected in the set-op result anyhow. + * We don't bother to determine the subquery's output ordering since + * it won't be reflected in the set-op result anyhow. */ *sortClauses = NIL; @@ -214,13 +214,13 @@ recurse_set_operations(Node *setOp, PlannerInfo *root, * output columns. * * XXX you don't really want to know about this: setrefs.c will apply - * replace_vars_with_subplan_refs() to the Result node's tlist. - * This would fail if the Vars generated by generate_setop_tlist() - * were not exactly equal() to the corresponding tlist entries of - * the subplan. However, since the subplan was generated by - * generate_union_plan() or generate_nonunion_plan(), and hence - * its tlist was generated by generate_append_tlist(), this will - * work. We just tell generate_setop_tlist() to use varno 0. + * replace_vars_with_subplan_refs() to the Result node's tlist. This + * would fail if the Vars generated by generate_setop_tlist() were not + * exactly equal() to the corresponding tlist entries of the subplan. + * However, since the subplan was generated by generate_union_plan() + * or generate_nonunion_plan(), and hence its tlist was generated by + * generate_append_tlist(), this will work. We just tell + * generate_setop_tlist() to use varno 0. */ if (flag >= 0 || !tlist_same_datatypes(plan->targetlist, colTypes, junkOK)) @@ -260,22 +260,22 @@ generate_union_plan(SetOperationStmt *op, PlannerInfo *root, /* * If plain UNION, tell children to fetch all tuples. * - * Note: in UNION ALL, we pass the top-level tuple_fraction unmodified - * to each arm of the UNION ALL. One could make a case for reducing - * the tuple fraction for later arms (discounting by the expected size - * of the earlier arms' results) but it seems not worth the trouble. - * The normal case where tuple_fraction isn't already zero is a LIMIT - * at top level, and passing it down as-is is usually enough to get the - * desired result of preferring fast-start plans. + * Note: in UNION ALL, we pass the top-level tuple_fraction unmodified to + * each arm of the UNION ALL. One could make a case for reducing the + * tuple fraction for later arms (discounting by the expected size of the + * earlier arms' results) but it seems not worth the trouble. The normal + * case where tuple_fraction isn't already zero is a LIMIT at top level, + * and passing it down as-is is usually enough to get the desired result + * of preferring fast-start plans. */ if (!op->all) tuple_fraction = 0.0; /* - * If any of my children are identical UNION nodes (same op, all-flag, - * and colTypes) then they can be merged into this node so that we - * generate only one Append and Sort for the lot. Recurse to find - * such nodes and compute their children's plans. + * If any of my children are identical UNION nodes (same op, all-flag, and + * colTypes) then they can be merged into this node so that we generate + * only one Append and Sort for the lot. Recurse to find such nodes and + * compute their children's plans. */ planlist = list_concat(recurse_union_children(op->larg, root, tuple_fraction, @@ -288,8 +288,8 @@ generate_union_plan(SetOperationStmt *op, PlannerInfo *root, * Generate tlist for Append plan node. * * The tlist for an Append plan isn't important as far as the Append is - * concerned, but we must make it look real anyway for the benefit of - * the next plan level up. + * concerned, but we must make it look real anyway for the benefit of the + * next plan level up. */ tlist = generate_append_tlist(op->colTypes, false, planlist, refnames_tlist); @@ -300,8 +300,8 @@ generate_union_plan(SetOperationStmt *op, PlannerInfo *root, plan = (Plan *) make_append(planlist, false, tlist); /* - * For UNION ALL, we just need the Append plan. For UNION, need to - * add Sort and Unique nodes to produce unique output. + * For UNION ALL, we just need the Append plan. For UNION, need to add + * Sort and Unique nodes to produce unique output. */ if (!op->all) { @@ -340,12 +340,12 @@ generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root, /* Recurse on children, ensuring their outputs are marked */ lplan = recurse_set_operations(op->larg, root, - 0.0 /* all tuples needed */, + 0.0 /* all tuples needed */ , op->colTypes, false, 0, refnames_tlist, &child_sortclauses); rplan = recurse_set_operations(op->rarg, root, - 0.0 /* all tuples needed */, + 0.0 /* all tuples needed */ , op->colTypes, false, 1, refnames_tlist, &child_sortclauses); @@ -355,10 +355,10 @@ generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root, * Generate tlist for Append plan node. * * The tlist for an Append plan isn't important as far as the Append is - * concerned, but we must make it look real anyway for the benefit of - * the next plan level up. In fact, it has to be real enough that the - * flag column is shown as a variable not a constant, else setrefs.c - * will get confused. + * concerned, but we must make it look real anyway for the benefit of the + * next plan level up. In fact, it has to be real enough that the flag + * column is shown as a variable not a constant, else setrefs.c will get + * confused. */ tlist = generate_append_tlist(op->colTypes, true, planlist, refnames_tlist); @@ -439,12 +439,11 @@ recurse_union_children(Node *setOp, PlannerInfo *root, /* * Not same, so plan this child separately. * - * Note we disallow any resjunk columns in child results. This is - * necessary since the Append node that implements the union won't do - * any projection, and upper levels will get confused if some of our - * output tuples have junk and some don't. This case only arises when - * we have an EXCEPT or INTERSECT as child, else there won't be - * resjunk anyway. + * Note we disallow any resjunk columns in child results. This is necessary + * since the Append node that implements the union won't do any + * projection, and upper levels will get confused if some of our output + * tuples have junk and some don't. This case only arises when we have an + * EXCEPT or INTERSECT as child, else there won't be resjunk anyway. */ return list_make1(recurse_set_operations(setOp, root, tuple_fraction, @@ -492,17 +491,17 @@ generate_setop_tlist(List *colTypes, int flag, Assert(!reftle->resjunk); /* - * Generate columns referencing input columns and having - * appropriate data types and column names. Insert datatype - * coercions where necessary. + * Generate columns referencing input columns and having appropriate + * data types and column names. Insert datatype coercions where + * necessary. * - * HACK: constants in the input's targetlist are copied up as-is - * rather than being referenced as subquery outputs. This is - * mainly to ensure that when we try to coerce them to the output - * column's datatype, the right things happen for UNKNOWN - * constants. But do this only at the first level of - * subquery-scan plans; we don't want phony constants appearing in - * the output tlists of upper-level nodes! + * HACK: constants in the input's targetlist are copied up as-is rather + * than being referenced as subquery outputs. This is mainly to + * ensure that when we try to coerce them to the output column's + * datatype, the right things happen for UNKNOWN constants. But do + * this only at the first level of subquery-scan plans; we don't want + * phony constants appearing in the output tlists of upper-level + * nodes! */ if (hack_constants && inputtle->expr && IsA(inputtle->expr, Const)) expr = (Node *) inputtle->expr; @@ -710,7 +709,7 @@ find_all_inheritors(Oid parentrel) List *rels_list; ListCell *l; - /* + /* * We build a list starting with the given rel and adding all direct and * indirect children. We can use a single list as both the record of * already-found rels and the agenda of rels yet to be scanned for more @@ -728,11 +727,11 @@ find_all_inheritors(Oid parentrel) currentchildren = find_inheritance_children(currentrel); /* - * Add to the queue only those children not already seen. This - * avoids making duplicate entries in case of multiple inheritance - * paths from the same parent. (It'll also keep us from getting - * into an infinite loop, though theoretically there can't be any - * cycles in the inheritance graph anyway.) + * Add to the queue only those children not already seen. This avoids + * making duplicate entries in case of multiple inheritance paths from + * the same parent. (It'll also keep us from getting into an infinite + * loop, though theoretically there can't be any cycles in the + * inheritance graph anyway.) */ rels_list = list_concat_unique_oid(rels_list, currentchildren); } @@ -790,8 +789,8 @@ expand_inherited_rtentry(PlannerInfo *root, Index rti) /* * Check that there's at least one descendant, else treat as no-child - * case. This could happen despite above has_subclass() check, if - * table once had a child but no longer does. + * case. This could happen despite above has_subclass() check, if table + * once had a child but no longer does. */ if (list_length(inhOIDs) < 2) { @@ -809,19 +808,19 @@ expand_inherited_rtentry(PlannerInfo *root, Index rti) Index childRTindex; /* - * It is possible that the parent table has children that are - * temp tables of other backends. We cannot safely access such - * tables (because of buffering issues), and the best thing to do - * seems to be to silently ignore them. + * It is possible that the parent table has children that are temp + * tables of other backends. We cannot safely access such tables + * (because of buffering issues), and the best thing to do seems to be + * to silently ignore them. */ if (childOID != parentOID && isOtherTempNamespace(get_rel_namespace(childOID))) continue; /* - * Build an RTE for the child, and attach to query's rangetable - * list. We copy most fields of the parent's RTE, but replace - * relation OID, and set inh = false. + * Build an RTE for the child, and attach to query's rangetable list. + * We copy most fields of the parent's RTE, but replace relation OID, + * and set inh = false. */ childrte = copyObject(rte); childrte->relid = childOID; @@ -833,7 +832,8 @@ expand_inherited_rtentry(PlannerInfo *root, Index rti) /* * If all the children were temp tables, pretend it's a non-inheritance - * situation. The duplicate RTE we added for the parent table is harmless. + * situation. The duplicate RTE we added for the parent table is + * harmless. */ if (list_length(inhRTIs) < 2) { @@ -843,11 +843,11 @@ expand_inherited_rtentry(PlannerInfo *root, Index rti) } /* - * The executor will check the parent table's access permissions when - * it examines the parent's inheritlist entry. There's no need to - * check twice, so turn off access check bits in the original RTE. - * (If we are invoked more than once, extra copies of the child RTEs - * will also not cause duplicate permission checks.) + * The executor will check the parent table's access permissions when it + * examines the parent's inheritlist entry. There's no need to check + * twice, so turn off access check bits in the original RTE. (If we are + * invoked more than once, extra copies of the child RTEs will also not + * cause duplicate permission checks.) */ rte->requiredPerms = 0; @@ -882,9 +882,8 @@ adjust_inherited_attrs(Node *node, } /* - * We assume that by now the planner has acquired at least - * AccessShareLock on both rels, and so we need no additional lock - * now. + * We assume that by now the planner has acquired at least AccessShareLock + * on both rels, and so we need no additional lock now. */ oldrelation = heap_open(old_relid, NoLock); newrelation = heap_open(new_relid, NoLock); @@ -1035,7 +1034,7 @@ adjust_inherited_attrs_mutator(Node *node, JoinExpr *j; j = (JoinExpr *) expression_tree_mutator(node, - adjust_inherited_attrs_mutator, + adjust_inherited_attrs_mutator, (void *) context); /* now fix JoinExpr's rtindex */ if (j->rtindex == context->old_rt_index) @@ -1048,8 +1047,8 @@ adjust_inherited_attrs_mutator(Node *node, InClauseInfo *ininfo; ininfo = (InClauseInfo *) expression_tree_mutator(node, - adjust_inherited_attrs_mutator, - (void *) context); + adjust_inherited_attrs_mutator, + (void *) context); /* now fix InClauseInfo's relid sets */ ininfo->lefthand = adjust_relid_set(ininfo->lefthand, context->old_rt_index, @@ -1119,10 +1118,10 @@ adjust_inherited_attrs_mutator(Node *node, /* * BUT: although we don't need to recurse into subplans, we do need to * make sure that they are copied, not just referenced as - * expression_tree_mutator will do by default. Otherwise we'll have - * the same subplan node referenced from each arm of the inheritance - * APPEND plan, which will cause trouble in the executor. This is a - * kluge that should go away when we redesign querytrees. + * expression_tree_mutator will do by default. Otherwise we'll have the + * same subplan node referenced from each arm of the inheritance APPEND + * plan, which will cause trouble in the executor. This is a kluge that + * should go away when we redesign querytrees. */ if (is_subplan(node)) { @@ -1205,8 +1204,8 @@ adjust_inherited_tlist(List *tlist, /* * If we changed anything, re-sort the tlist by resno, and make sure * resjunk entries have resnos above the last real resno. The sort - * algorithm is a bit stupid, but for such a seldom-taken path, small - * is probably better than fast. + * algorithm is a bit stupid, but for such a seldom-taken path, small is + * probably better than fast. */ if (!changed_it) return tlist; |