1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-31 17:02:12 +03:00

Fix pushing of index-expression qualifications through UNION ALL.

In commit 57664ed25e, 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.
This commit is contained in:
Tom Lane
2012-01-29 16:31:31 -05:00
parent b3bd5a093f
commit 106123fa26
4 changed files with 94 additions and 1 deletions

View File

@@ -2285,6 +2285,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:

View File

@@ -2623,8 +2623,11 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index)
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;