PostgreSQL Source Code git master
portal.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * portal.h
4 * POSTGRES portal definitions.
5 *
6 * A portal is an abstraction which represents the execution state of
7 * a running or runnable query. Portals support both SQL-level CURSORs
8 * and protocol-level portals.
9 *
10 * Scrolling (nonsequential access) and suspension of execution are allowed
11 * only for portals that contain a single SELECT-type query. We do not want
12 * to let the client suspend an update-type query partway through! Because
13 * the query rewriter does not allow arbitrary ON SELECT rewrite rules,
14 * only queries that were originally update-type could produce multiple
15 * plan trees; so the restriction to a single query is not a problem
16 * in practice.
17 *
18 * For SQL cursors, we support three kinds of scroll behavior:
19 *
20 * (1) Neither NO SCROLL nor SCROLL was specified: to remain backward
21 * compatible, we allow backward fetches here, unless it would
22 * impose additional runtime overhead to do so.
23 *
24 * (2) NO SCROLL was specified: don't allow any backward fetches.
25 *
26 * (3) SCROLL was specified: allow all kinds of backward fetches, even
27 * if we need to take a performance hit to do so. (The planner sticks
28 * a Materialize node atop the query plan if needed.)
29 *
30 * Case #1 is converted to #2 or #3 by looking at the query itself and
31 * determining if scrollability can be supported without additional
32 * overhead.
33 *
34 * Protocol-level portals have no nonsequential-fetch API and so the
35 * distinction doesn't matter for them. They are always initialized
36 * to look like NO SCROLL cursors.
37 *
38 *
39 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
40 * Portions Copyright (c) 1994, Regents of the University of California
41 *
42 * src/include/utils/portal.h
43 *
44 *-------------------------------------------------------------------------
45 */
46#ifndef PORTAL_H
47#define PORTAL_H
48
49#include "datatype/timestamp.h"
50#include "executor/execdesc.h"
51#include "tcop/cmdtag.h"
52#include "utils/plancache.h"
53#include "utils/resowner.h"
54
55/*
56 * We have several execution strategies for Portals, depending on what
57 * query or queries are to be executed. (Note: in all cases, a Portal
58 * executes just a single source-SQL query, and thus produces just a
59 * single result from the user's viewpoint. However, the rule rewriter
60 * may expand the single source query to zero or many actual queries.)
61 *
62 * PORTAL_ONE_SELECT: the portal contains one single SELECT query. We run
63 * the Executor incrementally as results are demanded. This strategy also
64 * supports holdable cursors (the Executor results can be dumped into a
65 * tuplestore for access after transaction completion).
66 *
67 * PORTAL_ONE_RETURNING: the portal contains a single INSERT/UPDATE/DELETE/
68 * MERGE query with a RETURNING clause (plus possibly auxiliary queries added
69 * by rule rewriting). On first execution, we run the portal to completion
70 * and dump the primary query's results into the portal tuplestore; the
71 * results are then returned to the client as demanded. (We can't support
72 * suspension of the query partway through, because the AFTER TRIGGER code
73 * can't cope, and also because we don't want to risk failing to execute
74 * all the auxiliary queries.)
75 *
76 * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but
77 * it has data-modifying CTEs. This is currently treated the same as the
78 * PORTAL_ONE_RETURNING case because of the possibility of needing to fire
79 * triggers. It may act more like PORTAL_ONE_SELECT in future.
80 *
81 * PORTAL_UTIL_SELECT: the portal contains a utility statement that returns
82 * a SELECT-like result (for example, EXPLAIN or SHOW). On first execution,
83 * we run the statement and dump its results into the portal tuplestore;
84 * the results are then returned to the client as demanded.
85 *
86 * PORTAL_MULTI_QUERY: all other cases. Here, we do not support partial
87 * execution: the portal's queries will be run to completion on first call.
88 */
89typedef enum PortalStrategy
90{
97
98/*
99 * A portal is always in one of these states. It is possible to transit
100 * from ACTIVE back to READY if the query is not run to completion;
101 * otherwise we never back up in status.
102 */
103typedef enum PortalStatus
104{
105 PORTAL_NEW, /* freshly created */
106 PORTAL_DEFINED, /* PortalDefineQuery done */
107 PORTAL_READY, /* PortalStart complete, can run it */
108 PORTAL_ACTIVE, /* portal is running (can't delete it) */
109 PORTAL_DONE, /* portal is finished (don't re-run it) */
110 PORTAL_FAILED, /* portal got error (can't re-run it) */
112
113typedef struct PortalData *Portal;
114
115typedef struct PortalData
116{
117 /* Bookkeeping data */
118 const char *name; /* portal's name */
119 const char *prepStmtName; /* source prepared statement (NULL if none) */
120 MemoryContext portalContext; /* subsidiary memory for portal */
121 ResourceOwner resowner; /* resources owned by portal */
122 void (*cleanup) (Portal portal); /* cleanup hook */
123
124 /*
125 * State data for remembering which subtransaction(s) the portal was
126 * created or used in. If the portal is held over from a previous
127 * transaction, both subxids are InvalidSubTransactionId. Otherwise,
128 * createSubid is the creating subxact and activeSubid is the last subxact
129 * in which we ran the portal.
130 */
131 SubTransactionId createSubid; /* the creating subxact */
132 SubTransactionId activeSubid; /* the last subxact with activity */
133 int createLevel; /* creating subxact's nesting level */
134
135 /* The query or queries the portal will execute */
136 const char *sourceText; /* text of query (as of 8.4, never NULL) */
137 CommandTag commandTag; /* command tag for original query */
138 QueryCompletion qc; /* command completion data for executed query */
139 List *stmts; /* list of PlannedStmts */
140 CachedPlan *cplan; /* CachedPlan, if stmts are from one */
141 CachedPlanSource *plansource; /* CachedPlanSource, for cplan */
142
143 ParamListInfo portalParams; /* params to pass to query */
144 QueryEnvironment *queryEnv; /* environment for query */
145
146 /* Features/options */
147 PortalStrategy strategy; /* see above */
148 int cursorOptions; /* DECLARE CURSOR option bits */
149
150 /* Status data */
151 PortalStatus status; /* see above */
152 bool portalPinned; /* a pinned portal can't be dropped */
153 bool autoHeld; /* was automatically converted from pinned to
154 * held (see HoldPinnedPortals()) */
155
156 /* If not NULL, Executor is active; call ExecutorEnd eventually: */
157 QueryDesc *queryDesc; /* info needed for executor invocation */
158
159 /* If portal returns tuples, this is their tupdesc: */
160 TupleDesc tupDesc; /* descriptor for result tuples */
161 /* and these are the format codes to use for the columns: */
162 int16 *formats; /* a format code for each column */
163
164 /*
165 * Outermost ActiveSnapshot for execution of the portal's queries. For
166 * all but a few utility commands, we require such a snapshot to exist.
167 * This ensures that TOAST references in query results can be detoasted,
168 * and helps to reduce thrashing of the process's exposed xmin.
169 */
170 Snapshot portalSnapshot; /* active snapshot, or NULL if none */
171
172 /*
173 * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING,
174 * PORTAL_ONE_MOD_WITH, or PORTAL_UTIL_SELECT query. (A cursor held past
175 * the end of its transaction no longer has any active executor state.)
176 */
177 Tuplestorestate *holdStore; /* store for holdable cursors */
178 MemoryContext holdContext; /* memory containing holdStore */
179
180 /*
181 * Snapshot under which tuples in the holdStore were read. We must keep a
182 * reference to this snapshot if there is any possibility that the tuples
183 * contain TOAST references, because releasing the snapshot could allow
184 * recently-dead rows to be vacuumed away, along with any toast data
185 * belonging to them. In the case of a held cursor, we avoid needing to
186 * keep such a snapshot by forcibly detoasting the data.
187 */
188 Snapshot holdSnapshot; /* registered snapshot, or NULL if none */
189
190 /*
191 * atStart, atEnd and portalPos indicate the current cursor position.
192 * portalPos is zero before the first row, N after fetching N'th row of
193 * query. After we run off the end, portalPos = # of rows in query, and
194 * atEnd is true. Note that atStart implies portalPos == 0, but not the
195 * reverse: we might have backed up only as far as the first row, not to
196 * the start. Also note that various code inspects atStart and atEnd, but
197 * only the portal movement routines should touch portalPos.
198 */
200 bool atEnd;
202
203 /* Presentation data, primarily used by the pg_cursors system view */
204 TimestampTz creation_time; /* time at which this portal was defined */
205 bool visible; /* include this portal in pg_cursors? */
207
208/*
209 * PortalIsValid
210 * True iff portal is valid.
211 */
212#define PortalIsValid(p) PointerIsValid(p)
213
214
215/* Prototypes for functions in utils/mmgr/portalmem.c */
216extern void EnablePortalManager(void);
217extern bool PreCommit_Portals(bool isPrepare);
218extern void AtAbort_Portals(void);
219extern void AtCleanup_Portals(void);
220extern void PortalErrorCleanup(void);
221extern void AtSubCommit_Portals(SubTransactionId mySubid,
222 SubTransactionId parentSubid,
223 int parentLevel,
224 ResourceOwner parentXactOwner);
225extern void AtSubAbort_Portals(SubTransactionId mySubid,
226 SubTransactionId parentSubid,
227 ResourceOwner myXactOwner,
228 ResourceOwner parentXactOwner);
229extern void AtSubCleanup_Portals(SubTransactionId mySubid);
230extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
231extern Portal CreateNewPortal(void);
232extern void PinPortal(Portal portal);
233extern void UnpinPortal(Portal portal);
234extern void MarkPortalActive(Portal portal);
235extern void MarkPortalDone(Portal portal);
236extern void MarkPortalFailed(Portal portal);
237extern void PortalDrop(Portal portal, bool isTopCommit);
238extern Portal GetPortalByName(const char *name);
239extern void PortalDefineQuery(Portal portal,
240 const char *prepStmtName,
241 const char *sourceText,
242 CommandTag commandTag,
243 List *stmts,
244 CachedPlan *cplan,
245 CachedPlanSource *plansource);
247extern void PortalCreateHoldStore(Portal portal);
248extern void PortalHashTableDeleteAll(void);
249extern bool ThereAreNoReadyPortals(void);
250extern void HoldPinnedPortals(void);
251extern void ForgetPortalSnapshots(void);
252
253#endif /* PORTAL_H */
uint32 SubTransactionId
Definition: c.h:627
int16_t int16
Definition: c.h:497
uint64_t uint64
Definition: c.h:503
CommandTag
Definition: cmdtag.h:23
int64 TimestampTz
Definition: timestamp.h:39
void AtAbort_Portals(void)
Definition: portalmem.c:783
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:981
PortalStatus
Definition: portal.h:104
@ PORTAL_FAILED
Definition: portal.h:110
@ PORTAL_NEW
Definition: portal.h:105
@ PORTAL_ACTIVE
Definition: portal.h:108
@ PORTAL_DONE
Definition: portal.h:109
@ PORTAL_READY
Definition: portal.h:107
@ PORTAL_DEFINED
Definition: portal.h:106
void EnablePortalManager(void)
Definition: portalmem.c:104
struct PortalData * Portal
Definition: portal.h:113
void MarkPortalDone(Portal portal)
Definition: portalmem.c:416
void PinPortal(Portal portal)
Definition: portalmem.c:373
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan, CachedPlanSource *plansource)
Definition: portalmem.c:282
Portal CreateNewPortal(void)
Definition: portalmem.c:235
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:679
PortalStrategy
Definition: portal.h:90
@ PORTAL_ONE_RETURNING
Definition: portal.h:92
@ PORTAL_MULTI_QUERY
Definition: portal.h:95
@ PORTAL_ONE_SELECT
Definition: portal.h:91
@ PORTAL_ONE_MOD_WITH
Definition: portal.h:93
@ PORTAL_UTIL_SELECT
Definition: portal.h:94
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:444
void UnpinPortal(Portal portal)
Definition: portalmem.c:382
void HoldPinnedPortals(void)
Definition: portalmem.c:1209
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:151
void MarkPortalActive(Portal portal)
Definition: portalmem.c:397
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:470
bool ThereAreNoReadyPortals(void)
Definition: portalmem.c:1173
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:945
void AtCleanup_Portals(void)
Definition: portalmem.c:860
void PortalHashTableDeleteAll(void)
Definition: portalmem.c:609
Portal CreatePortal(const char *name, bool allowDup, bool dupSilent)
Definition: portalmem.c:175
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1094
void PortalErrorCleanup(void)
Definition: portalmem.c:919
void ForgetPortalSnapshots(void)
Definition: portalmem.c:1258
void PortalCreateHoldStore(Portal portal)
Definition: portalmem.c:333
struct PortalData PortalData
Definition: pg_list.h:54
SubTransactionId createSubid
Definition: portal.h:131
CachedPlanSource * plansource
Definition: portal.h:141
Snapshot portalSnapshot
Definition: portal.h:170
SubTransactionId activeSubid
Definition: portal.h:132
CommandTag commandTag
Definition: portal.h:137
uint64 portalPos
Definition: portal.h:201
QueryDesc * queryDesc
Definition: portal.h:157
const char * sourceText
Definition: portal.h:136
bool atEnd
Definition: portal.h:200
bool atStart
Definition: portal.h:199
List * stmts
Definition: portal.h:139
ResourceOwner resowner
Definition: portal.h:121
TimestampTz creation_time
Definition: portal.h:204
bool autoHeld
Definition: portal.h:153
bool portalPinned
Definition: portal.h:152
int createLevel
Definition: portal.h:133
MemoryContext holdContext
Definition: portal.h:178
QueryEnvironment * queryEnv
Definition: portal.h:144
QueryCompletion qc
Definition: portal.h:138
MemoryContext portalContext
Definition: portal.h:120
int16 * formats
Definition: portal.h:162
ParamListInfo portalParams
Definition: portal.h:143
bool visible
Definition: portal.h:205
Snapshot holdSnapshot
Definition: portal.h:188
const char * name
Definition: portal.h:118
const char * prepStmtName
Definition: portal.h:119
TupleDesc tupDesc
Definition: portal.h:160
CachedPlan * cplan
Definition: portal.h:140
Tuplestorestate * holdStore
Definition: portal.h:177
int cursorOptions
Definition: portal.h:148
void(* cleanup)(Portal portal)
Definition: portal.h:122
PortalStrategy strategy
Definition: portal.h:147
PortalStatus status
Definition: portal.h:151
const char * name