diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-02 21:32:01 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-02 21:32:01 +0000 |
commit | 951130475221562b44b0da575fac8470adb5b555 (patch) | |
tree | 5dc2ac24a5381a2ff1c2f25e1d14430b66558c02 /src/backend/optimizer/plan/createplan.c | |
parent | 49f001d81ed635747c4439f38ae1fc6090887452 (diff) | |
download | postgresql-951130475221562b44b0da575fac8470adb5b555.tar.gz postgresql-951130475221562b44b0da575fac8470adb5b555.zip |
Rearrange the querytree representation of ORDER BY/GROUP BY/DISTINCT items
as per my recent proposal:
1. Fold SortClause and GroupClause into a single node type SortGroupClause.
We were already relying on them to be struct-equivalent, so using two node
tags wasn't accomplishing much except to get in the way of comparing items
with equal().
2. Add an "eqop" field to SortGroupClause to carry the associated equality
operator. This is cheap for the parser to get at the same time it's looking
up the sort operator, and storing it eliminates the need for repeated
not-so-cheap lookups during planning. In future this will also let us
represent GROUP/DISTINCT operations on datatypes that have hash opclasses
but no btree opclasses (ie, they have equality but no natural sort order).
The previous representation simply didn't work for that, since its only
indicator of comparison semantics was a sort operator.
3. Add a hasDistinctOn boolean to struct Query to explicitly record whether
the distinctClause came from DISTINCT or DISTINCT ON. This allows removing
some complicated and not 100% bulletproof code that attempted to figure
that out from the distinctClause alone.
This patch doesn't in itself create any new capability, but it's necessary
infrastructure for future attempts to use hash-based grouping for DISTINCT
and UNION/INTERSECT/EXCEPT.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 0884cda6070..80b6ed2edfe 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.241 2008/06/27 03:56:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.242 2008/08/02 21:32:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -760,7 +760,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) Oid in_oper = lfirst_oid(l); Oid sortop; TargetEntry *tle; - SortClause *sortcl; + SortGroupClause *sortcl; sortop = get_ordering_op_for_equality_op(in_oper, false); if (!OidIsValid(sortop)) /* shouldn't happen */ @@ -769,9 +769,10 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) tle = get_tle_by_resno(subplan->targetlist, groupColIdx[groupColPos]); Assert(tle != NULL); - sortcl = makeNode(SortClause); + sortcl = makeNode(SortGroupClause); sortcl->tleSortGroupRef = assignSortGroupRef(tle, subplan->targetlist); + sortcl->eqop = in_oper; sortcl->sortop = sortop; sortcl->nulls_first = false; sortList = lappend(sortList, sortcl); @@ -2531,6 +2532,8 @@ add_sort_column(AttrNumber colIdx, Oid sortOp, bool nulls_first, { int i; + Assert(OidIsValid(sortOp)); + for (i = 0; i < numCols; i++) { /* @@ -2753,7 +2756,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, * make_sort_from_sortclauses * Create sort plan to sort according to given sortclauses * - * 'sortcls' is a list of SortClauses + * 'sortcls' is a list of SortGroupClauses * 'lefttree' is the node which yields input tuples */ Sort * @@ -2778,7 +2781,7 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree) foreach(l, sortcls) { - SortClause *sortcl = (SortClause *) lfirst(l); + SortGroupClause *sortcl = (SortGroupClause *) lfirst(l); TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist); /* @@ -2802,14 +2805,14 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree) * make_sort_from_groupcols * Create sort plan to sort based on grouping columns * - * 'groupcls' is the list of GroupClauses + * 'groupcls' is the list of SortGroupClauses * 'grpColIdx' gives the column numbers to use * * 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 sort ordering info - * is used from the GroupClause entries. + * is used from the SortGroupClause entries. */ Sort * make_sort_from_groupcols(PlannerInfo *root, @@ -2837,7 +2840,7 @@ make_sort_from_groupcols(PlannerInfo *root, foreach(l, groupcls) { - GroupClause *grpcl = (GroupClause *) lfirst(l); + SortGroupClause *grpcl = (SortGroupClause *) lfirst(l); TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[grpno]); /* @@ -3038,7 +3041,7 @@ make_group(PlannerInfo *root, } /* - * distinctList is a list of SortClauses, identifying the targetlist items + * distinctList is a list of SortGroupClauses, identifying the targetlist items * that should be considered by the Unique filter. The input path must * already be sorted accordingly. */ @@ -3074,7 +3077,7 @@ make_unique(Plan *lefttree, List *distinctList) plan->righttree = NULL; /* - * convert SortClause list into arrays of attr indexes and equality + * convert SortGroupClause list into arrays of attr indexes and equality * operators, as wanted by executor */ Assert(numCols > 0); @@ -3083,14 +3086,12 @@ make_unique(Plan *lefttree, List *distinctList) foreach(slitem, distinctList) { - SortClause *sortcl = (SortClause *) lfirst(slitem); + SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem); TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist); uniqColIdx[keyno] = tle->resno; - uniqOperators[keyno] = get_equality_op_for_ordering_op(sortcl->sortop); - if (!OidIsValid(uniqOperators[keyno])) /* shouldn't happen */ - elog(ERROR, "could not find equality operator for ordering operator %u", - sortcl->sortop); + uniqOperators[keyno] = sortcl->eqop; + Assert(OidIsValid(uniqOperators[keyno])); keyno++; } @@ -3102,8 +3103,8 @@ make_unique(Plan *lefttree, List *distinctList) } /* - * distinctList is a list of SortClauses, identifying the targetlist items - * that should be considered by the SetOp filter. The input path must + * distinctList is a list of SortGroupClauses, identifying the targetlist + * items that should be considered by the SetOp filter. The input path must * already be sorted accordingly. */ SetOp * @@ -3140,7 +3141,7 @@ make_setop(SetOpCmd cmd, Plan *lefttree, plan->righttree = NULL; /* - * convert SortClause list into arrays of attr indexes and equality + * convert SortGroupClause list into arrays of attr indexes and equality * operators, as wanted by executor */ Assert(numCols > 0); @@ -3149,14 +3150,12 @@ make_setop(SetOpCmd cmd, Plan *lefttree, foreach(slitem, distinctList) { - SortClause *sortcl = (SortClause *) lfirst(slitem); + SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem); TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist); dupColIdx[keyno] = tle->resno; - dupOperators[keyno] = get_equality_op_for_ordering_op(sortcl->sortop); - if (!OidIsValid(dupOperators[keyno])) /* shouldn't happen */ - elog(ERROR, "could not find equality operator for ordering operator %u", - sortcl->sortop); + dupOperators[keyno] = sortcl->eqop; + Assert(OidIsValid(dupOperators[keyno])); keyno++; } |