summaryrefslogtreecommitdiff
path: root/src/backend/tcop/pquery.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/pquery.c')
-rw-r--r--src/backend/tcop/pquery.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 0b108ac1348..e7f240e298f 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -143,8 +143,8 @@ FreeQueryDesc(QueryDesc *qdesc)
/*
* ProcessQuery
- * Execute a single plannable query within a PORTAL_MULTI_QUERY
- * or PORTAL_ONE_RETURNING portal
+ * Execute a single plannable query within a PORTAL_MULTI_QUERY,
+ * PORTAL_ONE_RETURNING, or PORTAL_ONE_MOD_WITH portal
*
* plan: the plan tree for the query
* sourceText: the source text of the query
@@ -263,6 +263,7 @@ ChoosePortalStrategy(List *stmts)
* PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the
* single-statement case, since there are no rewrite rules that can add
* auxiliary queries to a SELECT or a utility command.
+ * PORTAL_ONE_MOD_WITH likewise allows only one top-level statement.
*/
if (list_length(stmts) == 1)
{
@@ -277,7 +278,12 @@ ChoosePortalStrategy(List *stmts)
if (query->commandType == CMD_SELECT &&
query->utilityStmt == NULL &&
query->intoClause == NULL)
- return PORTAL_ONE_SELECT;
+ {
+ if (query->hasModifyingCTE)
+ return PORTAL_ONE_MOD_WITH;
+ else
+ return PORTAL_ONE_SELECT;
+ }
if (query->commandType == CMD_UTILITY &&
query->utilityStmt != NULL)
{
@@ -297,7 +303,12 @@ ChoosePortalStrategy(List *stmts)
if (pstmt->commandType == CMD_SELECT &&
pstmt->utilityStmt == NULL &&
pstmt->intoClause == NULL)
- return PORTAL_ONE_SELECT;
+ {
+ if (pstmt->hasModifyingCTE)
+ return PORTAL_ONE_MOD_WITH;
+ else
+ return PORTAL_ONE_SELECT;
+ }
}
}
else
@@ -562,6 +573,7 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot)
break;
case PORTAL_ONE_RETURNING:
+ case PORTAL_ONE_MOD_WITH:
/*
* We don't start the executor until we are told to run the
@@ -572,7 +584,6 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot)
pstmt = (PlannedStmt *) PortalGetPrimaryStmt(portal);
Assert(IsA(pstmt, PlannedStmt));
- Assert(pstmt->hasReturning);
portal->tupDesc =
ExecCleanTypeFromTL(pstmt->planTree->targetlist,
false);
@@ -780,12 +791,13 @@ PortalRun(Portal portal, long count, bool isTopLevel,
{
case PORTAL_ONE_SELECT:
case PORTAL_ONE_RETURNING:
+ case PORTAL_ONE_MOD_WITH:
case PORTAL_UTIL_SELECT:
/*
* If we have not yet run the command, do so, storing its
- * results in the portal's tuplestore. Do this only for the
- * PORTAL_ONE_RETURNING and PORTAL_UTIL_SELECT cases.
+ * results in the portal's tuplestore. But we don't do that
+ * for the PORTAL_ONE_SELECT case.
*/
if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
FillPortalStore(portal, isTopLevel);
@@ -879,8 +891,8 @@ PortalRun(Portal portal, long count, bool isTopLevel,
/*
* PortalRunSelect
* Execute a portal's query in PORTAL_ONE_SELECT mode, and also
- * when fetching from a completed holdStore in PORTAL_ONE_RETURNING
- * and PORTAL_UTIL_SELECT cases.
+ * when fetching from a completed holdStore in PORTAL_ONE_RETURNING,
+ * PORTAL_ONE_MOD_WITH, and PORTAL_UTIL_SELECT cases.
*
* This handles simple N-rows-forward-or-backward cases. For more complex
* nonsequential access to a portal, see PortalRunFetch.
@@ -1031,7 +1043,8 @@ PortalRunSelect(Portal portal,
* FillPortalStore
* Run the query and load result tuples into the portal's tuple store.
*
- * This is used for PORTAL_ONE_RETURNING and PORTAL_UTIL_SELECT cases only.
+ * This is used for PORTAL_ONE_RETURNING, PORTAL_ONE_MOD_WITH, and
+ * PORTAL_UTIL_SELECT cases only.
*/
static void
FillPortalStore(Portal portal, bool isTopLevel)
@@ -1051,6 +1064,7 @@ FillPortalStore(Portal portal, bool isTopLevel)
switch (portal->strategy)
{
case PORTAL_ONE_RETURNING:
+ case PORTAL_ONE_MOD_WITH:
/*
* Run the portal to completion just as for the default
@@ -1392,6 +1406,7 @@ PortalRunFetch(Portal portal,
break;
case PORTAL_ONE_RETURNING:
+ case PORTAL_ONE_MOD_WITH:
case PORTAL_UTIL_SELECT:
/*
@@ -1455,6 +1470,7 @@ DoPortalRunFetch(Portal portal,
Assert(portal->strategy == PORTAL_ONE_SELECT ||
portal->strategy == PORTAL_ONE_RETURNING ||
+ portal->strategy == PORTAL_ONE_MOD_WITH ||
portal->strategy == PORTAL_UTIL_SELECT);
switch (fdirection)