1 /*-------------------------------------------------------------------------
4 * POSTGRES process query command code
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.134 2010/01/02 16:57:52 momjian Exp $
13 *-------------------------------------------------------------------------
18 #include "access/xact.h"
19 #include "commands/prepare.h"
20 #include "commands/trigger.h"
21 #include "executor/tstoreReceiver.h"
22 #include "miscadmin.h"
24 #include "tcop/pquery.h"
25 #include "tcop/tcopprot.h"
26 #include "tcop/utility.h"
27 #include "utils/memutils.h"
28 #include "utils/snapmgr.h"
32 * ActivePortal is the currently executing Portal (the most closely nested,
33 * if there are several).
35 Portal ActivePortal = NULL;
38 static void ProcessQuery(PlannedStmt *plan,
39 const char *sourceText,
43 static void FillPortalStore(Portal portal, bool isTopLevel);
44 static uint32 RunFromStore(Portal portal, ScanDirection direction, long count,
46 static long PortalRunSelect(Portal portal, bool forward, long count,
48 static void PortalRunUtility(Portal portal, Node *utilityStmt, bool isTopLevel,
49 DestReceiver *dest, char *completionTag);
50 static void PortalRunMulti(Portal portal, bool isTopLevel,
51 DestReceiver *dest, DestReceiver *altdest,
53 static long DoPortalRunFetch(Portal portal,
54 FetchDirection fdirection,
57 static void DoPortalRewind(Portal portal);
64 CreateQueryDesc(PlannedStmt *plannedstmt,
65 const char *sourceText,
67 Snapshot crosscheck_snapshot,
70 int instrument_options)
72 QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
74 qd->operation = plannedstmt->commandType; /* operation */
75 qd->plannedstmt = plannedstmt; /* plan */
76 qd->utilitystmt = plannedstmt->utilityStmt; /* in case DECLARE CURSOR */
77 qd->sourceText = sourceText; /* query text */
78 qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */
79 /* RI check snapshot */
80 qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
81 qd->dest = dest; /* output dest */
82 qd->params = params; /* parameter values passed into query */
83 qd->instrument_options = instrument_options; /* instrumentation wanted? */
85 /* null these fields until set by ExecutorStart */
95 * CreateUtilityQueryDesc
98 CreateUtilityQueryDesc(Node *utilitystmt,
99 const char *sourceText,
102 ParamListInfo params)
104 QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
106 qd->operation = CMD_UTILITY; /* operation */
107 qd->plannedstmt = NULL;
108 qd->utilitystmt = utilitystmt; /* utility command */
109 qd->sourceText = sourceText; /* query text */
110 qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */
111 qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */
112 qd->dest = dest; /* output dest */
113 qd->params = params; /* parameter values passed into query */
114 qd->instrument_options = false; /* uninteresting for utilities */
116 /* null these fields until set by ExecutorStart */
119 qd->planstate = NULL;
120 qd->totaltime = NULL;
129 FreeQueryDesc(QueryDesc *qdesc)
131 /* Can't be a live query */
132 Assert(qdesc->estate == NULL);
134 /* forget our snapshots */
135 UnregisterSnapshot(qdesc->snapshot);
136 UnregisterSnapshot(qdesc->crosscheck_snapshot);
138 /* Only the QueryDesc itself need be freed */
145 * Execute a single plannable query within a PORTAL_MULTI_QUERY
146 * or PORTAL_ONE_RETURNING portal
148 * plan: the plan tree for the query
149 * sourceText: the source text of the query
150 * params: any parameters needed
151 * dest: where to send results
152 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
153 * in which to store a command completion status string.
155 * completionTag may be NULL if caller doesn't want a status string.
157 * Must be called in a memory context that will be reset or deleted on
158 * error; otherwise the executor's memory usage will be leaked.
161 ProcessQuery(PlannedStmt *plan,
162 const char *sourceText,
163 ParamListInfo params,
167 QueryDesc *queryDesc;
169 elog(DEBUG3, "ProcessQuery");
172 * Must always set a snapshot for plannable queries.
174 PushActiveSnapshot(GetTransactionSnapshot());
177 * Create the QueryDesc object
179 queryDesc = CreateQueryDesc(plan, sourceText,
180 GetActiveSnapshot(), InvalidSnapshot,
184 * Set up to collect AFTER triggers
186 AfterTriggerBeginQuery();
189 * Call ExecutorStart to prepare the plan for execution
191 ExecutorStart(queryDesc, 0);
194 * Run the plan to completion.
196 ExecutorRun(queryDesc, ForwardScanDirection, 0L);
199 * Build command completion status string, if caller wants one.
205 switch (queryDesc->operation)
208 strcpy(completionTag, "SELECT");
211 if (queryDesc->estate->es_processed == 1)
212 lastOid = queryDesc->estate->es_lastoid;
214 lastOid = InvalidOid;
215 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
216 "INSERT %u %u", lastOid, queryDesc->estate->es_processed);
219 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
220 "UPDATE %u", queryDesc->estate->es_processed);
223 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
224 "DELETE %u", queryDesc->estate->es_processed);
227 strcpy(completionTag, "???");
232 /* Now take care of any queued AFTER triggers */
233 AfterTriggerEndQuery(queryDesc->estate);
238 * Now, we close down all the scans and free allocated resources.
240 ExecutorEnd(queryDesc);
242 FreeQueryDesc(queryDesc);
246 * ChoosePortalStrategy
247 * Select portal execution strategy given the intended statement list.
249 * The list elements can be Querys, PlannedStmts, or utility statements.
250 * That's more general than portals need, but plancache.c uses this too.
252 * See the comments in portal.h.
255 ChoosePortalStrategy(List *stmts)
261 * PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the
262 * single-statement case, since there are no rewrite rules that can add
263 * auxiliary queries to a SELECT or a utility command.
265 if (list_length(stmts) == 1)
267 Node *stmt = (Node *) linitial(stmts);
269 if (IsA(stmt, Query))
271 Query *query = (Query *) stmt;
273 if (query->canSetTag)
275 if (query->commandType == CMD_SELECT &&
276 query->utilityStmt == NULL &&
277 query->intoClause == NULL)
278 return PORTAL_ONE_SELECT;
279 if (query->commandType == CMD_UTILITY &&
280 query->utilityStmt != NULL)
282 if (UtilityReturnsTuples(query->utilityStmt))
283 return PORTAL_UTIL_SELECT;
284 /* it can't be ONE_RETURNING, so give up */
285 return PORTAL_MULTI_QUERY;
289 else if (IsA(stmt, PlannedStmt))
291 PlannedStmt *pstmt = (PlannedStmt *) stmt;
293 if (pstmt->canSetTag)
295 if (pstmt->commandType == CMD_SELECT &&
296 pstmt->utilityStmt == NULL &&
297 pstmt->intoClause == NULL)
298 return PORTAL_ONE_SELECT;
303 /* must be a utility command; assume it's canSetTag */
304 if (UtilityReturnsTuples(stmt))
305 return PORTAL_UTIL_SELECT;
306 /* it can't be ONE_RETURNING, so give up */
307 return PORTAL_MULTI_QUERY;
312 * PORTAL_ONE_RETURNING has to allow auxiliary queries added by rewrite.
313 * Choose PORTAL_ONE_RETURNING if there is exactly one canSetTag query and
314 * it has a RETURNING list.
319 Node *stmt = (Node *) lfirst(lc);
321 if (IsA(stmt, Query))
323 Query *query = (Query *) stmt;
325 if (query->canSetTag)
328 return PORTAL_MULTI_QUERY; /* no need to look further */
329 if (query->returningList == NIL)
330 return PORTAL_MULTI_QUERY; /* no need to look further */
333 else if (IsA(stmt, PlannedStmt))
335 PlannedStmt *pstmt = (PlannedStmt *) stmt;
337 if (pstmt->canSetTag)
340 return PORTAL_MULTI_QUERY; /* no need to look further */
341 if (!pstmt->hasReturning)
342 return PORTAL_MULTI_QUERY; /* no need to look further */
345 /* otherwise, utility command, assumed not canSetTag */
348 return PORTAL_ONE_RETURNING;
350 /* Else, it's the general case... */
351 return PORTAL_MULTI_QUERY;
355 * FetchPortalTargetList
356 * Given a portal that returns tuples, extract the query targetlist.
357 * Returns NIL if the portal doesn't have a determinable targetlist.
359 * Note: do not modify the result.
362 FetchPortalTargetList(Portal portal)
364 /* no point in looking if we determined it doesn't return tuples */
365 if (portal->strategy == PORTAL_MULTI_QUERY)
367 /* get the primary statement and find out what it returns */
368 return FetchStatementTargetList(PortalGetPrimaryStmt(portal));
372 * FetchStatementTargetList
373 * Given a statement that returns tuples, extract the query targetlist.
374 * Returns NIL if the statement doesn't have a determinable targetlist.
376 * This can be applied to a Query, a PlannedStmt, or a utility statement.
377 * That's more general than portals need, but plancache.c uses this too.
379 * Note: do not modify the result.
381 * XXX be careful to keep this in sync with UtilityReturnsTuples.
384 FetchStatementTargetList(Node *stmt)
388 if (IsA(stmt, Query))
390 Query *query = (Query *) stmt;
392 if (query->commandType == CMD_UTILITY &&
393 query->utilityStmt != NULL)
395 /* transfer attention to utility statement */
396 stmt = query->utilityStmt;
400 if (query->commandType == CMD_SELECT &&
401 query->utilityStmt == NULL &&
402 query->intoClause == NULL)
403 return query->targetList;
404 if (query->returningList)
405 return query->returningList;
409 if (IsA(stmt, PlannedStmt))
411 PlannedStmt *pstmt = (PlannedStmt *) stmt;
413 if (pstmt->commandType == CMD_SELECT &&
414 pstmt->utilityStmt == NULL &&
415 pstmt->intoClause == NULL)
416 return pstmt->planTree->targetlist;
417 if (pstmt->hasReturning)
418 return pstmt->planTree->targetlist;
421 if (IsA(stmt, FetchStmt))
423 FetchStmt *fstmt = (FetchStmt *) stmt;
426 Assert(!fstmt->ismove);
427 subportal = GetPortalByName(fstmt->portalname);
428 Assert(PortalIsValid(subportal));
429 return FetchPortalTargetList(subportal);
431 if (IsA(stmt, ExecuteStmt))
433 ExecuteStmt *estmt = (ExecuteStmt *) stmt;
434 PreparedStatement *entry;
436 Assert(!estmt->into);
437 entry = FetchPreparedStatement(estmt->name, true);
438 return FetchPreparedStatementTargetList(entry);
445 * Prepare a portal for execution.
447 * Caller must already have created the portal, done PortalDefineQuery(),
448 * and adjusted portal options if needed. If parameters are needed by
449 * the query, they must be passed in here (caller is responsible for
450 * giving them appropriate lifetime).
452 * The caller can optionally pass a snapshot to be used; pass InvalidSnapshot
453 * for the normal behavior of setting a new snapshot. This parameter is
454 * presently ignored for non-PORTAL_ONE_SELECT portals (it's only intended
455 * to be used for cursors).
457 * On return, portal is ready to accept PortalRun() calls, and the result
458 * tupdesc (if any) is known.
461 PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot)
463 Portal saveActivePortal;
464 ResourceOwner saveResourceOwner;
465 MemoryContext savePortalContext;
466 MemoryContext oldContext;
467 QueryDesc *queryDesc;
470 AssertArg(PortalIsValid(portal));
471 AssertState(portal->status == PORTAL_DEFINED);
474 * Set up global portal context pointers.
476 saveActivePortal = ActivePortal;
477 saveResourceOwner = CurrentResourceOwner;
478 savePortalContext = PortalContext;
481 ActivePortal = portal;
482 CurrentResourceOwner = portal->resowner;
483 PortalContext = PortalGetHeapMemory(portal);
485 oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
487 /* Must remember portal param list, if any */
488 portal->portalParams = params;
491 * Determine the portal execution strategy
493 portal->strategy = ChoosePortalStrategy(portal->stmts);
496 * Fire her up according to the strategy
498 switch (portal->strategy)
500 case PORTAL_ONE_SELECT:
502 /* Must set snapshot before starting executor. */
504 PushActiveSnapshot(snapshot);
506 PushActiveSnapshot(GetTransactionSnapshot());
509 * Create QueryDesc in portal's context; for the moment, set
510 * the destination to DestNone.
512 queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts),
521 * We do *not* call AfterTriggerBeginQuery() here. We assume
522 * that a SELECT cannot queue any triggers. It would be messy
523 * to support triggers since the execution of the portal may
524 * be interleaved with other queries.
528 * If it's a scrollable cursor, executor needs to support
529 * REWIND and backwards scan.
531 if (portal->cursorOptions & CURSOR_OPT_SCROLL)
532 eflags = EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
534 eflags = 0; /* default run-to-completion flags */
537 * Call ExecutorStart to prepare the plan for execution
539 ExecutorStart(queryDesc, eflags);
542 * This tells PortalCleanup to shut down the executor
544 portal->queryDesc = queryDesc;
547 * Remember tuple descriptor (computed by ExecutorStart)
549 portal->tupDesc = queryDesc->tupDesc;
552 * Reset cursor position data to "start of query"
554 portal->atStart = true;
555 portal->atEnd = false; /* allow fetches */
556 portal->portalPos = 0;
557 portal->posOverflow = false;
562 case PORTAL_ONE_RETURNING:
565 * We don't start the executor until we are told to run the
566 * portal. We do need to set up the result tupdesc.
571 pstmt = (PlannedStmt *) PortalGetPrimaryStmt(portal);
572 Assert(IsA(pstmt, PlannedStmt));
573 Assert(pstmt->hasReturning);
575 ExecCleanTypeFromTL(pstmt->planTree->targetlist,
580 * Reset cursor position data to "start of query"
582 portal->atStart = true;
583 portal->atEnd = false; /* allow fetches */
584 portal->portalPos = 0;
585 portal->posOverflow = false;
588 case PORTAL_UTIL_SELECT:
591 * We don't set snapshot here, because PortalRunUtility will
592 * take care of it if needed.
595 Node *ustmt = PortalGetPrimaryStmt(portal);
597 Assert(!IsA(ustmt, PlannedStmt));
598 portal->tupDesc = UtilityTupleDescriptor(ustmt);
602 * Reset cursor position data to "start of query"
604 portal->atStart = true;
605 portal->atEnd = false; /* allow fetches */
606 portal->portalPos = 0;
607 portal->posOverflow = false;
610 case PORTAL_MULTI_QUERY:
611 /* Need do nothing now */
612 portal->tupDesc = NULL;
618 /* Uncaught error while executing portal: mark it dead */
619 portal->status = PORTAL_FAILED;
621 /* Restore global vars and propagate error */
622 ActivePortal = saveActivePortal;
623 CurrentResourceOwner = saveResourceOwner;
624 PortalContext = savePortalContext;
630 MemoryContextSwitchTo(oldContext);
632 ActivePortal = saveActivePortal;
633 CurrentResourceOwner = saveResourceOwner;
634 PortalContext = savePortalContext;
636 portal->status = PORTAL_READY;
640 * PortalSetResultFormat
641 * Select the format codes for a portal's output.
643 * This must be run after PortalStart for a portal that will be read by
644 * a DestRemote or DestRemoteExecute destination. It is not presently needed
645 * for other destination types.
647 * formats[] is the client format request, as per Bind message conventions.
650 PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)
655 /* Do nothing if portal won't return tuples */
656 if (portal->tupDesc == NULL)
658 natts = portal->tupDesc->natts;
659 portal->formats = (int16 *)
660 MemoryContextAlloc(PortalGetHeapMemory(portal),
661 natts * sizeof(int16));
664 /* format specified for each column */
665 if (nFormats != natts)
667 (errcode(ERRCODE_PROTOCOL_VIOLATION),
668 errmsg("bind message has %d result formats but query has %d columns",
670 memcpy(portal->formats, formats, natts * sizeof(int16));
672 else if (nFormats > 0)
674 /* single format specified, use for all columns */
675 int16 format1 = formats[0];
677 for (i = 0; i < natts; i++)
678 portal->formats[i] = format1;
682 /* use default format for all columns */
683 for (i = 0; i < natts; i++)
684 portal->formats[i] = 0;
690 * Run a portal's query or queries.
692 * count <= 0 is interpreted as a no-op: the destination gets started up
693 * and shut down, but nothing else happens. Also, count == FETCH_ALL is
694 * interpreted as "all rows". Note that count is ignored in multi-query
695 * situations, where we always run the portal to completion.
697 * isTopLevel: true if query is being executed at backend "top level"
698 * (that is, directly from a client command message)
700 * dest: where to send output of primary (canSetTag) query
702 * altdest: where to send output of non-primary queries
704 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
705 * in which to store a command completion status string.
706 * May be NULL if caller doesn't want a status string.
708 * Returns TRUE if the portal's execution is complete, FALSE if it was
709 * suspended due to exhaustion of the count parameter.
712 PortalRun(Portal portal, long count, bool isTopLevel,
713 DestReceiver *dest, DestReceiver *altdest,
717 ResourceOwner saveTopTransactionResourceOwner;
718 MemoryContext saveTopTransactionContext;
719 Portal saveActivePortal;
720 ResourceOwner saveResourceOwner;
721 MemoryContext savePortalContext;
722 MemoryContext saveMemoryContext;
724 AssertArg(PortalIsValid(portal));
726 TRACE_POSTGRESQL_QUERY_EXECUTE_START();
728 /* Initialize completion tag to empty string */
730 completionTag[0] = '\0';
732 if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY)
734 elog(DEBUG3, "PortalRun");
735 /* PORTAL_MULTI_QUERY logs its own stats per query */
740 * Check for improper portal use, and mark portal active.
742 if (portal->status != PORTAL_READY)
744 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
745 errmsg("portal \"%s\" cannot be run", portal->name)));
746 portal->status = PORTAL_ACTIVE;
749 * Set up global portal context pointers.
751 * We have to play a special game here to support utility commands like
752 * VACUUM and CLUSTER, which internally start and commit transactions.
753 * When we are called to execute such a command, CurrentResourceOwner will
754 * be pointing to the TopTransactionResourceOwner --- which will be
755 * destroyed and replaced in the course of the internal commit and
756 * restart. So we need to be prepared to restore it as pointing to the
757 * exit-time TopTransactionResourceOwner. (Ain't that ugly? This idea of
758 * internally starting whole new transactions is not good.)
759 * CurrentMemoryContext has a similar problem, but the other pointers we
760 * save here will be NULL or pointing to longer-lived objects.
762 saveTopTransactionResourceOwner = TopTransactionResourceOwner;
763 saveTopTransactionContext = TopTransactionContext;
764 saveActivePortal = ActivePortal;
765 saveResourceOwner = CurrentResourceOwner;
766 savePortalContext = PortalContext;
767 saveMemoryContext = CurrentMemoryContext;
770 ActivePortal = portal;
771 CurrentResourceOwner = portal->resowner;
772 PortalContext = PortalGetHeapMemory(portal);
774 MemoryContextSwitchTo(PortalContext);
776 switch (portal->strategy)
778 case PORTAL_ONE_SELECT:
779 (void) PortalRunSelect(portal, true, count, dest);
781 /* we know the query is supposed to set the tag */
782 if (completionTag && portal->commandTag)
783 strcpy(completionTag, portal->commandTag);
785 /* Mark portal not active */
786 portal->status = PORTAL_READY;
789 * Since it's a forward fetch, say DONE iff atEnd is now true.
791 result = portal->atEnd;
794 case PORTAL_ONE_RETURNING:
795 case PORTAL_UTIL_SELECT:
798 * If we have not yet run the command, do so, storing its
799 * results in the portal's tuplestore.
801 if (!portal->holdStore)
802 FillPortalStore(portal, isTopLevel);
805 * Now fetch desired portion of results.
807 (void) PortalRunSelect(portal, true, count, dest);
809 /* we know the query is supposed to set the tag */
810 if (completionTag && portal->commandTag)
811 strcpy(completionTag, portal->commandTag);
813 /* Mark portal not active */
814 portal->status = PORTAL_READY;
817 * Since it's a forward fetch, say DONE iff atEnd is now true.
819 result = portal->atEnd;
822 case PORTAL_MULTI_QUERY:
823 PortalRunMulti(portal, isTopLevel,
824 dest, altdest, completionTag);
826 /* Prevent portal's commands from being re-executed */
827 portal->status = PORTAL_DONE;
829 /* Always complete at end of RunMulti */
834 elog(ERROR, "unrecognized portal strategy: %d",
835 (int) portal->strategy);
836 result = false; /* keep compiler quiet */
842 /* Uncaught error while executing portal: mark it dead */
843 portal->status = PORTAL_FAILED;
845 /* Restore global vars and propagate error */
846 if (saveMemoryContext == saveTopTransactionContext)
847 MemoryContextSwitchTo(TopTransactionContext);
849 MemoryContextSwitchTo(saveMemoryContext);
850 ActivePortal = saveActivePortal;
851 if (saveResourceOwner == saveTopTransactionResourceOwner)
852 CurrentResourceOwner = TopTransactionResourceOwner;
854 CurrentResourceOwner = saveResourceOwner;
855 PortalContext = savePortalContext;
861 if (saveMemoryContext == saveTopTransactionContext)
862 MemoryContextSwitchTo(TopTransactionContext);
864 MemoryContextSwitchTo(saveMemoryContext);
865 ActivePortal = saveActivePortal;
866 if (saveResourceOwner == saveTopTransactionResourceOwner)
867 CurrentResourceOwner = TopTransactionResourceOwner;
869 CurrentResourceOwner = saveResourceOwner;
870 PortalContext = savePortalContext;
872 if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY)
873 ShowUsage("EXECUTOR STATISTICS");
875 TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();
882 * Execute a portal's query in PORTAL_ONE_SELECT mode, and also
883 * when fetching from a completed holdStore in PORTAL_ONE_RETURNING
884 * and PORTAL_UTIL_SELECT cases.
886 * This handles simple N-rows-forward-or-backward cases. For more complex
887 * nonsequential access to a portal, see PortalRunFetch.
889 * count <= 0 is interpreted as a no-op: the destination gets started up
890 * and shut down, but nothing else happens. Also, count == FETCH_ALL is
891 * interpreted as "all rows".
893 * Caller must already have validated the Portal and done appropriate
894 * setup (cf. PortalRun).
896 * Returns number of rows processed (suitable for use in result tag)
899 PortalRunSelect(Portal portal,
904 QueryDesc *queryDesc;
905 ScanDirection direction;
909 * NB: queryDesc will be NULL if we are fetching from a held cursor or a
910 * completed utility query; can't use it in that path.
912 queryDesc = PortalGetQueryDesc(portal);
914 /* Caller messed up if we have neither a ready query nor held data. */
915 Assert(queryDesc || portal->holdStore);
918 * Force the queryDesc destination to the right thing. This supports
919 * MOVE, for example, which will pass in dest = DestNone. This is okay to
920 * change as long as we do it on every fetch. (The Executor must not
921 * assume that dest never changes.)
924 queryDesc->dest = dest;
927 * Determine which direction to go in, and check to see if we're already
928 * at the end of the available tuples in that direction. If so, set the
929 * direction to NoMovement to avoid trying to fetch any tuples. (This
930 * check exists because not all plan node types are robust about being
931 * called again if they've already returned NULL once.) Then call the
932 * executor (we must not skip this, because the destination needs to see a
933 * setup and shutdown even if no tuples are available). Finally, update
934 * the portal position state depending on the number of tuples that were
939 if (portal->atEnd || count <= 0)
940 direction = NoMovementScanDirection;
942 direction = ForwardScanDirection;
944 /* In the executor, zero count processes all rows */
945 if (count == FETCH_ALL)
948 if (portal->holdStore)
949 nprocessed = RunFromStore(portal, direction, count, dest);
952 PushActiveSnapshot(queryDesc->snapshot);
953 ExecutorRun(queryDesc, direction, count);
954 nprocessed = queryDesc->estate->es_processed;
958 if (!ScanDirectionIsNoMovement(direction))
963 portal->atStart = false; /* OK to go backward now */
965 (unsigned long) nprocessed < (unsigned long) count)
966 portal->atEnd = true; /* we retrieved 'em all */
967 oldPos = portal->portalPos;
968 portal->portalPos += nprocessed;
969 /* portalPos doesn't advance when we fall off the end */
970 if (portal->portalPos < oldPos)
971 portal->posOverflow = true;
976 if (portal->cursorOptions & CURSOR_OPT_NO_SCROLL)
978 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
979 errmsg("cursor can only scan forward"),
980 errhint("Declare it with SCROLL option to enable backward scan.")));
982 if (portal->atStart || count <= 0)
983 direction = NoMovementScanDirection;
985 direction = BackwardScanDirection;
987 /* In the executor, zero count processes all rows */
988 if (count == FETCH_ALL)
991 if (portal->holdStore)
992 nprocessed = RunFromStore(portal, direction, count, dest);
995 PushActiveSnapshot(queryDesc->snapshot);
996 ExecutorRun(queryDesc, direction, count);
997 nprocessed = queryDesc->estate->es_processed;
1001 if (!ScanDirectionIsNoMovement(direction))
1003 if (nprocessed > 0 && portal->atEnd)
1005 portal->atEnd = false; /* OK to go forward now */
1006 portal->portalPos++; /* adjust for endpoint case */
1009 (unsigned long) nprocessed < (unsigned long) count)
1011 portal->atStart = true; /* we retrieved 'em all */
1012 portal->portalPos = 0;
1013 portal->posOverflow = false;
1019 oldPos = portal->portalPos;
1020 portal->portalPos -= nprocessed;
1021 if (portal->portalPos > oldPos ||
1022 portal->portalPos <= 0)
1023 portal->posOverflow = true;
1033 * Run the query and load result tuples into the portal's tuple store.
1035 * This is used for PORTAL_ONE_RETURNING and PORTAL_UTIL_SELECT cases only.
1038 FillPortalStore(Portal portal, bool isTopLevel)
1040 DestReceiver *treceiver;
1041 char completionTag[COMPLETION_TAG_BUFSIZE];
1043 PortalCreateHoldStore(portal);
1044 treceiver = CreateDestReceiver(DestTuplestore);
1045 SetTuplestoreDestReceiverParams(treceiver,
1047 portal->holdContext,
1050 completionTag[0] = '\0';
1052 switch (portal->strategy)
1054 case PORTAL_ONE_RETURNING:
1057 * Run the portal to completion just as for the default
1058 * MULTI_QUERY case, but send the primary query's output to the
1059 * tuplestore. Auxiliary query outputs are discarded.
1061 PortalRunMulti(portal, isTopLevel,
1062 treceiver, None_Receiver, completionTag);
1065 case PORTAL_UTIL_SELECT:
1066 PortalRunUtility(portal, (Node *) linitial(portal->stmts),
1067 isTopLevel, treceiver, completionTag);
1071 elog(ERROR, "unsupported portal strategy: %d",
1072 (int) portal->strategy);
1076 /* Override default completion tag with actual command result */
1077 if (completionTag[0] != '\0')
1078 portal->commandTag = pstrdup(completionTag);
1080 (*treceiver->rDestroy) (treceiver);
1085 * Fetch tuples from the portal's tuple store.
1087 * Calling conventions are similar to ExecutorRun, except that we
1088 * do not depend on having a queryDesc or estate. Therefore we return the
1089 * number of tuples processed as the result, not in estate->es_processed.
1091 * One difference from ExecutorRun is that the destination receiver functions
1092 * are run in the caller's memory context (since we have no estate). Watch
1093 * out for memory leaks.
1096 RunFromStore(Portal portal, ScanDirection direction, long count,
1099 long current_tuple_count = 0;
1100 TupleTableSlot *slot;
1102 slot = MakeSingleTupleTableSlot(portal->tupDesc);
1104 (*dest->rStartup) (dest, CMD_SELECT, portal->tupDesc);
1106 if (ScanDirectionIsNoMovement(direction))
1108 /* do nothing except start/stop the destination */
1112 bool forward = ScanDirectionIsForward(direction);
1116 MemoryContext oldcontext;
1119 oldcontext = MemoryContextSwitchTo(portal->holdContext);
1121 ok = tuplestore_gettupleslot(portal->holdStore, forward, false,
1124 MemoryContextSwitchTo(oldcontext);
1129 (*dest->receiveSlot) (slot, dest);
1131 ExecClearTuple(slot);
1134 * check our tuple count.. if we've processed the proper number
1135 * then quit, else loop again and process more tuples. Zero count
1138 current_tuple_count++;
1139 if (count && count == current_tuple_count)
1144 (*dest->rShutdown) (dest);
1146 ExecDropSingleTupleTableSlot(slot);
1148 return (uint32) current_tuple_count;
1153 * Execute a utility statement inside a portal.
1156 PortalRunUtility(Portal portal, Node *utilityStmt, bool isTopLevel,
1157 DestReceiver *dest, char *completionTag)
1159 bool active_snapshot_set;
1161 elog(DEBUG3, "ProcessUtility");
1164 * Set snapshot if utility stmt needs one. Most reliable way to do this
1165 * seems to be to enumerate those that do not need one; this is a short
1166 * list. Transaction control, LOCK, and SET must *not* set a snapshot
1167 * since they need to be executable at the start of a serializable
1168 * transaction without freezing a snapshot. By extension we allow SHOW
1169 * not to set a snapshot. The other stmts listed are just efficiency
1170 * hacks. Beware of listing anything that can modify the database --- if,
1171 * say, it has to update an index with expressions that invoke
1172 * user-defined functions, then it had better have a snapshot.
1174 if (!(IsA(utilityStmt, TransactionStmt) ||
1175 IsA(utilityStmt, LockStmt) ||
1176 IsA(utilityStmt, VariableSetStmt) ||
1177 IsA(utilityStmt, VariableShowStmt) ||
1178 IsA(utilityStmt, ConstraintsSetStmt) ||
1179 /* efficiency hacks from here down */
1180 IsA(utilityStmt, FetchStmt) ||
1181 IsA(utilityStmt, ListenStmt) ||
1182 IsA(utilityStmt, NotifyStmt) ||
1183 IsA(utilityStmt, UnlistenStmt) ||
1184 IsA(utilityStmt, CheckPointStmt)))
1186 PushActiveSnapshot(GetTransactionSnapshot());
1187 active_snapshot_set = true;
1190 active_snapshot_set = false;
1192 ProcessUtility(utilityStmt,
1194 portal->portalParams,
1199 /* Some utility statements may change context on us */
1200 MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1203 * Some utility commands may pop the ActiveSnapshot stack from under us,
1204 * so we only pop the stack if we actually see a snapshot set. Note that
1205 * the set of utility commands that do this must be the same set
1206 * disallowed to run inside a transaction; otherwise, we could be popping
1207 * a snapshot that belongs to some other operation.
1209 if (active_snapshot_set && ActiveSnapshotSet())
1210 PopActiveSnapshot();
1215 * Execute a portal's queries in the general case (multi queries
1216 * or non-SELECT-like queries)
1219 PortalRunMulti(Portal portal, bool isTopLevel,
1220 DestReceiver *dest, DestReceiver *altdest,
1221 char *completionTag)
1223 ListCell *stmtlist_item;
1226 * If the destination is DestRemoteExecute, change to DestNone. The
1227 * reason is that the client won't be expecting any tuples, and indeed has
1228 * no way to know what they are, since there is no provision for Describe
1229 * to send a RowDescription message when this portal execution strategy is
1230 * in effect. This presently will only affect SELECT commands added to
1231 * non-SELECT queries by rewrite rules: such commands will be executed,
1232 * but the results will be discarded unless you use "simple Query"
1235 if (dest->mydest == DestRemoteExecute)
1236 dest = None_Receiver;
1237 if (altdest->mydest == DestRemoteExecute)
1238 altdest = None_Receiver;
1241 * Loop to handle the individual queries generated from a single parsetree
1242 * by analysis and rewrite.
1244 foreach(stmtlist_item, portal->stmts)
1246 Node *stmt = (Node *) lfirst(stmtlist_item);
1249 * If we got a cancel signal in prior command, quit
1251 CHECK_FOR_INTERRUPTS();
1253 if (IsA(stmt, PlannedStmt) &&
1254 ((PlannedStmt *) stmt)->utilityStmt == NULL)
1257 * process a plannable query.
1259 PlannedStmt *pstmt = (PlannedStmt *) stmt;
1261 TRACE_POSTGRESQL_QUERY_EXECUTE_START();
1263 if (log_executor_stats)
1266 if (pstmt->canSetTag)
1268 /* statement can set tag string */
1271 portal->portalParams,
1272 dest, completionTag);
1276 /* stmt added by rewrite cannot set tag */
1279 portal->portalParams,
1283 if (log_executor_stats)
1284 ShowUsage("EXECUTOR STATISTICS");
1286 TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();
1291 * process utility functions (create, destroy, etc..)
1293 * These are assumed canSetTag if they're the only stmt in the
1296 if (list_length(portal->stmts) == 1)
1297 PortalRunUtility(portal, stmt, isTopLevel, dest, completionTag);
1299 PortalRunUtility(portal, stmt, isTopLevel, altdest, NULL);
1303 * Increment command counter between queries, but not after the last
1306 if (lnext(stmtlist_item) != NULL)
1307 CommandCounterIncrement();
1310 * Clear subsidiary contexts to recover temporary memory.
1312 Assert(PortalGetHeapMemory(portal) == CurrentMemoryContext);
1314 MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
1318 * If a command completion tag was supplied, use it. Otherwise use the
1319 * portal's commandTag as the default completion tag.
1321 * Exception: clients will expect INSERT/UPDATE/DELETE tags to have
1322 * counts, so fake something up if necessary. (This could happen if the
1323 * original query was replaced by a DO INSTEAD rule.)
1325 if (completionTag && completionTag[0] == '\0')
1327 if (portal->commandTag)
1328 strcpy(completionTag, portal->commandTag);
1329 if (strcmp(completionTag, "INSERT") == 0)
1330 strcpy(completionTag, "INSERT 0 0");
1331 else if (strcmp(completionTag, "UPDATE") == 0)
1332 strcpy(completionTag, "UPDATE 0");
1333 else if (strcmp(completionTag, "DELETE") == 0)
1334 strcpy(completionTag, "DELETE 0");
1340 * Variant form of PortalRun that supports SQL FETCH directions.
1342 * Note: we presently assume that no callers of this want isTopLevel = true.
1344 * Returns number of rows processed (suitable for use in result tag)
1347 PortalRunFetch(Portal portal,
1348 FetchDirection fdirection,
1353 Portal saveActivePortal;
1354 ResourceOwner saveResourceOwner;
1355 MemoryContext savePortalContext;
1356 MemoryContext oldContext;
1358 AssertArg(PortalIsValid(portal));
1361 * Check for improper portal use, and mark portal active.
1363 if (portal->status != PORTAL_READY)
1365 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1366 errmsg("portal \"%s\" cannot be run", portal->name)));
1367 portal->status = PORTAL_ACTIVE;
1370 * Set up global portal context pointers.
1372 saveActivePortal = ActivePortal;
1373 saveResourceOwner = CurrentResourceOwner;
1374 savePortalContext = PortalContext;
1377 ActivePortal = portal;
1378 CurrentResourceOwner = portal->resowner;
1379 PortalContext = PortalGetHeapMemory(portal);
1381 oldContext = MemoryContextSwitchTo(PortalContext);
1383 switch (portal->strategy)
1385 case PORTAL_ONE_SELECT:
1386 result = DoPortalRunFetch(portal, fdirection, count, dest);
1389 case PORTAL_ONE_RETURNING:
1390 case PORTAL_UTIL_SELECT:
1393 * If we have not yet run the command, do so, storing its
1394 * results in the portal's tuplestore.
1396 if (!portal->holdStore)
1397 FillPortalStore(portal, false /* isTopLevel */ );
1400 * Now fetch desired portion of results.
1402 result = DoPortalRunFetch(portal, fdirection, count, dest);
1406 elog(ERROR, "unsupported portal strategy");
1407 result = 0; /* keep compiler quiet */
1413 /* Uncaught error while executing portal: mark it dead */
1414 portal->status = PORTAL_FAILED;
1416 /* Restore global vars and propagate error */
1417 ActivePortal = saveActivePortal;
1418 CurrentResourceOwner = saveResourceOwner;
1419 PortalContext = savePortalContext;
1425 MemoryContextSwitchTo(oldContext);
1427 /* Mark portal not active */
1428 portal->status = PORTAL_READY;
1430 ActivePortal = saveActivePortal;
1431 CurrentResourceOwner = saveResourceOwner;
1432 PortalContext = savePortalContext;
1439 * Guts of PortalRunFetch --- the portal context is already set up
1441 * Returns number of rows processed (suitable for use in result tag)
1444 DoPortalRunFetch(Portal portal,
1445 FetchDirection fdirection,
1451 Assert(portal->strategy == PORTAL_ONE_SELECT ||
1452 portal->strategy == PORTAL_ONE_RETURNING ||
1453 portal->strategy == PORTAL_UTIL_SELECT);
1460 fdirection = FETCH_BACKWARD;
1463 /* fall out of switch to share code with FETCH_BACKWARD */
1465 case FETCH_BACKWARD:
1468 fdirection = FETCH_FORWARD;
1471 /* fall out of switch to share code with FETCH_FORWARD */
1473 case FETCH_ABSOLUTE:
1477 * Definition: Rewind to start, advance count-1 rows, return
1478 * next row (if any). In practice, if the goal is less than
1479 * halfway back to the start, it's better to scan from where
1480 * we are. In any case, we arrange to fetch the target row
1483 if (portal->posOverflow || portal->portalPos == LONG_MAX ||
1484 count - 1 <= portal->portalPos / 2)
1486 DoPortalRewind(portal);
1488 PortalRunSelect(portal, true, count - 1,
1493 long pos = portal->portalPos;
1496 pos++; /* need one extra fetch if off end */
1498 PortalRunSelect(portal, false, pos - count + 1,
1500 else if (count > pos + 1)
1501 PortalRunSelect(portal, true, count - pos - 1,
1504 return PortalRunSelect(portal, true, 1L, dest);
1509 * Definition: Advance to end, back up abs(count)-1 rows,
1510 * return prior row (if any). We could optimize this if we
1511 * knew in advance where the end was, but typically we won't.
1512 * (Is it worth considering case where count > half of size of
1513 * query? We could rewind once we know the size ...)
1515 PortalRunSelect(portal, true, FETCH_ALL, None_Receiver);
1517 PortalRunSelect(portal, false, -count - 1, None_Receiver);
1518 return PortalRunSelect(portal, false, 1L, dest);
1523 /* Rewind to start, return zero rows */
1524 DoPortalRewind(portal);
1525 return PortalRunSelect(portal, true, 0L, dest);
1528 case FETCH_RELATIVE:
1532 * Definition: advance count-1 rows, return next row (if any).
1535 PortalRunSelect(portal, true, count - 1, None_Receiver);
1536 return PortalRunSelect(portal, true, 1L, dest);
1541 * Definition: back up abs(count)-1 rows, return prior row (if
1545 PortalRunSelect(portal, false, -count - 1, None_Receiver);
1546 return PortalRunSelect(portal, false, 1L, dest);
1551 /* Same as FETCH FORWARD 0, so fall out of switch */
1552 fdirection = FETCH_FORWARD;
1556 elog(ERROR, "bogus direction");
1561 * Get here with fdirection == FETCH_FORWARD or FETCH_BACKWARD, and count
1564 forward = (fdirection == FETCH_FORWARD);
1567 * Zero count means to re-fetch the current row, if any (per SQL92)
1573 /* Are we sitting on a row? */
1574 on_row = (!portal->atStart && !portal->atEnd);
1576 if (dest->mydest == DestNone)
1578 /* MOVE 0 returns 0/1 based on if FETCH 0 would return a row */
1579 return on_row ? 1L : 0L;
1584 * If we are sitting on a row, back up one so we can re-fetch it.
1585 * If we are not sitting on a row, we still have to start up and
1586 * shut down the executor so that the destination is initialized
1587 * and shut down correctly; so keep going. To PortalRunSelect,
1588 * count == 0 means we will retrieve no row.
1592 PortalRunSelect(portal, false, 1L, None_Receiver);
1593 /* Set up to fetch one row forward */
1601 * Optimize MOVE BACKWARD ALL into a Rewind.
1603 if (!forward && count == FETCH_ALL && dest->mydest == DestNone)
1605 long result = portal->portalPos;
1607 if (result > 0 && !portal->atEnd)
1609 DoPortalRewind(portal);
1610 /* result is bogus if pos had overflowed, but it's best we can do */
1614 return PortalRunSelect(portal, forward, count, dest);
1618 * DoPortalRewind - rewind a Portal to starting point
1621 DoPortalRewind(Portal portal)
1623 if (portal->holdStore)
1625 MemoryContext oldcontext;
1627 oldcontext = MemoryContextSwitchTo(portal->holdContext);
1628 tuplestore_rescan(portal->holdStore);
1629 MemoryContextSwitchTo(oldcontext);
1631 if (PortalGetQueryDesc(portal))
1632 ExecutorRewind(PortalGetQueryDesc(portal));
1634 portal->atStart = true;
1635 portal->atEnd = false;
1636 portal->portalPos = 0;
1637 portal->posOverflow = false;