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 d11ea73f71b0c7fa7856455a3eeb39e9c7602913..dcc857ce7d5a01e779b6cef3b9e420be827f0571 100644 (file)
@@ -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;