aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/tcop/pquery.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 579b37a9c6d..44f5fe8fc9d 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -1315,18 +1315,29 @@ PortalRunMulti(Portal portal,
}
/*
- * Increment command counter between queries, but not after the last
- * one.
- */
- if (lnext(portal->stmts, stmtlist_item) != NULL)
- CommandCounterIncrement();
-
- /*
* Clear subsidiary contexts to recover temporary memory.
*/
Assert(portal->portalContext == CurrentMemoryContext);
MemoryContextDeleteChildren(portal->portalContext);
+
+ /*
+ * Avoid crashing if portal->stmts has been reset. This can only
+ * occur if a CALL or DO utility statement executed an internal
+ * COMMIT/ROLLBACK (cf PortalReleaseCachedPlan). The CALL or DO must
+ * have been the only statement in the portal, so there's nothing left
+ * for us to do; but we don't want to dereference a now-dangling list
+ * pointer.
+ */
+ if (portal->stmts == NIL)
+ break;
+
+ /*
+ * Increment command counter between queries, but not after the last
+ * one.
+ */
+ if (lnext(portal->stmts, stmtlist_item) != NULL)
+ CommandCounterIncrement();
}
/* Pop the snapshot if we pushed one. */