Fix qual_is_pushdown_safe to not try to push down quals involving a whole-row
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Feb 2006 16:22:23 +0000 (16:22 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Feb 2006 16:22:23 +0000 (16:22 +0000)
Var referencing the subselect output.  While this case could possibly be made
to work, it seems not worth expending effort on.  Per report from Magnus
Naeslund(f).

src/backend/optimizer/path/allpaths.c

index d2100905406fe4048d83a99bcf3d16116d8f5ec3..c2fd30d5145268cf0b89bf79c9b8d398ebeb276d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.142 2006/02/04 23:03:20 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.143 2006/02/13 16:22:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -816,11 +816,14 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
  * it will work correctly: sublinks will already have been transformed into
  * subplans in the qual, but not in the subquery).
  *
- * 2. The qual must not refer to any subquery output columns that were
+ * 2. The qual must not refer to the whole-row output of the subquery
+ * (since there is no easy way to name that within the subquery itself).
+ *
+ * 3. The qual must not refer to any subquery output columns that were
  * found to have inconsistent types across a set operation tree by
  * subquery_is_pushdown_safe().
  *
- * 3. If the subquery uses DISTINCT ON, we must not push down any quals that
+ * 4. If the subquery uses DISTINCT ON, we must not push down any quals that
  * refer to non-DISTINCT output columns, because that could change the set
  * of rows returned.  This condition is vacuous for DISTINCT, because then
  * there are no non-DISTINCT output columns, but unfortunately it's fairly
@@ -828,7 +831,7 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
  * parsetree representation.  It's cheaper to just make sure all the Vars
  * in the qual refer to DISTINCT columns.
  *
- * 4. We must not push down any quals that refer to subselect outputs that
+ * 5. We must not push down any quals that refer to subselect outputs that
  * return sets, else we'd introduce functions-returning-sets into the
  * subquery's WHERE/HAVING quals.
  */
@@ -857,6 +860,13 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
 
                Assert(var->varno == rti);
 
+               /* Check point 2 */
+               if (var->varattno == 0)
+               {
+                       safe = false;
+                       break;
+               }
+
                /*
                 * We use a bitmapset to avoid testing the same attno more than once.
                 * (NB: this only works because subquery outputs can't have negative
@@ -866,7 +876,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
                        continue;
                tested = bms_add_member(tested, var->varattno);
 
-               /* Check point 2 */
+               /* Check point 3 */
                if (differentTypes[var->varattno])
                {
                        safe = false;
@@ -878,7 +888,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
                Assert(tle != NULL);
                Assert(!tle->resjunk);
 
-               /* If subquery uses DISTINCT or DISTINCT ON, check point 3 */
+               /* If subquery uses DISTINCT or DISTINCT ON, check point 4 */
                if (subquery->distinctClause != NIL &&
                        !targetIsInSortList(tle, subquery->distinctClause))
                {
@@ -887,7 +897,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
                        break;
                }
 
-               /* Refuse functions returning sets (point 4) */
+               /* Refuse functions returning sets (point 5) */
                if (expression_returns_set((Node *) tle->expr))
                {
                        safe = false;