Revert "Don't lock partitions pruned by initial pruning"
authorAmit Langote <[email protected]>
Thu, 22 May 2025 05:17:24 +0000 (14:17 +0900)
committerAmit Langote <[email protected]>
Thu, 22 May 2025 08:02:35 +0000 (17:02 +0900)
As pointed out by Tom Lane, the patch introduced fragile and invasive
design around plan invalidation handling when locking of prunable
partitions was deferred from plancache.c to the executor. In
particular, it violated assumptions about CachedPlan immutability and
altered executor APIs in ways that are difficult to justify given the
added complexity and overhead.

This also removes the firstResultRels field added to PlannedStmt in
commit 28317de72, which was intended to support deferred locking of
certain ModifyTable result relations.

Reported-by: Tom Lane <[email protected]>
Discussion: https://postgr.es/m/605328.1747710381@sss.pgh.pa.us

33 files changed:
contrib/auto_explain/auto_explain.c
contrib/pg_stat_statements/pg_stat_statements.c
doc/src/sgml/release-18.sgml
src/backend/commands/copyto.c
src/backend/commands/createas.c
src/backend/commands/explain.c
src/backend/commands/extension.c
src/backend/commands/matview.c
src/backend/commands/portalcmds.c
src/backend/commands/prepare.c
src/backend/commands/trigger.c
src/backend/executor/README
src/backend/executor/execMain.c
src/backend/executor/execParallel.c
src/backend/executor/execPartition.c
src/backend/executor/execUtils.c
src/backend/executor/functions.c
src/backend/executor/spi.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/tcop/postgres.c
src/backend/tcop/pquery.c
src/backend/utils/cache/plancache.c
src/backend/utils/mmgr/portalmem.c
src/include/commands/explain.h
src/include/commands/trigger.h
src/include/executor/execdesc.h
src/include/executor/executor.h
src/include/nodes/execnodes.h
src/include/nodes/pathnodes.h
src/include/nodes/plannodes.h
src/include/utils/plancache.h
src/include/utils/portal.h

index cd6625020a730f45bf2bd98ceeceab9db52297b9..1f4badb4928409bd891b479ad9524f39e7a9ae9f 100644 (file)
@@ -81,7 +81,7 @@ static ExecutorRun_hook_type prev_ExecutorRun = NULL;
 static ExecutorFinish_hook_type prev_ExecutorFinish = NULL;
 static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
 
-static bool explain_ExecutorStart(QueryDesc *queryDesc, int eflags);
+static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags);
 static void explain_ExecutorRun(QueryDesc *queryDesc,
                                ScanDirection direction,
                                uint64 count);
@@ -261,11 +261,9 @@ _PG_init(void)
 /*
  * ExecutorStart hook: start up logging if needed
  */
-static bool
+static void
 explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
 {
-   bool        plan_valid;
-
    /*
     * At the beginning of each top-level statement, decide whether we'll
     * sample this statement.  If nested-statement explaining is enabled,
@@ -301,13 +299,9 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
    }
 
    if (prev_ExecutorStart)
-       plan_valid = prev_ExecutorStart(queryDesc, eflags);
+       prev_ExecutorStart(queryDesc, eflags);
    else
-       plan_valid = standard_ExecutorStart(queryDesc, eflags);
-
-   /* The plan may have become invalid during standard_ExecutorStart() */
-   if (!plan_valid)
-       return false;
+       standard_ExecutorStart(queryDesc, eflags);
 
    if (auto_explain_enabled())
    {
@@ -325,8 +319,6 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
            MemoryContextSwitchTo(oldcxt);
        }
    }
-
-   return true;
 }
 
 /*
index 9778407cba30bbdec2c4d57d6f9b42d9da6cb9d8..d8fdf42df79354e9aec32130e816c4814304083a 100644 (file)
@@ -335,7 +335,7 @@ static PlannedStmt *pgss_planner(Query *parse,
                                 const char *query_string,
                                 int cursorOptions,
                                 ParamListInfo boundParams);
-static bool pgss_ExecutorStart(QueryDesc *queryDesc, int eflags);
+static void pgss_ExecutorStart(QueryDesc *queryDesc, int eflags);
 static void pgss_ExecutorRun(QueryDesc *queryDesc,
                             ScanDirection direction,
                             uint64 count);
@@ -989,19 +989,13 @@ pgss_planner(Query *parse,
 /*
  * ExecutorStart hook: start up tracking if needed
  */
-static bool
+static void
 pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
 {
-   bool        plan_valid;
-
    if (prev_ExecutorStart)
-       plan_valid = prev_ExecutorStart(queryDesc, eflags);
+       prev_ExecutorStart(queryDesc, eflags);
    else
-       plan_valid = standard_ExecutorStart(queryDesc, eflags);
-
-   /* The plan may have become invalid during standard_ExecutorStart() */
-   if (!plan_valid)
-       return false;
+       standard_ExecutorStart(queryDesc, eflags);
 
    /*
     * If query has queryId zero, don't track it.  This prevents double
@@ -1024,8 +1018,6 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
            MemoryContextSwitchTo(oldcxt);
        }
    }
-
-   return true;
 }
 
 /*
index cdf47ac6d2ac74144ad352dd3179126ff13f61b8..143a8b8764701298182cfd68655b63d614bbcc31 100644 (file)
@@ -588,27 +588,6 @@ Improve the locking performance of queries that access many relations (Tomas Von
 </para>
 </listitem>
 
-<!--
-Author: Amit Langote <[email protected]>
-2025-01-30 [bb3ec16e1] Move PartitionPruneInfo out of plan nodes into PlannedSt
-Author: Amit Langote <[email protected]>
-2025-01-31 [d47cbf474] Perform runtime initial pruning outside ExecInitNode()
-Author: Amit Langote <[email protected]>
-2025-02-07 [cbc127917] Track unpruned relids to avoid processing pruned relatio
-Author: Amit Langote <[email protected]>
-2025-02-20 [525392d57] Don't lock partitions pruned by initial pruning
--->
-
-<listitem>
-<para>
-Avoid the locking of pruned partitions during execution (Amit Langote)
-<ulink url="&commit_baseurl;bb3ec16e1">&sect;</ulink>
-<ulink url="&commit_baseurl;d47cbf474">&sect;</ulink>
-<ulink url="&commit_baseurl;cbc127917">&sect;</ulink>
-<ulink url="&commit_baseurl;525392d57">&sect;</ulink>
-</para>
-</listitem>
-
 <!--
 Author: David Rowley <[email protected]>
 2024-08-20 [adf97c156] Speed up Hash Join by making ExprStates support hashing
index f87e405351d110d3656bc06a1cfa475094bb30da..ea6f18f2c80085cb4e70533af18ac359c20c2741 100644 (file)
@@ -835,7 +835,7 @@ BeginCopyTo(ParseState *pstate,
        ((DR_copy *) dest)->cstate = cstate;
 
        /* Create a QueryDesc requesting no output */
-       cstate->queryDesc = CreateQueryDesc(plan, NULL, pstate->p_sourcetext,
+       cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
                                            GetActiveSnapshot(),
                                            InvalidSnapshot,
                                            dest, NULL, NULL, 0);
@@ -845,8 +845,7 @@ BeginCopyTo(ParseState *pstate,
         *
         * ExecutorStart computes a result tupdesc for us
         */
-       if (!ExecutorStart(cstate->queryDesc, 0))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
+       ExecutorStart(cstate->queryDesc, 0);
 
        tupDesc = cstate->queryDesc->tupDesc;
    }
index 0a4155773eb5f87cd8fd6656e219e93bdfb25998..dfd2ab8e8628c7a32a9a44ad3ec1adff3a7e4a27 100644 (file)
@@ -334,13 +334,12 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
        UpdateActiveSnapshotCommandId();
 
        /* Create a QueryDesc, redirecting output to our tuple receiver */
-       queryDesc = CreateQueryDesc(plan, NULL, pstate->p_sourcetext,
+       queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
                                    GetActiveSnapshot(), InvalidSnapshot,
                                    dest, params, queryEnv, 0);
 
        /* call ExecutorStart to prepare the plan for execution */
-       if (!ExecutorStart(queryDesc, GetIntoRelEFlags(into)))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
+       ExecutorStart(queryDesc, GetIntoRelEFlags(into));
 
        /* run the plan to completion */
        ExecutorRun(queryDesc, ForwardScanDirection, 0);
index 786ee865f147d72d1ac36da12016fcb6d90b75f1..09ea30dfb920074de955bb48d824c113886285c8 100644 (file)
@@ -369,8 +369,7 @@ standard_ExplainOneQuery(Query *query, int cursorOptions,
    }
 
    /* run it (if needed) and produce output */
-   ExplainOnePlan(plan, NULL, NULL, -1, into, es, queryString, params,
-                  queryEnv,
+   ExplainOnePlan(plan, into, es, queryString, params, queryEnv,
                   &planduration, (es->buffers ? &bufusage : NULL),
                   es->memory ? &mem_counters : NULL);
 }
@@ -492,9 +491,7 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es,
  * to call it.
  */
 void
-ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
-              CachedPlanSource *plansource, int query_index,
-              IntoClause *into, ExplainState *es,
+ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
               const char *queryString, ParamListInfo params,
               QueryEnvironment *queryEnv, const instr_time *planduration,
               const BufferUsage *bufusage,
@@ -550,7 +547,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
        dest = None_Receiver;
 
    /* Create a QueryDesc for the query */
-   queryDesc = CreateQueryDesc(plannedstmt, cplan, queryString,
+   queryDesc = CreateQueryDesc(plannedstmt, queryString,
                                GetActiveSnapshot(), InvalidSnapshot,
                                dest, params, queryEnv, instrument_option);
 
@@ -564,17 +561,8 @@ ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
    if (into)
        eflags |= GetIntoRelEFlags(into);
 
-   /* Prepare the plan for execution. */
-   if (queryDesc->cplan)
-   {
-       ExecutorStartCachedPlan(queryDesc, eflags, plansource, query_index);
-       Assert(queryDesc->planstate);
-   }
-   else
-   {
-       if (!ExecutorStart(queryDesc, eflags))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
-   }
+   /* call ExecutorStart to prepare the plan for execution */
+   ExecutorStart(queryDesc, eflags);
 
    /* Execute the plan for statistics if asked for */
    if (es->analyze)
index 73c52e970f6c3bbbf4a3d6176dc491831001c166..e6f9ab6dfd66b008b9f41c0795c83f55d12db454 100644 (file)
@@ -993,13 +993,11 @@ execute_sql_string(const char *sql, const char *filename)
                QueryDesc  *qdesc;
 
                qdesc = CreateQueryDesc(stmt,
-                                       NULL,
                                        sql,
                                        GetActiveSnapshot(), NULL,
                                        dest, NULL, NULL, 0);
 
-               if (!ExecutorStart(qdesc, 0))
-                   elog(ERROR, "ExecutorStart() failed unexpectedly");
+               ExecutorStart(qdesc, 0);
                ExecutorRun(qdesc, ForwardScanDirection, 0);
                ExecutorFinish(qdesc);
                ExecutorEnd(qdesc);
index e7854add17825b41bd56c8e7a421d1e968488f93..27c2cb26ef5f3903da346308fad756c97ff413be 100644 (file)
@@ -438,13 +438,12 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
    UpdateActiveSnapshotCommandId();
 
    /* Create a QueryDesc, redirecting output to our tuple receiver */
-   queryDesc = CreateQueryDesc(plan, NULL, queryString,
+   queryDesc = CreateQueryDesc(plan, queryString,
                                GetActiveSnapshot(), InvalidSnapshot,
                                dest, NULL, NULL, 0);
 
    /* call ExecutorStart to prepare the plan for execution */
-   if (!ExecutorStart(queryDesc, 0))
-       elog(ERROR, "ExecutorStart() failed unexpectedly");
+   ExecutorStart(queryDesc, 0);
 
    /* run the plan */
    ExecutorRun(queryDesc, ForwardScanDirection, 0);
index 4c2ac04522459afb56d3d3e5a942c53f6e45269c..e7c8171c1020717e7fdf89dc6a01861806fa5fe9 100644 (file)
@@ -117,7 +117,6 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa
                      queryString,
                      CMDTAG_SELECT,    /* cursor's query is always a SELECT */
                      list_make1(plan),
-                     NULL,
                      NULL);
 
    /*----------
index bf7d2b2309fc2122e1290fce0b4a3c3b2d00bdc5..34b6410d6a26cde048868543124bdc6886ac2045 100644 (file)
@@ -205,8 +205,7 @@ ExecuteQuery(ParseState *pstate,
                      query_string,
                      entry->plansource->commandTag,
                      plan_list,
-                     cplan,
-                     entry->plansource);
+                     cplan);
 
    /*
     * For CREATE TABLE ... AS EXECUTE, we must verify that the prepared
@@ -586,7 +585,6 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
    MemoryContextCounters mem_counters;
    MemoryContext planner_ctx = NULL;
    MemoryContext saved_ctx = NULL;
-   int         query_index = 0;
 
    if (es->memory)
    {
@@ -659,8 +657,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
        PlannedStmt *pstmt = lfirst_node(PlannedStmt, p);
 
        if (pstmt->commandType != CMD_UTILITY)
-           ExplainOnePlan(pstmt, cplan, entry->plansource, query_index,
-                          into, es, query_string, paramLI, pstate->p_queryEnv,
+           ExplainOnePlan(pstmt, into, es, query_string, paramLI, pstate->p_queryEnv,
                           &planduration, (es->buffers ? &bufusage : NULL),
                           es->memory ? &mem_counters : NULL);
        else
@@ -671,8 +668,6 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
        /* Separate plans with an appropriate separator */
        if (lnext(plan_list, p) != NULL)
            ExplainSeparatePlans(es);
-
-       query_index++;
    }
 
    if (estate)
index c9f61130c69408f36d24b977d63772fb30ddadfe..67f8e70f9c1666f76ca3f3d38a80403b4e714b38 100644 (file)
@@ -5057,21 +5057,6 @@ AfterTriggerBeginQuery(void)
 }
 
 
-/* ----------
- * AfterTriggerAbortQuery()
- *
- * Called by standard_ExecutorEnd() if the query execution was aborted due to
- * the plan becoming invalid during initialization.
- * ----------
- */
-void
-AfterTriggerAbortQuery(void)
-{
-   /* Revert the actions of AfterTriggerBeginQuery(). */
-   afterTriggers.query_depth--;
-}
-
-
 /* ----------
  * AfterTriggerEndQuery()
  *
index 02745c23ed974e33e0955a4bb1058ed6f14155e5..54f4782f31b6070efa5e712fbb248736d7af95d4 100644 (file)
@@ -285,28 +285,6 @@ are typically reset to empty once per tuple.  Per-tuple contexts are usually
 associated with ExprContexts, and commonly each PlanState node has its own
 ExprContext to evaluate its qual and targetlist expressions in.
 
-Relation Locking
-----------------
-
-When the executor initializes a plan tree for execution, it doesn't lock
-non-index relations if the plan tree is freshly generated and not derived
-from a CachedPlan. This is because such locks have already been established
-during the query's parsing, rewriting, and planning phases. However, with a
-cached plan tree, some relations may remain unlocked. The function
-AcquireExecutorLocks() only locks unprunable relations in the plan, deferring
-the locking of prunable ones to executor initialization. This avoids
-unnecessary locking of relations that will be pruned during "initial" runtime
-pruning in ExecDoInitialPruning().
-
-This approach creates a window where a cached plan tree with child tables
-could become outdated if another backend modifies these tables before
-ExecDoInitialPruning() locks them. As a result, the executor has the added duty
-to verify the plan tree's validity whenever it locks a child table after
-doing initial pruning. This validation is done by checking the CachedPlan.is_valid
-flag. If the plan tree is outdated (is_valid = false), the executor stops
-further initialization, cleans up anything in EState that would have been
-allocated up to that point, and retries execution after recreating the
-invalid plan in the CachedPlan.  See ExecutorStartCachedPlan().
 
 Query Processing Control Flow
 -----------------------------
@@ -315,13 +293,11 @@ This is a sketch of control flow for full query processing:
 
    CreateQueryDesc
 
-   ExecutorStart or ExecutorStartCachedPlan
+   ExecutorStart
        CreateExecutorState
            creates per-query context
-       switch to per-query context to run ExecDoInitialPruning and ExecInitNode
+       switch to per-query context to run ExecInitNode
        AfterTriggerBeginQuery
-       ExecDoInitialPruning
-           does initial pruning and locks surviving partitions if needed
        ExecInitNode --- recursively scans plan tree
            ExecInitNode
                recurse into subsidiary nodes
@@ -345,12 +321,7 @@ This is a sketch of control flow for full query processing:
 
    FreeQueryDesc
 
-As mentioned in the "Relation Locking" section, if the plan tree is found to
-be stale after locking partitions in ExecDoInitialPruning(), the control is
-immediately returned to ExecutorStartCachedPlan(), which will create a new plan
-tree and perform the steps starting from CreateExecutorState() again.
-
-Per above comments, it's not really critical for ExecEndPlan to free any
+Per above comments, it's not really critical for ExecEndNode to free any
 memory; it'll all go away in FreeExecutorState anyway.  However, we do need to
 be careful to close relations, drop buffer pins, etc, so we do need to scan
 the plan state tree to find these sorts of resources.
index 7230f968101a6ef256906e515b830d3c38311456..0391798dd2c33a6188c415903005c047a038593c 100644 (file)
 #include "parser/parse_relation.h"
 #include "pgstat.h"
 #include "rewrite/rewriteHandler.h"
-#include "storage/lmgr.h"
 #include "tcop/utility.h"
 #include "utils/acl.h"
 #include "utils/backend_status.h"
 #include "utils/lsyscache.h"
 #include "utils/partcache.h"
-#include "utils/plancache.h"
 #include "utils/rls.h"
 #include "utils/snapmgr.h"
 
@@ -119,16 +117,11 @@ static void ReportNotNullViolationError(ResultRelInfo *resultRelInfo,
  * get control when ExecutorStart is called.  Such a plugin would
  * normally call standard_ExecutorStart().
  *
- * Return value indicates if the plan has been initialized successfully so
- * that queryDesc->planstate contains a valid PlanState tree.  It may not
- * if the plan got invalidated during InitPlan().
  * ----------------------------------------------------------------
  */
-bool
+void
 ExecutorStart(QueryDesc *queryDesc, int eflags)
 {
-   bool        plan_valid;
-
    /*
     * In some cases (e.g. an EXECUTE statement or an execute message with the
     * extended query protocol) the query_id won't be reported, so do it now.
@@ -140,14 +133,12 @@ ExecutorStart(QueryDesc *queryDesc, int eflags)
    pgstat_report_query_id(queryDesc->plannedstmt->queryId, false);
 
    if (ExecutorStart_hook)
-       plan_valid = (*ExecutorStart_hook) (queryDesc, eflags);
+       (*ExecutorStart_hook) (queryDesc, eflags);
    else
-       plan_valid = standard_ExecutorStart(queryDesc, eflags);
-
-   return plan_valid;
+       standard_ExecutorStart(queryDesc, eflags);
 }
 
-bool
+void
 standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
 {
    EState     *estate;
@@ -271,64 +262,6 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
    InitPlan(queryDesc, eflags);
 
    MemoryContextSwitchTo(oldcontext);
-
-   return ExecPlanStillValid(queryDesc->estate);
-}
-
-/*
- * ExecutorStartCachedPlan
- *     Start execution for a given query in the CachedPlanSource, replanning
- *     if the plan is invalidated due to deferred locks taken during the
- *     plan's initialization
- *
- * This function handles cases where the CachedPlan given in queryDesc->cplan
- * might become invalid during the initialization of the plan given in
- * queryDesc->plannedstmt, particularly when prunable relations in it are
- * locked after performing initial pruning. If the locks invalidate the plan,
- * the function calls UpdateCachedPlan() to replan all queries in the
- * CachedPlan, and then retries initialization.
- *
- * The function repeats the process until ExecutorStart() successfully
- * initializes the plan, that is without the CachedPlan becoming invalid.
- */
-void
-ExecutorStartCachedPlan(QueryDesc *queryDesc, int eflags,
-                       CachedPlanSource *plansource,
-                       int query_index)
-{
-   if (unlikely(queryDesc->cplan == NULL))
-       elog(ERROR, "ExecutorStartCachedPlan(): missing CachedPlan");
-   if (unlikely(plansource == NULL))
-       elog(ERROR, "ExecutorStartCachedPlan(): missing CachedPlanSource");
-
-   /*
-    * Loop and retry with an updated plan until no further invalidation
-    * occurs.
-    */
-   while (1)
-   {
-       if (!ExecutorStart(queryDesc, eflags))
-       {
-           /*
-            * Clean up the current execution state before creating the new
-            * plan to retry ExecutorStart().  Mark execution as aborted to
-            * ensure that AFTER trigger state is properly reset.
-            */
-           queryDesc->estate->es_aborted = true;
-           ExecutorEnd(queryDesc);
-
-           /* Retry ExecutorStart() with an updated plan tree. */
-           queryDesc->plannedstmt = UpdateCachedPlan(plansource, query_index,
-                                                     queryDesc->queryEnv);
-       }
-       else
-
-           /*
-            * Exit the loop if the plan is initialized successfully and no
-            * sinval messages were received that invalidated the CachedPlan.
-            */
-           break;
-   }
 }
 
 /* ----------------------------------------------------------------
@@ -387,7 +320,6 @@ standard_ExecutorRun(QueryDesc *queryDesc,
    estate = queryDesc->estate;
 
    Assert(estate != NULL);
-   Assert(!estate->es_aborted);
    Assert(!(estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY));
 
    /* caller must ensure the query's snapshot is active */
@@ -494,11 +426,8 @@ standard_ExecutorFinish(QueryDesc *queryDesc)
    Assert(estate != NULL);
    Assert(!(estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY));
 
-   /*
-    * This should be run once and only once per Executor instance and never
-    * if the execution was aborted.
-    */
-   Assert(!estate->es_finished && !estate->es_aborted);
+   /* This should be run once and only once per Executor instance */
+   Assert(!estate->es_finished);
 
    /* Switch into per-query memory context */
    oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
@@ -561,10 +490,11 @@ standard_ExecutorEnd(QueryDesc *queryDesc)
                                             (PgStat_Counter) estate->es_parallel_workers_launched);
 
    /*
-    * Check that ExecutorFinish was called, unless in EXPLAIN-only mode or if
-    * execution was aborted.
+    * Check that ExecutorFinish was called, unless in EXPLAIN-only mode. This
+    * Assert is needed because ExecutorFinish is new as of 9.1, and callers
+    * might forget to call it.
     */
-   Assert(estate->es_finished || estate->es_aborted ||
+   Assert(estate->es_finished ||
           (estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY));
 
    /*
@@ -578,14 +508,6 @@ standard_ExecutorEnd(QueryDesc *queryDesc)
    UnregisterSnapshot(estate->es_snapshot);
    UnregisterSnapshot(estate->es_crosscheck_snapshot);
 
-   /*
-    * Reset AFTER trigger module if the query execution was aborted.
-    */
-   if (estate->es_aborted &&
-       !(estate->es_top_eflags &
-         (EXEC_FLAG_SKIP_TRIGGERS | EXEC_FLAG_EXPLAIN_ONLY)))
-       AfterTriggerAbortQuery();
-
    /*
     * Must switch out of context before destroying it
     */
@@ -684,21 +606,6 @@ ExecCheckPermissions(List *rangeTable, List *rteperminfos,
                   (rte->rtekind == RTE_SUBQUERY &&
                    rte->relkind == RELKIND_VIEW));
 
-           /*
-            * Ensure that we have at least an AccessShareLock on relations
-            * whose permissions need to be checked.
-            *
-            * Skip this check in a parallel worker because locks won't be
-            * taken until ExecInitNode() performs plan initialization.
-            *
-            * XXX: ExecCheckPermissions() in a parallel worker may be
-            * redundant with the checks done in the leader process, so this
-            * should be reviewed to ensure it’s necessary.
-            */
-           Assert(IsParallelWorker() ||
-                  CheckRelationOidLockedByMe(rte->relid, AccessShareLock,
-                                             true));
-
            (void) getRTEPermissionInfo(rteperminfos, rte);
            /* Many-to-one mapping not allowed */
            Assert(!bms_is_member(rte->perminfoindex, indexset));
@@ -924,12 +831,6 @@ ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
  *
  *     Initializes the query plan: open files, allocate storage
  *     and start up the rule manager
- *
- *     If the plan originates from a CachedPlan (given in queryDesc->cplan),
- *     it can become invalid during runtime "initial" pruning when the
- *     remaining set of locks is taken.  The function returns early in that
- *     case without initializing the plan, and the caller is expected to
- *     retry with a new valid plan.
  * ----------------------------------------------------------------
  */
 static void
@@ -937,7 +838,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
 {
    CmdType     operation = queryDesc->operation;
    PlannedStmt *plannedstmt = queryDesc->plannedstmt;
-   CachedPlan *cachedplan = queryDesc->cplan;
    Plan       *plan = plannedstmt->planTree;
    List       *rangeTable = plannedstmt->rtable;
    EState     *estate = queryDesc->estate;
@@ -958,7 +858,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
                       bms_copy(plannedstmt->unprunableRelids));
 
    estate->es_plannedstmt = plannedstmt;
-   estate->es_cachedplan = cachedplan;
    estate->es_part_prune_infos = plannedstmt->partPruneInfos;
 
    /*
@@ -972,9 +871,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
     */
    ExecDoInitialPruning(estate);
 
-   if (!ExecPlanStillValid(estate))
-       return;
-
    /*
     * Next, build the ExecRowMark array from the PlanRowMark(s), if any.
     */
@@ -3092,9 +2988,6 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
     * the snapshot, rangetable, and external Param info.  They need their own
     * copies of local state, including a tuple table, es_param_exec_vals,
     * result-rel info, etc.
-    *
-    * es_cachedplan is not copied because EPQ plan execution does not acquire
-    * any new locks that could invalidate the CachedPlan.
     */
    rcestate->es_direction = ForwardScanDirection;
    rcestate->es_snapshot = parentestate->es_snapshot;
index 39c990ae638d5b1f9e3fc32bd5e33daf3308aff0..f3e77bda279063bd5eed42ddb378e7db370d8340 100644 (file)
@@ -1278,15 +1278,8 @@ ExecParallelGetQueryDesc(shm_toc *toc, DestReceiver *receiver,
    paramspace = shm_toc_lookup(toc, PARALLEL_KEY_PARAMLISTINFO, false);
    paramLI = RestoreParamList(&paramspace);
 
-   /*
-    * Create a QueryDesc for the query.  We pass NULL for cachedplan, because
-    * we don't have a pointer to the CachedPlan in the leader's process. It's
-    * fine because the only reason the executor needs to see it is to decide
-    * if it should take locks on certain relations, but parallel workers
-    * always take locks anyway.
-    */
+   /* Create a QueryDesc for the query. */
    return CreateQueryDesc(pstmt,
-                          NULL,
                           queryString,
                           GetActiveSnapshot(), InvalidSnapshot,
                           receiver, paramLI, NULL, instrument_options);
@@ -1471,8 +1464,7 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
 
    /* Start up the executor */
    queryDesc->plannedstmt->jitFlags = fpes->jit_flags;
-   if (!ExecutorStart(queryDesc, fpes->eflags))
-       elog(ERROR, "ExecutorStart() failed unexpectedly");
+   ExecutorStart(queryDesc, fpes->eflags);
 
    /* Special executor initialization steps for parallel workers */
    queryDesc->planstate->state->es_query_dsa = area;
index 3f8a4cb52441ad769d52714b194018d353ea1b8d..514eae1037dc30c6bb066fb9a9c5f31488ed9d93 100644 (file)
@@ -26,7 +26,6 @@
 #include "partitioning/partdesc.h"
 #include "partitioning/partprune.h"
 #include "rewrite/rewriteManip.h"
-#include "storage/lmgr.h"
 #include "utils/acl.h"
 #include "utils/lsyscache.h"
 #include "utils/partcache.h"
@@ -1771,8 +1770,7 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
  * ExecDoInitialPruning:
  *     Perform runtime "initial" pruning, if necessary, to determine the set
  *     of child subnodes that need to be initialized during ExecInitNode() for
- *     all plan nodes that contain a PartitionPruneInfo.  This also locks the
- *     leaf partitions whose subnodes will be initialized if needed.
+ *     all plan nodes that contain a PartitionPruneInfo.
  *
  * ExecInitPartitionExecPruning:
  *     Updates the PartitionPruneState found at given part_prune_index in
@@ -1798,8 +1796,7 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
  * ExecDoInitialPruning
  *     Perform runtime "initial" pruning, if necessary, to determine the set
  *     of child subnodes that need to be initialized during ExecInitNode() for
- *     plan nodes that support partition pruning.  This also locks the leaf
- *     partitions whose subnodes will be initialized if needed.
+ *     plan nodes that support partition pruning.
  *
  * This function iterates over each PartitionPruneInfo entry in
  * estate->es_part_prune_infos. For each entry, it creates a PartitionPruneState
@@ -1821,9 +1818,7 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
 void
 ExecDoInitialPruning(EState *estate)
 {
-   PlannedStmt *stmt = estate->es_plannedstmt;
    ListCell   *lc;
-   List       *locked_relids = NIL;
 
    foreach(lc, estate->es_part_prune_infos)
    {
@@ -1849,68 +1844,11 @@ ExecDoInitialPruning(EState *estate)
        else
            validsubplan_rtis = all_leafpart_rtis;
 
-       if (ExecShouldLockRelations(estate))
-       {
-           int         rtindex = -1;
-
-           while ((rtindex = bms_next_member(validsubplan_rtis,
-                                             rtindex)) >= 0)
-           {
-               RangeTblEntry *rte = exec_rt_fetch(rtindex, estate);
-
-               Assert(rte->rtekind == RTE_RELATION &&
-                      rte->rellockmode != NoLock);
-               LockRelationOid(rte->relid, rte->rellockmode);
-               locked_relids = lappend_int(locked_relids, rtindex);
-           }
-       }
        estate->es_unpruned_relids = bms_add_members(estate->es_unpruned_relids,
                                                     validsubplan_rtis);
        estate->es_part_prune_results = lappend(estate->es_part_prune_results,
                                                validsubplans);
    }
-
-   /*
-    * Lock the first result relation of each ModifyTable node, even if it was
-    * pruned.  This is required for ExecInitModifyTable(), which keeps its
-    * first result relation if all other result relations have been pruned,
-    * because some executor paths (e.g., in nodeModifyTable.c and
-    * execPartition.c) rely on there being at least one result relation.
-    *
-    * There's room for improvement here --- we actually only need to do this
-    * if all other result relations of the ModifyTable node were pruned, but
-    * we don't have an easy way to tell that here.
-    */
-   if (stmt->resultRelations && ExecShouldLockRelations(estate))
-   {
-       foreach(lc, stmt->firstResultRels)
-       {
-           Index       firstResultRel = lfirst_int(lc);
-
-           if (!bms_is_member(firstResultRel, estate->es_unpruned_relids))
-           {
-               RangeTblEntry *rte = exec_rt_fetch(firstResultRel, estate);
-
-               Assert(rte->rtekind == RTE_RELATION && rte->rellockmode != NoLock);
-               LockRelationOid(rte->relid, rte->rellockmode);
-               locked_relids = lappend_int(locked_relids, firstResultRel);
-           }
-       }
-   }
-
-   /*
-    * Release the useless locks if the plan won't be executed.  This is the
-    * same as what CheckCachedPlan() in plancache.c does.
-    */
-   if (!ExecPlanStillValid(estate))
-   {
-       foreach(lc, locked_relids)
-       {
-           RangeTblEntry *rte = exec_rt_fetch(lfirst_int(lc), estate);
-
-           UnlockRelationOid(rte->relid, rte->rellockmode);
-       }
-   }
 }
 
 /*
index 772c86e70e9bfea4a874284046c8d204044b84db..fdc65c2b42b331109e64a2381b2183a45bde3ce7 100644 (file)
@@ -147,7 +147,6 @@ CreateExecutorState(void)
    estate->es_top_eflags = 0;
    estate->es_instrument = 0;
    estate->es_finished = false;
-   estate->es_aborted = false;
 
    estate->es_exprcontexts = NIL;
 
index 8d4d062d5793ba5a88ef3107741103107b6059c8..359aafea681b916757550514067fd087be177dfa 100644 (file)
@@ -34,6 +34,7 @@
 #include "utils/funccache.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 
@@ -1338,7 +1339,6 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
        dest = None_Receiver;
 
    es->qd = CreateQueryDesc(es->stmt,
-                            NULL,
                             fcache->func->src,
                             GetActiveSnapshot(),
                             InvalidSnapshot,
@@ -1363,8 +1363,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
            eflags = EXEC_FLAG_SKIP_TRIGGERS;
        else
            eflags = 0;         /* default run-to-completion flags */
-       if (!ExecutorStart(es->qd, eflags))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
+       ExecutorStart(es->qd, eflags);
    }
 
    es->status = F_EXEC_RUN;
index 3288396def3c593fd95c3675e840c9ea7f2ed5a9..ecb2e4ccaa1ca281bc5d9f687c6a9d5281518c47 100644 (file)
@@ -70,8 +70,7 @@ static int    _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
 static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes,
                                         Datum *Values, const char *Nulls);
 
-static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount,
-                       CachedPlanSource *plansource, int query_index);
+static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount);
 
 static void _SPI_error_callback(void *arg);
 
@@ -1686,8 +1685,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
                      query_string,
                      plansource->commandTag,
                      stmt_list,
-                     cplan,
-                     plansource);
+                     cplan);
 
    /*
     * Set up options for portal.  Default SCROLL type is chosen the same way
@@ -2502,7 +2500,6 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
        CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1);
        List       *stmt_list;
        ListCell   *lc2;
-       int         query_index = 0;
 
        spicallbackarg.query = plansource->query_string;
 
@@ -2693,16 +2690,14 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
                    snap = InvalidSnapshot;
 
                qdesc = CreateQueryDesc(stmt,
-                                       cplan,
                                        plansource->query_string,
                                        snap, crosscheck_snapshot,
                                        dest,
                                        options->params,
                                        _SPI_current->queryEnv,
                                        0);
-
-               res = _SPI_pquery(qdesc, fire_triggers, canSetTag ? options->tcount : 0,
-                                 plansource, query_index);
+               res = _SPI_pquery(qdesc, fire_triggers,
+                                 canSetTag ? options->tcount : 0);
                FreeQueryDesc(qdesc);
            }
            else
@@ -2799,8 +2794,6 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
                my_res = res;
                goto fail;
            }
-
-           query_index++;
        }
 
        /* Done with this plan, so release refcount */
@@ -2878,8 +2871,7 @@ _SPI_convert_params(int nargs, Oid *argtypes,
 }
 
 static int
-_SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount,
-           CachedPlanSource *plansource, int query_index)
+_SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount)
 {
    int         operation = queryDesc->operation;
    int         eflags;
@@ -2935,16 +2927,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount,
    else
        eflags = EXEC_FLAG_SKIP_TRIGGERS;
 
-   if (queryDesc->cplan)
-   {
-       ExecutorStartCachedPlan(queryDesc, eflags, plansource, query_index);
-       Assert(queryDesc->planstate);
-   }
-   else
-   {
-       if (!ExecutorStart(queryDesc, eflags))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
-   }
+   ExecutorStart(queryDesc, eflags);
 
    ExecutorRun(queryDesc, ForwardScanDirection, tcount);
 
index 49ad6e835782fd87e6a7fdacd4633433c9f6955b..ff65867eebee7f3bc347c4380efffbac26d1c41a 100644 (file)
@@ -331,7 +331,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
    glob->finalrteperminfos = NIL;
    glob->finalrowmarks = NIL;
    glob->resultRelations = NIL;
-   glob->firstResultRels = NIL;
    glob->appendRelations = NIL;
    glob->partPruneInfos = NIL;
    glob->relationOids = NIL;
@@ -571,7 +570,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
                                              glob->prunableRelids);
    result->permInfos = glob->finalrteperminfos;
    result->resultRelations = glob->resultRelations;
-   result->firstResultRels = glob->firstResultRels;
    result->appendRelations = glob->appendRelations;
    result->subplans = glob->subplans;
    result->rewindPlanIDs = glob->rewindPlanIDs;
index 150e9f060ee0073e2946b5a880c224c6d254cb2f..999a5a8ab5a2e1c716b43d782edd057cf0f23bbc 100644 (file)
@@ -1248,9 +1248,6 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
                        lappend_int(root->glob->resultRelations,
                                    splan->rootRelation);
                }
-               root->glob->firstResultRels =
-                   lappend_int(root->glob->firstResultRels,
-                               linitial_int(splan->resultRelations));
            }
            break;
        case T_Append:
index 1ae51b1b3915756371c6923d163da4aa8467844b..92ddeba78fddb2efc4ec8ba842cc1630fb69e95e 100644 (file)
@@ -1226,7 +1226,6 @@ exec_simple_query(const char *query_string)
                          query_string,
                          commandTag,
                          plantree_list,
-                         NULL,
                          NULL);
 
        /*
@@ -2028,8 +2027,7 @@ exec_bind_message(StringInfo input_message)
                      query_string,
                      psrc->commandTag,
                      cplan->stmt_list,
-                     cplan,
-                     psrc);
+                     cplan);
 
    /* Portal is defined, set the plan ID based on its contents. */
    foreach(lc, portal->stmts)
index 8164d0fbb4f6974370a5a31c8adb4817e0fe0ce7..d1593f38b35fdb9e752bdd20cc0d9f00d0791904 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "access/xact.h"
 #include "commands/prepare.h"
-#include "executor/execdesc.h"
 #include "executor/executor.h"
 #include "executor/tstoreReceiver.h"
 #include "miscadmin.h"
@@ -38,9 +37,6 @@ Portal        ActivePortal = NULL;
 
 
 static void ProcessQuery(PlannedStmt *plan,
-                        CachedPlan *cplan,
-                        CachedPlanSource *plansource,
-                        int query_index,
                         const char *sourceText,
                         ParamListInfo params,
                         QueryEnvironment *queryEnv,
@@ -70,7 +66,6 @@ static void DoPortalRewind(Portal portal);
  */
 QueryDesc *
 CreateQueryDesc(PlannedStmt *plannedstmt,
-               CachedPlan *cplan,
                const char *sourceText,
                Snapshot snapshot,
                Snapshot crosscheck_snapshot,
@@ -83,7 +78,6 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
 
    qd->operation = plannedstmt->commandType;   /* operation */
    qd->plannedstmt = plannedstmt;  /* plan */
-   qd->cplan = cplan;          /* CachedPlan supplying the plannedstmt */
    qd->sourceText = sourceText;    /* query text */
    qd->snapshot = RegisterSnapshot(snapshot);  /* snapshot */
    /* RI check snapshot */
@@ -129,9 +123,6 @@ FreeQueryDesc(QueryDesc *qdesc)
  *     PORTAL_ONE_RETURNING, or PORTAL_ONE_MOD_WITH portal
  *
  * plan: the plan tree for the query
- * cplan: CachedPlan supplying the plan
- * plansource: CachedPlanSource supplying the cplan
- * query_index: index of the query in plansource->query_list
  * sourceText: the source text of the query
  * params: any parameters needed
  * dest: where to send results
@@ -144,9 +135,6 @@ FreeQueryDesc(QueryDesc *qdesc)
  */
 static void
 ProcessQuery(PlannedStmt *plan,
-            CachedPlan *cplan,
-            CachedPlanSource *plansource,
-            int query_index,
             const char *sourceText,
             ParamListInfo params,
             QueryEnvironment *queryEnv,
@@ -158,23 +146,14 @@ ProcessQuery(PlannedStmt *plan,
    /*
     * Create the QueryDesc object
     */
-   queryDesc = CreateQueryDesc(plan, cplan, sourceText,
+   queryDesc = CreateQueryDesc(plan, sourceText,
                                GetActiveSnapshot(), InvalidSnapshot,
                                dest, params, queryEnv, 0);
 
    /*
-    * Prepare the plan for execution
+    * Call ExecutorStart to prepare the plan for execution
     */
-   if (queryDesc->cplan)
-   {
-       ExecutorStartCachedPlan(queryDesc, 0, plansource, query_index);
-       Assert(queryDesc->planstate);
-   }
-   else
-   {
-       if (!ExecutorStart(queryDesc, 0))
-           elog(ERROR, "ExecutorStart() failed unexpectedly");
-   }
+   ExecutorStart(queryDesc, 0);
 
    /*
     * Run the plan to completion.
@@ -515,7 +494,6 @@ PortalStart(Portal portal, ParamListInfo params,
                 * the destination to DestNone.
                 */
                queryDesc = CreateQueryDesc(linitial_node(PlannedStmt, portal->stmts),
-                                           portal->cplan,
                                            portal->sourceText,
                                            GetActiveSnapshot(),
                                            InvalidSnapshot,
@@ -535,19 +513,9 @@ PortalStart(Portal portal, ParamListInfo params,
                    myeflags = eflags;
 
                /*
-                * Prepare the plan for execution.
+                * Call ExecutorStart to prepare the plan for execution
                 */
-               if (portal->cplan)
-               {
-                   ExecutorStartCachedPlan(queryDesc, myeflags,
-                                           portal->plansource, 0);
-                   Assert(queryDesc->planstate);
-               }
-               else
-               {
-                   if (!ExecutorStart(queryDesc, myeflags))
-                       elog(ERROR, "ExecutorStart() failed unexpectedly");
-               }
+               ExecutorStart(queryDesc, myeflags);
 
                /*
                 * This tells PortalCleanup to shut down the executor
@@ -1221,7 +1189,6 @@ PortalRunMulti(Portal portal,
 {
    bool        active_snapshot_set = false;
    ListCell   *stmtlist_item;
-   int         query_index = 0;
 
    /*
     * If the destination is DestRemoteExecute, change to DestNone.  The
@@ -1303,9 +1270,6 @@ PortalRunMulti(Portal portal,
            {
                /* statement can set tag string */
                ProcessQuery(pstmt,
-                            portal->cplan,
-                            portal->plansource,
-                            query_index,
                             portal->sourceText,
                             portal->portalParams,
                             portal->queryEnv,
@@ -1315,9 +1279,6 @@ PortalRunMulti(Portal portal,
            {
                /* stmt added by rewrite cannot set tag */
                ProcessQuery(pstmt,
-                            portal->cplan,
-                            portal->plansource,
-                            query_index,
                             portal->sourceText,
                             portal->portalParams,
                             portal->queryEnv,
@@ -1382,8 +1343,6 @@ PortalRunMulti(Portal portal,
         */
        if (lnext(portal->stmts, stmtlist_item) != NULL)
            CommandCounterIncrement();
-
-       query_index++;
    }
 
    /* Pop the snapshot if we pushed one. */
index 9bcbc4c3e9767544d4fe423144ccb00fbbc4b056..89a1c79e984d104613ea875a66d2f2c860383e25 100644 (file)
@@ -92,8 +92,7 @@ static void ReleaseGenericPlan(CachedPlanSource *plansource);
 static bool StmtPlanRequiresRevalidation(CachedPlanSource *plansource);
 static bool BuildingPlanRequiresSnapshot(CachedPlanSource *plansource);
 static List *RevalidateCachedQuery(CachedPlanSource *plansource,
-                                  QueryEnvironment *queryEnv,
-                                  bool release_generic);
+                                  QueryEnvironment *queryEnv);
 static bool CheckCachedPlan(CachedPlanSource *plansource);
 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
                                   ParamListInfo boundParams, QueryEnvironment *queryEnv);
@@ -663,17 +662,10 @@ BuildingPlanRequiresSnapshot(CachedPlanSource *plansource)
  * The result value is the transient analyzed-and-rewritten query tree if we
  * had to do re-analysis, and NIL otherwise.  (This is returned just to save
  * a tree copying step in a subsequent BuildCachedPlan call.)
- *
- * This also releases and drops the generic plan (plansource->gplan), if any,
- * as most callers will typically build a new CachedPlan for the plansource
- * right after this. However, when called from UpdateCachedPlan(), the
- * function does not release the generic plan, as UpdateCachedPlan() updates
- * an existing CachedPlan in place.
  */
 static List *
 RevalidateCachedQuery(CachedPlanSource *plansource,
-                     QueryEnvironment *queryEnv,
-                     bool release_generic)
+                     QueryEnvironment *queryEnv)
 {
    bool        snapshot_set;
    List       *tlist;          /* transient query-tree list */
@@ -772,9 +764,8 @@ RevalidateCachedQuery(CachedPlanSource *plansource,
        MemoryContextDelete(qcxt);
    }
 
-   /* Drop the generic plan reference, if any, and if requested */
-   if (release_generic)
-       ReleaseGenericPlan(plansource);
+   /* Drop the generic plan reference if any */
+   ReleaseGenericPlan(plansource);
 
    /*
     * Now re-do parse analysis and rewrite.  This not incidentally acquires
@@ -937,10 +928,8 @@ RevalidateCachedQuery(CachedPlanSource *plansource,
  * Caller must have already called RevalidateCachedQuery to verify that the
  * querytree is up to date.
  *
- * On a "true" return, we have acquired locks on the "unprunableRelids" set
- * for all plans in plansource->stmt_list. However, the plans are not fully
- * race-condition-free until the executor acquires locks on the prunable
- * relations that survive initial runtime pruning during InitPlan().
+ * On a "true" return, we have acquired the locks needed to run the plan.
+ * (We must do this for the "true" result to be race-condition-free.)
  */
 static bool
 CheckCachedPlan(CachedPlanSource *plansource)
@@ -1025,8 +1014,6 @@ CheckCachedPlan(CachedPlanSource *plansource)
  * Planning work is done in the caller's memory context.  The finished plan
  * is in a child memory context, which typically should get reparented
  * (unless this is a one-shot plan, in which case we don't copy the plan).
- *
- * Note: When changing this, you should also look at UpdateCachedPlan().
  */
 static CachedPlan *
 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
@@ -1037,7 +1024,6 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
    bool        snapshot_set;
    bool        is_transient;
    MemoryContext plan_context;
-   MemoryContext stmt_context = NULL;
    MemoryContext oldcxt = CurrentMemoryContext;
    ListCell   *lc;
 
@@ -1055,7 +1041,7 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
     * let's treat it as real and redo the RevalidateCachedQuery call.
     */
    if (!plansource->is_valid)
-       qlist = RevalidateCachedQuery(plansource, queryEnv, true);
+       qlist = RevalidateCachedQuery(plansource, queryEnv);
 
    /*
     * If we don't already have a copy of the querytree list that can be
@@ -1093,19 +1079,10 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
        PopActiveSnapshot();
 
    /*
-    * Normally, we create a dedicated memory context for the CachedPlan and
-    * its subsidiary data. Although it's usually not very large, the context
-    * is designed to allow growth if necessary.
-    *
-    * The PlannedStmts are stored in a separate child context (stmt_context)
-    * of the CachedPlan's memory context. This separation allows
-    * UpdateCachedPlan() to free and replace the PlannedStmts without
-    * affecting the CachedPlan structure or its stmt_list List.
-    *
-    * For one-shot plans, we instead use the caller's memory context, as the
-    * CachedPlan will not persist.  stmt_context will be set to NULL in this
-    * case, because UpdateCachedPlan() should never get called on a one-shot
-    * plan.
+    * Normally we make a dedicated memory context for the CachedPlan and its
+    * subsidiary data.  (It's probably not going to be large, but just in
+    * case, allow it to grow large.  It's transient for the moment.)  But for
+    * a one-shot plan, we just leave it in the caller's memory context.
     */
    if (!plansource->is_oneshot)
    {
@@ -1114,17 +1091,12 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
                                             ALLOCSET_START_SMALL_SIZES);
        MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
 
-       stmt_context = AllocSetContextCreate(CurrentMemoryContext,
-                                            "CachedPlan PlannedStmts",
-                                            ALLOCSET_START_SMALL_SIZES);
-       MemoryContextCopyAndSetIdentifier(stmt_context, plansource->query_string);
-       MemoryContextSetParent(stmt_context, plan_context);
+       /*
+        * Copy plan into the new context.
+        */
+       MemoryContextSwitchTo(plan_context);
 
-       MemoryContextSwitchTo(stmt_context);
        plist = copyObject(plist);
-
-       MemoryContextSwitchTo(plan_context);
-       plist = list_copy(plist);
    }
    else
        plan_context = CurrentMemoryContext;
@@ -1165,10 +1137,8 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
        plan->saved_xmin = InvalidTransactionId;
    plan->refcount = 0;
    plan->context = plan_context;
-   plan->stmt_context = stmt_context;
    plan->is_oneshot = plansource->is_oneshot;
    plan->is_saved = false;
-   plan->is_reused = false;
    plan->is_valid = true;
 
    /* assign generation number to new plan */
@@ -1179,113 +1149,6 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
    return plan;
 }
 
-/*
- * UpdateCachedPlan
- *     Create fresh plans for all queries in the CachedPlanSource, replacing
- *     those in the generic plan's stmt_list, and return the plan for the
- *     query_index'th query.
- *
- * This function is primarily used by ExecutorStartCachedPlan() to handle
- * cases where the original generic CachedPlan becomes invalid. Such
- * invalidation may occur when prunable relations in the old plan for the
- * query_index'th query are locked in preparation for execution.
- *
- * Note that invalidations received during the execution of the query_index'th
- * query can affect both the queries that have already finished execution
- * (e.g., due to concurrent modifications on prunable relations that were not
- * locked during their execution) and also the queries that have not yet been
- * executed.  As a result, this function updates all plans to ensure
- * CachedPlan.is_valid is safely set to true.
- *
- * The old PlannedStmts in plansource->gplan->stmt_list are freed here, so
- * the caller and any of its callers must not rely on them remaining accessible
- * after this function is called.
- */
-PlannedStmt *
-UpdateCachedPlan(CachedPlanSource *plansource, int query_index,
-                QueryEnvironment *queryEnv)
-{
-   List       *query_list = plansource->query_list,
-              *plan_list;
-   ListCell   *l1,
-              *l2;
-   CachedPlan *plan = plansource->gplan;
-   MemoryContext oldcxt;
-
-   Assert(ActiveSnapshotSet());
-
-   /* Sanity checks (XXX can be Asserts?) */
-   if (plan == NULL)
-       elog(ERROR, "UpdateCachedPlan() called in the wrong context: plansource->gplan is NULL");
-   else if (plan->is_valid)
-       elog(ERROR, "UpdateCachedPlan() called in the wrong context: plansource->gplan->is_valid is true");
-   else if (plan->is_oneshot)
-       elog(ERROR, "UpdateCachedPlan() called in the wrong context: plansource->gplan->is_oneshot is true");
-
-   /*
-    * The plansource might have become invalid since GetCachedPlan() returned
-    * the CachedPlan. See the comment in BuildCachedPlan() for details on why
-    * this might happen.  Although invalidation is likely a false positive as
-    * stated there, we make the plan valid to ensure the query list used for
-    * planning is up to date.
-    *
-    * The risk of catching an invalidation is higher here than when
-    * BuildCachedPlan() is called from GetCachedPlan(), because this function
-    * is normally called long after GetCachedPlan() returns the CachedPlan,
-    * so much more processing could have occurred including things that mark
-    * the CachedPlanSource invalid.
-    *
-    * Note: Do not release plansource->gplan, because the upstream callers
-    * (such as the callers of ExecutorStartCachedPlan()) would still be
-    * referencing it.
-    */
-   if (!plansource->is_valid)
-       query_list = RevalidateCachedQuery(plansource, queryEnv, false);
-   Assert(query_list != NIL);
-
-   /*
-    * Build a new generic plan for all the queries after making a copy to be
-    * scribbled on by the planner.
-    */
-   query_list = copyObject(query_list);
-
-   /*
-    * Planning work is done in the caller's memory context.  The resulting
-    * PlannedStmt is then copied into plan->stmt_context after throwing away
-    * the old ones.
-    */
-   plan_list = pg_plan_queries(query_list, plansource->query_string,
-                               plansource->cursor_options, NULL);
-   Assert(list_length(plan_list) == list_length(plan->stmt_list));
-
-   MemoryContextReset(plan->stmt_context);
-   oldcxt = MemoryContextSwitchTo(plan->stmt_context);
-   forboth(l1, plan_list, l2, plan->stmt_list)
-   {
-       PlannedStmt *plannedstmt = lfirst(l1);
-
-       lfirst(l2) = copyObject(plannedstmt);
-   }
-   MemoryContextSwitchTo(oldcxt);
-
-   /*
-    * XXX Should this also (re)set the properties of the CachedPlan that are
-    * set in BuildCachedPlan() after creating the fresh plans such as
-    * planRoleId, dependsOnRole, and saved_xmin?
-    */
-
-   /*
-    * We've updated all the plans that might have been invalidated, so mark
-    * the CachedPlan as valid.
-    */
-   plan->is_valid = true;
-
-   /* Also update generic_cost because we just created a new generic plan. */
-   plansource->generic_cost = cached_plan_cost(plan, false);
-
-   return list_nth_node(PlannedStmt, plan->stmt_list, query_index);
-}
-
 /*
  * choose_custom_plan: choose whether to use custom or generic plan
  *
@@ -1402,13 +1265,8 @@ cached_plan_cost(CachedPlan *plan, bool include_planner)
  * plan or a custom plan for the given parameters: the caller does not know
  * which it will get.
  *
- * On return, the plan is valid, but if it is a reused generic plan, not all
- * locks are acquired. In such cases, CheckCachedPlan() does not take locks
- * on relations subject to initial runtime pruning; instead, these locks are
- * deferred until execution startup, when ExecDoInitialPruning() performs
- * initial pruning.  The plan's "is_reused" flag is set to indicate that
- * CachedPlanRequiresLocking() should return true when called by
- * ExecDoInitialPruning().
+ * On return, the plan is valid and we have sufficient locks to begin
+ * execution.
  *
  * On return, the refcount of the plan has been incremented; a later
  * ReleaseCachedPlan() call is expected.  If "owner" is not NULL then
@@ -1434,7 +1292,7 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
        elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
 
    /* Make sure the querytree list is valid and we have parse-time locks */
-   qlist = RevalidateCachedQuery(plansource, queryEnv, true);
+   qlist = RevalidateCachedQuery(plansource, queryEnv);
 
    /* Decide whether to use a custom plan */
    customplan = choose_custom_plan(plansource, boundParams);
@@ -1446,8 +1304,6 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
            /* We want a generic plan, and we already have a valid one */
            plan = plansource->gplan;
            Assert(plan->magic == CACHEDPLAN_MAGIC);
-           /* Reusing the existing plan, so not all locks may be acquired. */
-           plan->is_reused = true;
        }
        else
        {
@@ -1913,7 +1769,7 @@ CachedPlanGetTargetList(CachedPlanSource *plansource,
        return NIL;
 
    /* Make sure the querytree list is valid and we have parse-time locks */
-   RevalidateCachedQuery(plansource, queryEnv, true);
+   RevalidateCachedQuery(plansource, queryEnv);
 
    /* Get the primary statement and find out what it returns */
    pstmt = QueryListGetPrimaryStmt(plansource->query_list);
@@ -2035,7 +1891,7 @@ AcquireExecutorLocks(List *stmt_list, bool acquire)
    foreach(lc1, stmt_list)
    {
        PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
-       int         rtindex;
+       ListCell   *lc2;
 
        if (plannedstmt->commandType == CMD_UTILITY)
        {
@@ -2053,16 +1909,13 @@ AcquireExecutorLocks(List *stmt_list, bool acquire)
            continue;
        }
 
-       rtindex = -1;
-       while ((rtindex = bms_next_member(plannedstmt->unprunableRelids,
-                                         rtindex)) >= 0)
+       foreach(lc2, plannedstmt->rtable)
        {
-           RangeTblEntry *rte = list_nth_node(RangeTblEntry,
-                                              plannedstmt->rtable,
-                                              rtindex - 1);
+           RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
 
-           Assert(rte->rtekind == RTE_RELATION ||
-                  (rte->rtekind == RTE_SUBQUERY && OidIsValid(rte->relid)));
+           if (!(rte->rtekind == RTE_RELATION ||
+                 (rte->rtekind == RTE_SUBQUERY && OidIsValid(rte->relid))))
+               continue;
 
            /*
             * Acquire the appropriate type of lock on each relation OID. Note
index e3526e780649f28492e252d7507baaa517af2b2a..0be1c2b0fff85c32cdea5771521ea6d2eb4585f1 100644 (file)
@@ -284,8 +284,7 @@ PortalDefineQuery(Portal portal,
                  const char *sourceText,
                  CommandTag commandTag,
                  List *stmts,
-                 CachedPlan *cplan,
-                 CachedPlanSource *plansource)
+                 CachedPlan *cplan)
 {
    Assert(PortalIsValid(portal));
    Assert(portal->status == PORTAL_NEW);
@@ -300,7 +299,6 @@ PortalDefineQuery(Portal portal,
    portal->commandTag = commandTag;
    portal->stmts = stmts;
    portal->cplan = cplan;
-   portal->plansource = plansource;
    portal->status = PORTAL_DEFINED;
 }
 
index 03c5b3d73e5c610a68dcfd43351c1d6c371ec51a..3b122f79ed84877322baff1543275de9e823d42c 100644 (file)
@@ -63,10 +63,8 @@ extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into,
                              struct ExplainState *es, ParseState *pstate,
                              ParamListInfo params);
 
-extern void ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
-                          CachedPlanSource *plansource, int query_index,
-                          IntoClause *into, struct ExplainState *es,
-                          const char *queryString,
+extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into,
+                          struct ExplainState *es, const char *queryString,
                           ParamListInfo params, QueryEnvironment *queryEnv,
                           const instr_time *planduration,
                           const BufferUsage *bufusage,
index 4180601dcd4015e9e2a0987ebfa34b87223d7776..2ed2c4bb3784bfb894e40b4bbaec6ff795f30852 100644 (file)
@@ -258,7 +258,6 @@ extern void ExecASTruncateTriggers(EState *estate,
 extern void AfterTriggerBeginXact(void);
 extern void AfterTriggerBeginQuery(void);
 extern void AfterTriggerEndQuery(EState *estate);
-extern void AfterTriggerAbortQuery(void);
 extern void AfterTriggerFireDeferred(void);
 extern void AfterTriggerEndXact(bool isCommit);
 extern void AfterTriggerBeginSubXact(void);
index ba53305ad42d284712eacf0260991412f12ae8af..86db3dc8d0de234dada48eda426b9c47f9dcb8fc 100644 (file)
@@ -35,7 +35,6 @@ typedef struct QueryDesc
    /* These fields are provided by CreateQueryDesc */
    CmdType     operation;      /* CMD_SELECT, CMD_UPDATE, etc. */
    PlannedStmt *plannedstmt;   /* planner's output (could be utility, too) */
-   CachedPlan *cplan;          /* CachedPlan that supplies the plannedstmt */
    const char *sourceText;     /* source text of the query */
    Snapshot    snapshot;       /* snapshot to use for query */
    Snapshot    crosscheck_snapshot;    /* crosscheck for RI update/delete */
@@ -58,7 +57,6 @@ typedef struct QueryDesc
 
 /* in pquery.c */
 extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
-                                 CachedPlan *cplan,
                                  const char *sourceText,
                                  Snapshot snapshot,
                                  Snapshot crosscheck_snapshot,
index ae99407db89df2b9d35140c36b34d9591aff9275..104b059544dd35582bd97b1e6f8ea3c251da9e07 100644 (file)
@@ -19,7 +19,6 @@
 #include "nodes/lockoptions.h"
 #include "nodes/parsenodes.h"
 #include "utils/memutils.h"
-#include "utils/plancache.h"
 
 
 /*
@@ -73,7 +72,7 @@
 
 
 /* Hook for plugins to get control in ExecutorStart() */
-typedef bool (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags);
+typedef void (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags);
 extern PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook;
 
 /* Hook for plugins to get control in ExecutorRun() */
@@ -229,11 +228,8 @@ ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
 /*
  * prototypes from functions in execMain.c
  */
-extern bool ExecutorStart(QueryDesc *queryDesc, int eflags);
-extern void ExecutorStartCachedPlan(QueryDesc *queryDesc, int eflags,
-                                   CachedPlanSource *plansource,
-                                   int query_index);
-extern bool standard_ExecutorStart(QueryDesc *queryDesc, int eflags);
+extern void ExecutorStart(QueryDesc *queryDesc, int eflags);
+extern void standard_ExecutorStart(QueryDesc *queryDesc, int eflags);
 extern void ExecutorRun(QueryDesc *queryDesc,
                        ScanDirection direction, uint64 count);
 extern void standard_ExecutorRun(QueryDesc *queryDesc,
@@ -300,30 +296,6 @@ extern void ExecEndNode(PlanState *node);
 extern void ExecShutdownNode(PlanState *node);
 extern void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node);
 
-/*
- * Is the CachedPlan in es_cachedplan still valid?
- *
- * Called from InitPlan() because invalidation messages that affect the plan
- * might be received after locks have been taken on runtime-prunable relations.
- * The caller should take appropriate action if the plan has become invalid.
- */
-static inline bool
-ExecPlanStillValid(EState *estate)
-{
-   return estate->es_cachedplan == NULL ? true :
-       CachedPlanValid(estate->es_cachedplan);
-}
-
-/*
- * Locks are needed only if running a cached plan that might contain unlocked
- * relations, such as a reused generic plan.
- */
-static inline bool
-ExecShouldLockRelations(EState *estate)
-{
-   return estate->es_cachedplan == NULL ? false :
-       CachedPlanRequiresLocking(estate->es_cachedplan);
-}
 
 /* ----------------------------------------------------------------
  *     ExecProcNode
index 5b6cadb5a6c163ae7eca0dc345a5a151380bba99..2492282213ff359c2353d86bcab1a7271e676458 100644 (file)
@@ -42,7 +42,6 @@
 #include "storage/condition_variable.h"
 #include "utils/hsearch.h"
 #include "utils/queryenvironment.h"
-#include "utils/plancache.h"
 #include "utils/reltrigger.h"
 #include "utils/sharedtuplestore.h"
 #include "utils/snapshot.h"
@@ -664,7 +663,6 @@ typedef struct EState
                                         * ExecRowMarks, or NULL if none */
    List       *es_rteperminfos;    /* List of RTEPermissionInfo */
    PlannedStmt *es_plannedstmt;    /* link to top of plan tree */
-   CachedPlan *es_cachedplan;  /* CachedPlan providing the plan tree */
    List       *es_part_prune_infos;    /* List of PartitionPruneInfo */
    List       *es_part_prune_states;   /* List of PartitionPruneState */
    List       *es_part_prune_results;  /* List of Bitmapset */
@@ -717,7 +715,6 @@ typedef struct EState
    int         es_top_eflags;  /* eflags passed to ExecutorStart */
    int         es_instrument;  /* OR of InstrumentOption flags */
    bool        es_finished;    /* true when ExecutorFinish is done */
-   bool        es_aborted;     /* true when execution was aborted */
 
    List       *es_exprcontexts;    /* List of ExprContexts within EState */
 
index 1dd2d1560cb3807adaacd27eafcf2210afa86b41..6567759595daad5c6317fbae22729d2e966f98cc 100644 (file)
@@ -138,9 +138,6 @@ typedef struct PlannerGlobal
    /* "flat" list of integer RT indexes */
    List       *resultRelations;
 
-   /* "flat" list of integer RT indexes (one per ModifyTable node) */
-   List       *firstResultRels;
-
    /* "flat" list of AppendRelInfos */
    List       *appendRelations;
 
index 658d76225e472b39b71234398b6cb755280408a1..f0d514e6e15264dbd44bb6e3b0862703acb8482b 100644 (file)
@@ -105,13 +105,6 @@ typedef struct PlannedStmt
    /* integer list of RT indexes, or NIL */
    List       *resultRelations;
 
-   /*
-    * rtable indexes of first target relation in each ModifyTable node in the
-    * plan for INSERT/UPDATE/DELETE/MERGE
-    */
-   /* integer list of RT indexes, or NIL */
-   List       *firstResultRels;
-
    /* list of AppendRelInfo nodes */
    List       *appendRelations;
 
index 07ec5318db79d88903bdf0c427c1e96010ac0de1..1baa6d50bfd7a70dc195bc4e906c2a51f4eae5cf 100644 (file)
@@ -18,8 +18,6 @@
 #include "access/tupdesc.h"
 #include "lib/ilist.h"
 #include "nodes/params.h"
-#include "nodes/parsenodes.h"
-#include "nodes/plannodes.h"
 #include "tcop/cmdtag.h"
 #include "utils/queryenvironment.h"
 #include "utils/resowner.h"
@@ -153,11 +151,10 @@ typedef struct CachedPlanSource
  * The reference count includes both the link from the parent CachedPlanSource
  * (if any), and any active plan executions, so the plan can be discarded
  * exactly when refcount goes to zero.  Both the struct itself and the
- * subsidiary data, except the PlannedStmts in stmt_list live in the context
- * denoted by the context field; the PlannedStmts live in the context denoted
- * by stmt_context.  Separate contexts makes it easy to free a no-longer-needed
- * cached plan. (However, if is_oneshot is true, the context does not belong
- * solely to the CachedPlan so no freeing is possible.)
+ * subsidiary data live in the context denoted by the context field.
+ * This makes it easy to free a no-longer-needed cached plan.  (However,
+ * if is_oneshot is true, the context does not belong solely to the CachedPlan
+ * so no freeing is possible.)
  */
 typedef struct CachedPlan
 {
@@ -165,7 +162,6 @@ typedef struct CachedPlan
    List       *stmt_list;      /* list of PlannedStmts */
    bool        is_oneshot;     /* is it a "oneshot" plan? */
    bool        is_saved;       /* is CachedPlan in a long-lived context? */
-   bool        is_reused;      /* is it a reused generic plan? */
    bool        is_valid;       /* is the stmt_list currently valid? */
    Oid         planRoleId;     /* Role ID the plan was created for */
    bool        dependsOnRole;  /* is plan specific to that role? */
@@ -174,10 +170,6 @@ typedef struct CachedPlan
    int         generation;     /* parent's generation number for this plan */
    int         refcount;       /* count of live references to this struct */
    MemoryContext context;      /* context containing this CachedPlan */
-   MemoryContext stmt_context; /* context containing the PlannedStmts in
-                                * stmt_list, but not the List itself which is
-                                * in the above context; NULL if is_oneshot is
-                                * true. */
 } CachedPlan;
 
 /*
@@ -249,10 +241,6 @@ extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource,
                                 ParamListInfo boundParams,
                                 ResourceOwner owner,
                                 QueryEnvironment *queryEnv);
-extern PlannedStmt *UpdateCachedPlan(CachedPlanSource *plansource,
-                                    int query_index,
-                                    QueryEnvironment *queryEnv);
-
 extern void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner);
 
 extern bool CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource,
@@ -265,30 +253,4 @@ extern bool CachedPlanIsSimplyValid(CachedPlanSource *plansource,
 extern CachedExpression *GetCachedExpression(Node *expr);
 extern void FreeCachedExpression(CachedExpression *cexpr);
 
-/*
- * CachedPlanRequiresLocking: should the executor acquire additional locks?
- *
- * If the plan is a saved generic plan, the executor must acquire locks for
- * relations that are not covered by AcquireExecutorLocks(), such as partitions
- * that are subject to initial runtime pruning.
- */
-static inline bool
-CachedPlanRequiresLocking(CachedPlan *cplan)
-{
-   return !cplan->is_oneshot && cplan->is_reused;
-}
-
-/*
- * CachedPlanValid
- *      Returns whether a cached generic plan is still valid.
- *
- * Invoked by the executor to check if the plan has not been invalidated after
- * taking locks during the initialization of the plan.
- */
-static inline bool
-CachedPlanValid(CachedPlan *cplan)
-{
-   return cplan->is_valid;
-}
-
 #endif                         /* PLANCACHE_H */
index ddee031f551405c4ee12e20e8bb19be1836181eb..0b62143af8bcfae7b856861630a05c7d18932e91 100644 (file)
@@ -138,7 +138,6 @@ typedef struct PortalData
    QueryCompletion qc;         /* command completion data for executed query */
    List       *stmts;          /* list of PlannedStmts */
    CachedPlan *cplan;          /* CachedPlan, if stmts are from one */
-   CachedPlanSource *plansource;   /* CachedPlanSource, for cplan */
 
    ParamListInfo portalParams; /* params to pass to query */
    QueryEnvironment *queryEnv; /* environment for query */
@@ -241,8 +240,7 @@ extern void PortalDefineQuery(Portal portal,
                              const char *sourceText,
                              CommandTag commandTag,
                              List *stmts,
-                             CachedPlan *cplan,
-                             CachedPlanSource *plansource);
+                             CachedPlan *cplan);
 extern PlannedStmt *PortalGetPrimaryStmt(Portal portal);
 extern void PortalCreateHoldStore(Portal portal);
 extern void PortalHashTableDeleteAll(void);