summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 7328f41a399..8f1d8e81cc4 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.219 2007/01/05 22:19:31 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.220 2007/01/09 02:14:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -117,7 +117,7 @@ static MergeJoin *make_mergejoin(List *tlist,
Plan *lefttree, Plan *righttree,
JoinType jointype);
static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
- AttrNumber *sortColIdx, Oid *sortOperators);
+ AttrNumber *sortColIdx, Oid *sortOperators, bool *nullsFirst);
static Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree,
List *pathkeys);
@@ -734,7 +734,9 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path)
Assert(tle != NULL);
sortList = addTargetToSortList(NULL, tle,
sortList, subplan->targetlist,
- SORTBY_ASC, NIL, false);
+ SORTBY_DEFAULT,
+ SORTBY_NULLS_DEFAULT,
+ NIL, false);
}
plan = (Plan *) make_sort_from_sortclauses(root, sortList, subplan);
plan = (Plan *) make_unique(plan, sortList);
@@ -2359,11 +2361,12 @@ make_mergejoin(List *tlist,
/*
* make_sort --- basic routine to build a Sort plan node
*
- * Caller must have built the sortColIdx and sortOperators arrays already.
+ * Caller must have built the sortColIdx, sortOperators, and nullsFirst
+ * arrays already.
*/
static Sort *
make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
- AttrNumber *sortColIdx, Oid *sortOperators)
+ AttrNumber *sortColIdx, Oid *sortOperators, bool *nullsFirst)
{
Sort *node = makeNode(Sort);
Plan *plan = &node->plan;
@@ -2383,6 +2386,7 @@ make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
node->numCols = numCols;
node->sortColIdx = sortColIdx;
node->sortOperators = sortOperators;
+ node->nullsFirst = nullsFirst;
return node;
}
@@ -2397,14 +2401,23 @@ make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
* max possible number of columns. Return value is the new column count.
*/
static int
-add_sort_column(AttrNumber colIdx, Oid sortOp,
- int numCols, AttrNumber *sortColIdx, Oid *sortOperators)
+add_sort_column(AttrNumber colIdx, Oid sortOp, bool nulls_first,
+ int numCols, AttrNumber *sortColIdx,
+ Oid *sortOperators, bool *nullsFirst)
{
int i;
for (i = 0; i < numCols; i++)
{
- if (sortColIdx[i] == colIdx)
+ /*
+ * Note: we check sortOp because it's conceivable that "ORDER BY
+ * foo USING <, foo USING <<<" is not redundant, if <<< distinguishes
+ * values that < considers equal. We need not check nulls_first
+ * however because a lower-order column with the same sortop but
+ * opposite nulls direction is redundant.
+ */
+ if (sortColIdx[i] == colIdx &&
+ sortOperators[numCols] == sortOp)
{
/* Already sorting by this col, so extra sort key is useless */
return numCols;
@@ -2414,6 +2427,7 @@ add_sort_column(AttrNumber colIdx, Oid sortOp,
/* Add the column */
sortColIdx[numCols] = colIdx;
sortOperators[numCols] = sortOp;
+ nullsFirst[numCols] = nulls_first;
return numCols + 1;
}
@@ -2441,6 +2455,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys)
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ bool *nullsFirst;
/*
* We will need at most list_length(pathkeys) sort columns; possibly less
@@ -2448,6 +2463,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys)
numsortkeys = list_length(pathkeys);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -2527,13 +2543,15 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys)
* So enter it only once in the sort arrays.
*/
numsortkeys = add_sort_column(tle->resno, pathkey->sortop,
- numsortkeys, sortColIdx, sortOperators);
+ pathkey->nulls_first,
+ numsortkeys,
+ sortColIdx, sortOperators, nullsFirst);
}
Assert(numsortkeys > 0);
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators);
+ sortColIdx, sortOperators, nullsFirst);
}
/*
@@ -2551,6 +2569,7 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ bool *nullsFirst;
/*
* We will need at most list_length(sortcls) sort columns; possibly less
@@ -2558,6 +2577,7 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
numsortkeys = list_length(sortcls);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -2572,13 +2592,15 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
* redundantly.
*/
numsortkeys = add_sort_column(tle->resno, sortcl->sortop,
- numsortkeys, sortColIdx, sortOperators);
+ sortcl->nulls_first,
+ numsortkeys,
+ sortColIdx, sortOperators, nullsFirst);
}
Assert(numsortkeys > 0);
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators);
+ sortColIdx, sortOperators, nullsFirst);
}
/*
@@ -2591,8 +2613,8 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
* This might look like it could be merged with make_sort_from_sortclauses,
* but presently we *must* use the grpColIdx[] array to locate sort columns,
* because the child plan's tlist is not marked with ressortgroupref info
- * appropriate to the grouping node. So, only the sortop is used from the
- * GroupClause entries.
+ * appropriate to the grouping node. So, only the sort direction info
+ * is used from the GroupClause entries.
*/
Sort *
make_sort_from_groupcols(PlannerInfo *root,
@@ -2606,6 +2628,7 @@ make_sort_from_groupcols(PlannerInfo *root,
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ bool *nullsFirst;
/*
* We will need at most list_length(groupcls) sort columns; possibly less
@@ -2613,6 +2636,7 @@ make_sort_from_groupcols(PlannerInfo *root,
numsortkeys = list_length(groupcls);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -2627,14 +2651,16 @@ make_sort_from_groupcols(PlannerInfo *root,
* redundantly.
*/
numsortkeys = add_sort_column(tle->resno, grpcl->sortop,
- numsortkeys, sortColIdx, sortOperators);
+ grpcl->nulls_first,
+ numsortkeys,
+ sortColIdx, sortOperators, nullsFirst);
grpno++;
}
Assert(numsortkeys > 0);
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators);
+ sortColIdx, sortOperators, nullsFirst);
}
Material *
@@ -2871,7 +2897,6 @@ make_unique(Plan *lefttree, List *distinctList)
* distinctList is a list of SortClauses, identifying the targetlist items
* that should be considered by the SetOp filter.
*/
-
SetOp *
make_setop(SetOpCmd cmd, Plan *lefttree,
List *distinctList, AttrNumber flagColIdx)