diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-01-10 00:30:21 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-01-10 00:30:21 +0000 |
commit | e439fef6fc3e81aeb865f2c5a77c6faa2ee2a931 (patch) | |
tree | 5e9f5d620801533ab14d63012a44a5b12bfe27cc | |
parent | 6bd343329e62fe9da7917f4a22ffc57ec7060e45 (diff) | |
download | postgresql-e439fef6fc3e81aeb865f2c5a77c6faa2ee2a931.tar.gz postgresql-e439fef6fc3e81aeb865f2c5a77c6faa2ee2a931.zip |
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.
-rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 7aa191644ad..90485171d97 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -16,7 +16,7 @@ * * * 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; /* - * First make a modifiable copy of the subquery. This avoids - * problems if the same subquery is referenced from multiple - * jointree items (which can't happen normally, but might after - * rule rewriting). + * Need a modifiable copy of the subquery to hack on. Even if + * we didn't sometimes choose not to pull up below, we must do + * this to avoid problems if the same subquery is referenced from + * multiple jointree items (which can't happen normally, but might + * after rule rewriting). */ subquery = copyObject(subquery); @@ -197,6 +198,33 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join) 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 * rangetable to upper query's. */ |