aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/pathnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/pathnode.c')
-rw-r--r--src/backend/optimizer/util/pathnode.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index c5b6c2ed610..ad3c10ac27b 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.143 2008/04/21 20:54:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.144 2008/08/02 21:32:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -935,8 +935,10 @@ translate_sub_tlist(List *tlist, int relid)
* corresponding upper-level equality operators listed in opids would think
* the values are distinct. (Note: the opids entries could be cross-type
* operators, and thus not exactly the equality operators that the subquery
- * would use itself. We assume that the subquery is compatible if these
- * operators appear in the same btree opfamily as the ones the subquery uses.)
+ * would use itself. We use equality_ops_are_compatible() to check
+ * compatibility. That looks at btree or hash opfamily membership, and so
+ * should give trustworthy answers for all operators that we might need
+ * to deal with here.)
*/
static bool
query_is_distinct_for(Query *query, List *colnos, List *opids)
@@ -955,13 +957,13 @@ query_is_distinct_for(Query *query, List *colnos, List *opids)
{
foreach(l, query->distinctClause)
{
- SortClause *scl = (SortClause *) lfirst(l);
- TargetEntry *tle = get_sortgroupclause_tle(scl,
+ SortGroupClause *sgc = (SortGroupClause *) lfirst(l);
+ TargetEntry *tle = get_sortgroupclause_tle(sgc,
query->targetList);
opid = distinct_col_search(tle->resno, colnos, opids);
if (!OidIsValid(opid) ||
- !ops_in_same_btree_opfamily(opid, scl->sortop))
+ !equality_ops_are_compatible(opid, sgc->eqop))
break; /* exit early if no match */
}
if (l == NULL) /* had matches for all? */
@@ -976,13 +978,13 @@ query_is_distinct_for(Query *query, List *colnos, List *opids)
{
foreach(l, query->groupClause)
{
- GroupClause *grpcl = (GroupClause *) lfirst(l);
- TargetEntry *tle = get_sortgroupclause_tle(grpcl,
+ SortGroupClause *sgc = (SortGroupClause *) lfirst(l);
+ TargetEntry *tle = get_sortgroupclause_tle(sgc,
query->targetList);
opid = distinct_col_search(tle->resno, colnos, opids);
if (!OidIsValid(opid) ||
- !ops_in_same_btree_opfamily(opid, grpcl->sortop))
+ !equality_ops_are_compatible(opid, sgc->eqop))
break; /* exit early if no match */
}
if (l == NULL) /* had matches for all? */
@@ -1002,10 +1004,11 @@ query_is_distinct_for(Query *query, List *colnos, List *opids)
* UNION, INTERSECT, EXCEPT guarantee uniqueness of the whole output row,
* except with ALL.
*
- * XXX this code knows that prepunion.c will adopt the default ordering
- * operator for each column datatype as the sortop. It'd probably be
- * better if these operators were chosen at parse time and stored into the
- * parsetree, instead of leaving bits of the planner to decide semantics.
+ * XXX this code knows that prepunion.c will adopt the default sort/group
+ * operators for each column datatype to determine uniqueness. It'd
+ * probably be better if these operators were chosen at parse time and
+ * stored into the parsetree, instead of leaving bits of the planner to
+ * decide semantics.
*/
if (query->setOperations)
{
@@ -1020,14 +1023,20 @@ query_is_distinct_for(Query *query, List *colnos, List *opids)
foreach(l, query->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(l);
+ Oid tle_eq_opr;
if (tle->resjunk)
continue; /* ignore resjunk columns */
opid = distinct_col_search(tle->resno, colnos, opids);
- if (!OidIsValid(opid) ||
- !ops_in_same_btree_opfamily(opid,
- ordering_oper_opid(exprType((Node *) tle->expr))))
+ if (!OidIsValid(opid))
+ break; /* exit early if no match */
+ /* check for compatible semantics */
+ get_sort_group_operators(exprType((Node *) tle->expr),
+ false, false, false,
+ NULL, &tle_eq_opr, NULL);
+ if (!OidIsValid(tle_eq_opr) ||
+ !equality_ops_are_compatible(opid, tle_eq_opr))
break; /* exit early if no match */
}
if (l == NULL) /* had matches for all? */