Fix subquery pullup logic to not be fooled when a view that appears

'simple' references another view that is not simple.  Must recheck
conditions after performing recursive pullup.  Per example from
Laurent Perez, 9-Jan-04.
This commit is contained in:
Tom Lane 2004-01-10 00:30:21 +00:00
parent 6bd343329e
commit e439fef6fc

View File

@ -16,7 +16,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.14 2003/11/29 19:51:51 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.15 2004/01/10 00:30:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -168,10 +168,11 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
List *rt; List *rt;
/* /*
* First make a modifiable copy of the subquery. This avoids * Need a modifiable copy of the subquery to hack on. Even if
* problems if the same subquery is referenced from multiple * we didn't sometimes choose not to pull up below, we must do
* jointree items (which can't happen normally, but might after * this to avoid problems if the same subquery is referenced from
* rule rewriting). * multiple jointree items (which can't happen normally, but might
* after rule rewriting).
*/ */
subquery = copyObject(subquery); subquery = copyObject(subquery);
@ -196,6 +197,33 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
pull_up_subqueries(subquery, (Node *) subquery->jointree, pull_up_subqueries(subquery, (Node *) subquery->jointree,
false); false);
/*
* Now we must recheck whether the subquery is still simple
* enough to pull up. If not, abandon processing it.
*
* We don't really need to recheck all the conditions involved,
* but it's easier just to keep this "if" looking the same as
* the one above.
*/
if (is_simple_subquery(subquery) &&
(!below_outer_join || has_nullable_targetlist(subquery)) &&
!contain_whole_tuple_var((Node *) parse, varno, 0))
{
/* good to go */
}
else
{
/*
* Give up, return unmodified RangeTblRef.
*
* Note: The work we just did will be redone when the
* subquery gets planned on its own. Perhaps we could avoid
* that by storing the modified subquery back into the
* rangetable, but I'm not gonna risk it now.
*/
return jtnode;
}
/* /*
* Adjust level-0 varnos in subquery so that we can append its * Adjust level-0 varnos in subquery so that we can append its
* rangetable to upper query's. * rangetable to upper query's.