*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.108 2004/01/18 00:50:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.109 2004/04/07 18:17:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static Plan *recurse_set_operations(Node *setOp, Query *parse,
List *colTypes, bool junkOK,
- int flag, List *refnames_tlist);
+ int flag, List *refnames_tlist,
+ List **sortClauses);
static Plan *generate_union_plan(SetOperationStmt *op, Query *parse,
- List *refnames_tlist);
+ List *refnames_tlist, List **sortClauses);
static Plan *generate_nonunion_plan(SetOperationStmt *op, Query *parse,
- List *refnames_tlist);
+ List *refnames_tlist, List **sortClauses);
static List *recurse_union_children(Node *setOp, Query *parse,
SetOperationStmt *top_union,
List *refnames_tlist);
* This routine only deals with the setOperations tree of the given query.
* Any top-level ORDER BY requested in parse->sortClause will be added
* when we return to grouping_planner.
+ *
+ * *sortClauses is an output argument: it is set to a list of SortClauses
+ * representing the result ordering of the topmost set operation.
*/
Plan *
-plan_set_operations(Query *parse)
+plan_set_operations(Query *parse, List **sortClauses)
{
SetOperationStmt *topop = (SetOperationStmt *) parse->setOperations;
Node *node;
*/
return recurse_set_operations((Node *) topop, parse,
topop->colTypes, true, -1,
- leftmostQuery->targetList);
+ leftmostQuery->targetList,
+ sortClauses);
}
/*
* junkOK: if true, child resjunk columns may be left in the result
* flag: if >= 0, add a resjunk output column indicating value of flag
* refnames_tlist: targetlist to take column names from
+ * *sortClauses: receives list of SortClauses for result plan, if any
*/
static Plan *
recurse_set_operations(Node *setOp, Query *parse,
List *colTypes, bool junkOK,
- int flag, List *refnames_tlist)
+ int flag, List *refnames_tlist,
+ List **sortClauses)
{
if (IsA(setOp, RangeTblRef))
{
NIL,
rtr->rtindex,
subplan);
+
+ /*
+ * 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;
+
return plan;
}
else if (IsA(setOp, SetOperationStmt))
/* UNIONs are much different from INTERSECT/EXCEPT */
if (op->op == SETOP_UNION)
- plan = generate_union_plan(op, parse, refnames_tlist);
+ plan = generate_union_plan(op, parse, refnames_tlist,
+ sortClauses);
else
- plan = generate_nonunion_plan(op, parse, refnames_tlist);
+ plan = generate_nonunion_plan(op, parse, refnames_tlist,
+ sortClauses);
/*
* If necessary, add a Result node to project the caller-requested
*/
static Plan *
generate_union_plan(SetOperationStmt *op, Query *parse,
- List *refnames_tlist)
+ List *refnames_tlist,
+ List **sortClauses)
{
List *planlist;
List *tlist;
sortList = addAllTargetsToSortList(NULL, NIL, tlist, false);
plan = (Plan *) make_sort_from_sortclauses(parse, sortList, plan);
plan = (Plan *) make_unique(plan, sortList);
+ *sortClauses = sortList;
}
+ else
+ *sortClauses = NIL;
+
return plan;
}
*/
static Plan *
generate_nonunion_plan(SetOperationStmt *op, Query *parse,
- List *refnames_tlist)
+ List *refnames_tlist,
+ List **sortClauses)
{
Plan *lplan,
*rplan,
*plan;
List *tlist,
*sortList,
- *planlist;
+ *planlist,
+ *child_sortclauses;
SetOpCmd cmd;
/* Recurse on children, ensuring their outputs are marked */
lplan = recurse_set_operations(op->larg, parse,
op->colTypes, false, 0,
- refnames_tlist);
+ refnames_tlist,
+ &child_sortclauses);
rplan = recurse_set_operations(op->rarg, parse,
op->colTypes, false, 1,
- refnames_tlist);
+ refnames_tlist,
+ &child_sortclauses);
planlist = makeList2(lplan, rplan);
/*
break;
}
plan = (Plan *) make_setop(cmd, plan, sortList, length(op->colTypes) + 1);
+
+ *sortClauses = sortList;
+
return plan;
}
SetOperationStmt *top_union,
List *refnames_tlist)
{
+ List *child_sortclauses;
+
if (IsA(setOp, SetOperationStmt))
{
SetOperationStmt *op = (SetOperationStmt *) setOp;
*/
return makeList1(recurse_set_operations(setOp, parse,
top_union->colTypes, false,
- -1, refnames_tlist));
+ -1, refnames_tlist,
+ &child_sortclauses));
}
/*