diff options
Diffstat (limited to 'src/backend/tcop/pquery.c')
-rw-r--r-- | src/backend/tcop/pquery.c | 348 |
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); |