aboutsummaryrefslogtreecommitdiff
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.c348
1 files changed, 199 insertions, 149 deletions
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 49e2a4b0082..8973cca6d26 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.81 2004/07/17 03:29:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.82 2004/07/31 00:45:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -246,94 +246,110 @@ PortalStart(Portal portal, ParamListInfo params)
AssertState(portal->status == PORTAL_NEW); /* else extra PortalStart */
/*
- * Set global portal context pointers. (Should we set QueryContext?)
+ * Set up global portal context pointers. (Should we set QueryContext?)
*/
saveActivePortal = ActivePortal;
- ActivePortal = portal;
saveResourceOwner = CurrentResourceOwner;
- CurrentResourceOwner = portal->resowner;
savePortalContext = PortalContext;
- PortalContext = PortalGetHeapMemory(portal);
+ PG_TRY();
+ {
+ ActivePortal = portal;
+ CurrentResourceOwner = portal->resowner;
+ PortalContext = PortalGetHeapMemory(portal);
- oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
+ oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
- /* Must remember portal param list, if any */
- portal->portalParams = params;
+ /* Must remember portal param list, if any */
+ portal->portalParams = params;
- /*
- * Determine the portal execution strategy
- */
- portal->strategy = ChoosePortalStrategy(portal->parseTrees);
+ /*
+ * Determine the portal execution strategy
+ */
+ portal->strategy = ChoosePortalStrategy(portal->parseTrees);
- /*
- * Fire her up according to the strategy
- */
- switch (portal->strategy)
- {
- case PORTAL_ONE_SELECT:
+ /*
+ * Fire her up according to the strategy
+ */
+ switch (portal->strategy)
+ {
+ case PORTAL_ONE_SELECT:
- /*
- * Must set query snapshot before starting executor.
- */
- SetQuerySnapshot();
+ /*
+ * Must set query snapshot before starting executor.
+ */
+ SetQuerySnapshot();
- /*
- * Create QueryDesc in portal's context; for the moment, set
- * the destination to None.
- */
- queryDesc = CreateQueryDesc((Query *) linitial(portal->parseTrees),
- (Plan *) linitial(portal->planTrees),
- None_Receiver,
- params,
- false);
+ /*
+ * Create QueryDesc in portal's context; for the moment, set
+ * the destination to None.
+ */
+ queryDesc = CreateQueryDesc((Query *) linitial(portal->parseTrees),
+ (Plan *) linitial(portal->planTrees),
+ None_Receiver,
+ params,
+ false);
- /*
- * Call ExecStart to prepare the plan for execution
- */
- ExecutorStart(queryDesc, false, false);
+ /*
+ * Call ExecStart to prepare the plan for execution
+ */
+ ExecutorStart(queryDesc, false, false);
- /*
- * This tells PortalCleanup to shut down the executor
- */
- portal->queryDesc = queryDesc;
+ /*
+ * This tells PortalCleanup to shut down the executor
+ */
+ portal->queryDesc = queryDesc;
- /*
- * Remember tuple descriptor (computed by ExecutorStart)
- */
- portal->tupDesc = queryDesc->tupDesc;
+ /*
+ * Remember tuple descriptor (computed by ExecutorStart)
+ */
+ portal->tupDesc = queryDesc->tupDesc;
- /*
- * Reset cursor position data to "start of query"
- */
- portal->atStart = true;
- portal->atEnd = false; /* allow fetches */
- portal->portalPos = 0;
- portal->posOverflow = false;
- break;
+ /*
+ * Reset cursor position data to "start of query"
+ */
+ portal->atStart = true;
+ portal->atEnd = false; /* allow fetches */
+ portal->portalPos = 0;
+ portal->posOverflow = false;
+ break;
- case PORTAL_UTIL_SELECT:
+ case PORTAL_UTIL_SELECT:
- /*
- * We don't set query snapshot here, because PortalRunUtility
- * will take care of it.
- */
- portal->tupDesc =
- UtilityTupleDescriptor(((Query *) linitial(portal->parseTrees))->utilityStmt);
+ /*
+ * We don't set query snapshot here, because PortalRunUtility
+ * will take care of it.
+ */
+ portal->tupDesc =
+ UtilityTupleDescriptor(((Query *) linitial(portal->parseTrees))->utilityStmt);
- /*
- * Reset cursor position data to "start of query"
- */
- portal->atStart = true;
- portal->atEnd = false; /* allow fetches */
- portal->portalPos = 0;
- portal->posOverflow = false;
- break;
+ /*
+ * Reset cursor position data to "start of query"
+ */
+ portal->atStart = true;
+ portal->atEnd = false; /* allow fetches */
+ portal->portalPos = 0;
+ portal->posOverflow = false;
+ break;
- case PORTAL_MULTI_QUERY:
- /* Need do nothing now */
- portal->tupDesc = NULL;
- break;
+ case PORTAL_MULTI_QUERY:
+ /* Need do nothing now */
+ portal->tupDesc = NULL;
+ break;
+ }
}
+ PG_CATCH();
+ {
+ /* Uncaught error while executing portal: mark it dead */
+ portal->status = PORTAL_FAILED;
+
+ /* Restore global vars and propagate error */
+ ActivePortal = saveActivePortal;
+ CurrentResourceOwner = saveResourceOwner;
+ PortalContext = savePortalContext;
+
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
MemoryContextSwitchTo(oldContext);
@@ -449,91 +465,108 @@ PortalRun(Portal portal, long count,
portal->status = PORTAL_ACTIVE;
/*
- * Set global portal context pointers.
+ * Set up global portal context pointers.
*/
saveActivePortal = ActivePortal;
- ActivePortal = portal;
saveResourceOwner = CurrentResourceOwner;
- CurrentResourceOwner = portal->resowner;
savePortalContext = PortalContext;
- PortalContext = PortalGetHeapMemory(portal);
saveQueryContext = QueryContext;
- QueryContext = portal->queryContext;
+ PG_TRY();
+ {
+ ActivePortal = portal;
+ CurrentResourceOwner = portal->resowner;
+ PortalContext = PortalGetHeapMemory(portal);
+ QueryContext = portal->queryContext;
- oldContext = MemoryContextSwitchTo(PortalContext);
+ oldContext = MemoryContextSwitchTo(PortalContext);
- switch (portal->strategy)
- {
- case PORTAL_ONE_SELECT:
- (void) PortalRunSelect(portal, true, count, dest);
- /* we know the query is supposed to set the tag */
- if (completionTag && portal->commandTag)
- strcpy(completionTag, portal->commandTag);
+ switch (portal->strategy)
+ {
+ case PORTAL_ONE_SELECT:
+ (void) PortalRunSelect(portal, true, count, dest);
+ /* we know the query is supposed to set the tag */
+ if (completionTag && portal->commandTag)
+ strcpy(completionTag, portal->commandTag);
- /* Mark portal not active */
- portal->status = PORTAL_READY;
+ /* Mark portal not active */
+ portal->status = PORTAL_READY;
- /*
- * Since it's a forward fetch, say DONE iff atEnd is now true.
- */
- result = portal->atEnd;
- break;
+ /*
+ * Since it's a forward fetch, say DONE iff atEnd is now true.
+ */
+ result = portal->atEnd;
+ break;
- case PORTAL_UTIL_SELECT:
+ case PORTAL_UTIL_SELECT:
- /*
- * If we have not yet run the utility statement, do so,
- * storing its results in the portal's tuplestore.
- */
- if (!portal->portalUtilReady)
- {
- DestReceiver *treceiver;
-
- PortalCreateHoldStore(portal);
- treceiver = CreateDestReceiver(Tuplestore, portal);
- PortalRunUtility(portal, linitial(portal->parseTrees),
- treceiver, NULL);
- (*treceiver->rDestroy) (treceiver);
- portal->portalUtilReady = true;
- }
+ /*
+ * If we have not yet run the utility statement, do so,
+ * storing its results in the portal's tuplestore.
+ */
+ if (!portal->portalUtilReady)
+ {
+ DestReceiver *treceiver;
+
+ PortalCreateHoldStore(portal);
+ treceiver = CreateDestReceiver(Tuplestore, portal);
+ PortalRunUtility(portal, linitial(portal->parseTrees),
+ treceiver, NULL);
+ (*treceiver->rDestroy) (treceiver);
+ portal->portalUtilReady = true;
+ }
- /*
- * Now fetch desired portion of results.
- */
- (void) PortalRunSelect(portal, true, count, dest);
+ /*
+ * Now fetch desired portion of results.
+ */
+ (void) PortalRunSelect(portal, true, count, dest);
- /*
- * We know the query is supposed to set the tag; we assume
- * only the default tag is needed.
- */
- if (completionTag && portal->commandTag)
- strcpy(completionTag, portal->commandTag);
+ /*
+ * We know the query is supposed to set the tag; we assume
+ * only the default tag is needed.
+ */
+ if (completionTag && portal->commandTag)
+ strcpy(completionTag, portal->commandTag);
- /* Mark portal not active */
- portal->status = PORTAL_READY;
+ /* Mark portal not active */
+ portal->status = PORTAL_READY;
- /*
- * Since it's a forward fetch, say DONE iff atEnd is now true.
- */
- result = portal->atEnd;
- break;
+ /*
+ * Since it's a forward fetch, say DONE iff atEnd is now true.
+ */
+ result = portal->atEnd;
+ break;
- case PORTAL_MULTI_QUERY:
- PortalRunMulti(portal, dest, altdest, completionTag);
+ case PORTAL_MULTI_QUERY:
+ PortalRunMulti(portal, dest, altdest, completionTag);
- /* Prevent portal's commands from being re-executed */
- portal->status = PORTAL_DONE;
+ /* Prevent portal's commands from being re-executed */
+ portal->status = PORTAL_DONE;
- /* Always complete at end of RunMulti */
- result = true;
- break;
+ /* Always complete at end of RunMulti */
+ result = true;
+ break;
- default:
- elog(ERROR, "unrecognized portal strategy: %d",
- (int) portal->strategy);
- result = false; /* keep compiler quiet */
- break;
+ default:
+ elog(ERROR, "unrecognized portal strategy: %d",
+ (int) portal->strategy);
+ result = false; /* keep compiler quiet */
+ break;
+ }
+ }
+ PG_CATCH();
+ {
+ /* Uncaught error while executing portal: mark it dead */
+ portal->status = PORTAL_FAILED;
+
+ /* Restore global vars and propagate error */
+ ActivePortal = saveActivePortal;
+ CurrentResourceOwner = saveResourceOwner;
+ PortalContext = savePortalContext;
+ QueryContext = saveQueryContext;
+
+ PG_RE_THROW();
}
+ PG_END_TRY();
MemoryContextSwitchTo(oldContext);
@@ -970,30 +1003,47 @@ PortalRunFetch(Portal portal,
portal->status = PORTAL_ACTIVE;
/*
- * Set global portal context pointers.
+ * Set up global portal context pointers.
*/
saveActivePortal = ActivePortal;
- ActivePortal = portal;
saveResourceOwner = CurrentResourceOwner;
- CurrentResourceOwner = portal->resowner;
savePortalContext = PortalContext;
- PortalContext = PortalGetHeapMemory(portal);
saveQueryContext = QueryContext;
- QueryContext = portal->queryContext;
+ PG_TRY();
+ {
+ ActivePortal = portal;
+ CurrentResourceOwner = portal->resowner;
+ PortalContext = PortalGetHeapMemory(portal);
+ QueryContext = portal->queryContext;
- oldContext = MemoryContextSwitchTo(PortalContext);
+ oldContext = MemoryContextSwitchTo(PortalContext);
- switch (portal->strategy)
+ switch (portal->strategy)
+ {
+ case PORTAL_ONE_SELECT:
+ result = DoPortalRunFetch(portal, fdirection, count, dest);
+ break;
+
+ default:
+ elog(ERROR, "unsupported portal strategy");
+ result = 0; /* keep compiler quiet */
+ break;
+ }
+ }
+ PG_CATCH();
{
- case PORTAL_ONE_SELECT:
- result = DoPortalRunFetch(portal, fdirection, count, dest);
- break;
+ /* Uncaught error while executing portal: mark it dead */
+ portal->status = PORTAL_FAILED;
- default:
- elog(ERROR, "unsupported portal strategy");
- result = 0; /* keep compiler quiet */
- break;
+ /* Restore global vars and propagate error */
+ ActivePortal = saveActivePortal;
+ CurrentResourceOwner = saveResourceOwner;
+ PortalContext = savePortalContext;
+ QueryContext = saveQueryContext;
+
+ PG_RE_THROW();
}
+ PG_END_TRY();
MemoryContextSwitchTo(oldContext);