aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-01-29 16:31:23 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-01-29 16:31:23 -0500
commitb28ffd0fcc583c1811e5295279e7d4366c3cae6c (patch)
treeaeccbd11b8dea5b42c5897f3297a97c1fc759acb /src/backend
parented6e0545f5f6e9977c8410e04244138b567c5a73 (diff)
downloadpostgresql-b28ffd0fcc583c1811e5295279e7d4366c3cae6c.tar.gz
postgresql-b28ffd0fcc583c1811e5295279e7d4366c3cae6c.zip
Fix pushing of index-expression qualifications through UNION ALL.
In commit 57664ed25e5dea117158a2e663c29e60b3546e1c, I made the planner wrap non-simple-variable outputs of appendrel children (IOW, child SELECTs of UNION ALL subqueries) inside PlaceHolderVars, in order to solve some issues with EquivalenceClass processing. However, this means that any upper-level WHERE clauses mentioning such outputs will now contain PlaceHolderVars after they're pushed down into the appendrel child, and that prevents indxpath.c from recognizing that they could be matched to index expressions. To fix, add explicit stripping of PlaceHolderVars from index operands, same as we have long done for RelabelType nodes. Add a regression test covering both this and the plain-UNION case (which is a totally different code path, but should also be able to do it). Per bug #6416 from Matteo Beccati. Back-patch to 9.1, same as the previous change.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/optimizer/path/indxpath.c9
-rw-r--r--src/backend/optimizer/plan/createplan.c5
2 files changed, 13 insertions, 1 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 920593781b2..d51e84a80a2 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -2581,6 +2581,15 @@ match_index_to_operand(Node *operand,
int indkey;
/*
+ * Ignore any PlaceHolderVar nodes above the operand. This is needed so
+ * that we can successfully use expression-index constraints pushed down
+ * through appendrels (UNION ALL). It's safe because a PlaceHolderVar
+ * appearing in a relation-scan-level expression is certainly a no-op.
+ */
+ while (operand && IsA(operand, PlaceHolderVar))
+ operand = (Node *) ((PlaceHolderVar *) operand)->phexpr;
+
+ /*
* Ignore any RelabelType node above the operand. This is needed to be
* able to apply indexscanning in binary-compatible-operator cases. Note:
* we can assume there is at most one RelabelType node;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index aea42b1dd46..9ac0c991902 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -2673,8 +2673,11 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)
ListCell *indexpr_item;
/*
- * Remove any binary-compatible relabeling of the indexkey
+ * Remove any PlaceHolderVars or binary-compatible relabeling of the
+ * indexkey (this must match logic in match_index_to_operand()).
*/
+ while (IsA(node, PlaceHolderVar))
+ node = (Node *) ((PlaceHolderVar *) node)->phexpr;
if (IsA(node, RelabelType))
node = (Node *) ((RelabelType *) node)->arg;