Repair oversight in 8.2 change that improved the handling of "pseudoconstant"
authorTom Lane
Thu, 15 Feb 2007 03:07:13 +0000 (03:07 +0000)
committerTom Lane
Thu, 15 Feb 2007 03:07:13 +0000 (03:07 +0000)
WHERE clauses.  createplan.c is now willing to stick a gating Result node
almost anywhere in the plan tree, and in particular one can wind up directly
underneath a MergeJoin node.  This means it had better be willing to handle
Mark/Restore.  Fortunately, that's trivial in such cases, since we can just
pass off the call to the input node (which the planner has previously ensured
can handle Mark/Restore).  Per report from Phil Frost.

src/backend/executor/execAmi.c
src/backend/executor/nodeResult.c
src/include/executor/nodeResult.h

index ee49b39664964e2fc78a850243ab9e58ab6fb08d..68d0d54a53c54f08bca345400be39cf32a601085 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.90 2007/01/05 22:19:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.91 2007/02/15 03:07:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -243,6 +243,10 @@ ExecMarkPos(PlanState *node)
            ExecSortMarkPos((SortState *) node);
            break;
 
+       case T_ResultState:
+           ExecResultMarkPos((ResultState *) node);
+           break;
+
        default:
            /* don't make hard error unless caller asks to restore... */
            elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
@@ -296,6 +300,10 @@ ExecRestrPos(PlanState *node)
            ExecSortRestrPos((SortState *) node);
            break;
 
+       case T_ResultState:
+           ExecResultRestrPos((ResultState *) node);
+           break;
+
        default:
            elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
            break;
@@ -328,6 +336,16 @@ ExecSupportsMarkRestore(NodeTag plantype)
        case T_Sort:
            return true;
 
+       case T_Result:
+           /*
+            * T_Result only supports mark/restore if it has a child plan
+            * that does, so we do not have enough information to give a
+            * really correct answer.  However, for current uses it's
+            * enough to always say "false", because this routine is not
+            * asked about gating Result plans, only base-case Results.
+            */
+           return false;
+
        default:
            break;
    }
index 9765103cbe2df36d6c5e7df2c3856047027a4ad5..2d20079569f152ad6ac49bfb78fb06f512622b35 100644 (file)
@@ -38,7 +38,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/nodeResult.c,v 1.37 2007/02/02 00:07:03 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/nodeResult.c,v 1.38 2007/02/15 03:07:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -166,6 +166,36 @@ ExecResult(ResultState *node)
    return NULL;
 }
 
+/* ----------------------------------------------------------------
+ *     ExecResultMarkPos
+ * ----------------------------------------------------------------
+ */
+void
+ExecResultMarkPos(ResultState *node)
+{
+   PlanState  *outerPlan = outerPlanState(node);
+
+   if (outerPlan != NULL)
+       ExecMarkPos(outerPlan);
+   else
+       elog(DEBUG2, "Result nodes do not support mark/restore");
+}
+
+/* ----------------------------------------------------------------
+ *     ExecResultRestrPos
+ * ----------------------------------------------------------------
+ */
+void
+ExecResultRestrPos(ResultState *node)
+{
+   PlanState  *outerPlan = outerPlanState(node);
+
+   if (outerPlan != NULL)
+       ExecRestrPos(outerPlan);
+   else
+       elog(ERROR, "Result nodes do not support mark/restore");
+}
+
 /* ----------------------------------------------------------------
  *     ExecInitResult
  *
@@ -180,8 +210,8 @@ ExecInitResult(Result *node, EState *estate, int eflags)
    ResultState *resstate;
 
    /* check for unsupported flags */
-   Assert(!(eflags & EXEC_FLAG_MARK));
-   Assert(!(eflags & EXEC_FLAG_BACKWARD) || outerPlan(node) != NULL);
+   Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)) ||
+          outerPlan(node) != NULL);
 
    /*
     * create state structure
index bc30ce30c88b2b3fcec7ea6521cb29ddd7cf6c02..b7a9c6fab620678cacb6708647748e80ac738025 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/executor/nodeResult.h,v 1.23 2007/01/05 22:19:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/executor/nodeResult.h,v 1.24 2007/02/15 03:07:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,6 +20,8 @@ extern int    ExecCountSlotsResult(Result *node);
 extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags);
 extern TupleTableSlot *ExecResult(ResultState *node);
 extern void ExecEndResult(ResultState *node);
+extern void ExecResultMarkPos(ResultState *node);
+extern void ExecResultRestrPos(ResultState *node);
 extern void ExecReScanResult(ResultState *node, ExprContext *exprCtxt);
 
 #endif   /* NODERESULT_H */