aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-01-10 00:30:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-01-10 00:30:21 +0000
commite439fef6fc3e81aeb865f2c5a77c6faa2ee2a931 (patch)
tree5e9f5d620801533ab14d63012a44a5b12bfe27cc
parent6bd343329e62fe9da7917f4a22ffc57ec7060e45 (diff)
downloadpostgresql-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.c38
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.
*/