* PortalRun * Run a portal's query or queries. * * count <= 0 is interpreted as a no-op: the destination gets started up * and shut down, but nothing else happens. Also, count == FETCH_ALL is * interpreted as "all rows". (cf FetchStmt.howMany) * Note that count is ignored in multi-query * * isTopLevel: true if query is being executed at backend "top level" * (that is, directly from a c
| 889 | * suspended due to exhaustion of the count parameter. |
| 890 | */ |
| 891 | bool |
| 892 | PortalRun(Portal portal, int64 count, bool isTopLevel, bool run_once, |
| 893 | DestReceiver *dest, DestReceiver *altdest, |
| 894 | QueryCompletion *qc) |
| 895 | { |
| 896 | bool result = false; |
| 897 | uint64 nprocessed; |
| 898 | ResourceOwner saveTopTransactionResourceOwner; |
| 899 | MemoryContext saveTopTransactionContext; |
| 900 | Portal saveActivePortal; |
| 901 | ResourceOwner saveResourceOwner; |
| 902 | MemoryContext savePortalContext; |
| 903 | MemoryContext saveMemoryContext; |
| 904 | |
| 905 | AssertArg(PortalIsValid(portal)); |
| 906 | |
| 907 | TRACE_POSTGRESQL_QUERY_EXECUTE_START(); |
| 908 | |
| 909 | /* Initialize empty completion data */ |
| 910 | if (qc) |
| 911 | InitializeQueryCompletion(qc); |
| 912 | |
| 913 | if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY) |
| 914 | { |
| 915 | elog(DEBUG3, "PortalRun"); |
| 916 | /* PORTAL_MULTI_QUERY logs its own stats per query */ |
| 917 | ResetUsage(); |
| 918 | } |
| 919 | |
| 920 | /* |
| 921 | * Check for improper portal use, and mark portal active. |
| 922 | */ |
| 923 | MarkPortalActive(portal); |
| 924 | |
| 925 | /* Set run_once flag. Shouldn't be clear if previously set. */ |
| 926 | Assert(!portal->run_once || run_once); |
| 927 | portal->run_once = run_once; |
| 928 | |
| 929 | /* |
| 930 | * Set up global portal context pointers. |
| 931 | * |
| 932 | * We have to play a special game here to support utility commands like |
| 933 | * VACUUM and CLUSTER, which internally start and commit transactions. |
| 934 | * When we are called to execute such a command, CurrentResourceOwner will |
| 935 | * be pointing to the TopTransactionResourceOwner --- which will be |
| 936 | * destroyed and replaced in the course of the internal commit and |
| 937 | * restart. So we need to be prepared to restore it as pointing to the |
| 938 | * exit-time TopTransactionResourceOwner. (Ain't that ugly? This idea of |
| 939 | * internally starting whole new transactions is not good.) |
| 940 | * CurrentMemoryContext has a similar problem, but the other pointers we |
| 941 | * save here will be NULL or pointing to longer-lived objects. |
| 942 | */ |
| 943 | saveTopTransactionResourceOwner = TopTransactionResourceOwner; |
| 944 | saveTopTransactionContext = TopTransactionContext; |
| 945 | saveActivePortal = ActivePortal; |
| 946 | saveResourceOwner = CurrentResourceOwner; |
| 947 | savePortalContext = PortalContext; |
| 948 | saveMemoryContext = CurrentMemoryContext; |
no test coverage detected