aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/tlist.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-11-08 19:25:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-11-08 19:25:37 +0000
commit1be0601681197fe79a2d2d403c518e7aeff1788a (patch)
tree6d686123b9ca4e5dc70efa9dba364a558ddaa307 /src/backend/optimizer/util/tlist.c
parentf1528b5154ed68ec37735e7125732a96aa1758e1 (diff)
downloadpostgresql-1be0601681197fe79a2d2d403c518e7aeff1788a.tar.gz
postgresql-1be0601681197fe79a2d2d403c518e7aeff1788a.zip
Last week's patch for make_sort_from_pathkeys wasn't good enough: it has
to be able to discard top-level RelabelType nodes on *both* sides of the equivalence-class-to-target-list comparison, since make_pathkey_from_sortinfo might either add or remove a RelabelType. Also fix the latter to do the removal case cleanly. Per example from Peter.
Diffstat (limited to 'src/backend/optimizer/util/tlist.c')
-rw-r--r--src/backend/optimizer/util/tlist.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 1e507235c53..e58fe7dc7f1 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.74 2007/01/05 22:19:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.75 2007/11/08 19:25:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -45,6 +45,34 @@ tlist_member(Node *node, List *targetlist)
}
/*
+ * tlist_member_ignore_relabel
+ * Same as above, except that we ignore top-level RelabelType nodes
+ * while checking for a match. This is needed for some scenarios
+ * involving binary-compatible sort operations.
+ */
+TargetEntry *
+tlist_member_ignore_relabel(Node *node, List *targetlist)
+{
+ ListCell *temp;
+
+ while (node && IsA(node, RelabelType))
+ node = (Node *) ((RelabelType *) node)->arg;
+
+ foreach(temp, targetlist)
+ {
+ TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
+ Expr *tlexpr = tlentry->expr;
+
+ while (tlexpr && IsA(tlexpr, RelabelType))
+ tlexpr = ((RelabelType *) tlexpr)->arg;
+
+ if (equal(node, tlexpr))
+ return tlentry;
+ }
+ return NULL;
+}
+
+/*
* flatten_tlist
* Create a target list that only contains unique variables.
*