]> granicus.if.org Git - postgresql/commitdiff
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:29 +0000 (16:22 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Feb 2006 16:22:29 +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 55e928936cc1b1f2bb43592b0d3543dddd2bcd49..f665c3f1dc5019c694c4d9b1007bf9c2b3067494 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.137.2.1 2005/11/22 18:23:10 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.137.2.2 2006/02/13 16:22:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -793,11 +793,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
@@ -805,7 +808,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.
  */
@@ -834,6 +837,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
@@ -843,7 +853,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;
@@ -855,7 +865,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))
                {
@@ -864,7 +874,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;