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-2021, 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  * query with a RETURNING clause (plus possibly auxiliary queries added by
69  * 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  */
89 typedef 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  */
103 typedef 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) */
111 } PortalStatus;
112 
113 typedef struct PortalData *Portal;
114 
115 typedef 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 
134  /* The query or queries the portal will execute */
135  const char *sourceText; /* text of query (as of 8.4, never NULL) */
136  CommandTag commandTag; /* command tag for original query */
137  QueryCompletion qc; /* command completion data for executed query */
138  List *stmts; /* list of PlannedStmts */
139  CachedPlan *cplan; /* CachedPlan, if stmts are from one */
140 
141  ParamListInfo portalParams; /* params to pass to query */
142  QueryEnvironment *queryEnv; /* environment for query */
143 
144  /* Features/options */
145  PortalStrategy strategy; /* see above */
146  int cursorOptions; /* DECLARE CURSOR option bits */
147  bool run_once; /* portal will only be run once */
148 
149  /* Status data */
150  PortalStatus status; /* see above */
151  bool portalPinned; /* a pinned portal can't be dropped */
152  bool autoHeld; /* was automatically converted from pinned to
153  * held (see HoldPinnedPortals()) */
154 
155  /* If not NULL, Executor is active; call ExecutorEnd eventually: */
156  QueryDesc *queryDesc; /* info needed for executor invocation */
157 
158  /* If portal returns tuples, this is their tupdesc: */
159  TupleDesc tupDesc; /* descriptor for result tuples */
160  /* and these are the format codes to use for the columns: */
161  int16 *formats; /* a format code for each column */
162 
163  /*
164  * Outermost ActiveSnapshot for execution of the portal's queries. For
165  * all but a few utility commands, we require such a snapshot to exist.
166  * This ensures that TOAST references in query results can be detoasted,
167  * and helps to reduce thrashing of the process's exposed xmin.
168  */
169  Snapshot portalSnapshot; /* active snapshot, or NULL if none */
170 
171  /*
172  * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING or
173  * PORTAL_UTIL_SELECT query. (A cursor held past the end of its
174  * transaction no longer has any active executor state.)
175  */
176  Tuplestorestate *holdStore; /* store for holdable cursors */
177  MemoryContext holdContext; /* memory containing holdStore */
178 
179  /*
180  * Snapshot under which tuples in the holdStore were read. We must keep a
181  * reference to this snapshot if there is any possibility that the tuples
182  * contain TOAST references, because releasing the snapshot could allow
183  * recently-dead rows to be vacuumed away, along with any toast data
184  * belonging to them. In the case of a held cursor, we avoid needing to
185  * keep such a snapshot by forcibly detoasting the data.
186  */
187  Snapshot holdSnapshot; /* registered snapshot, or NULL if none */
188 
189  /*
190  * atStart, atEnd and portalPos indicate the current cursor position.
191  * portalPos is zero before the first row, N after fetching N'th row of
192  * query. After we run off the end, portalPos = # of rows in query, and
193  * atEnd is true. Note that atStart implies portalPos == 0, but not the
194  * reverse: we might have backed up only as far as the first row, not to
195  * the start. Also note that various code inspects atStart and atEnd, but
196  * only the portal movement routines should touch portalPos.
197  */
198  bool atStart;
199  bool atEnd;
200  uint64 portalPos;
201 
202  /* Presentation data, primarily used by the pg_cursors system view */
203  TimestampTz creation_time; /* time at which this portal was defined */
204  bool visible; /* include this portal in pg_cursors? */
205 } PortalData;
206 
207 /*
208  * PortalIsValid
209  * True iff portal is valid.
210  */
211 #define PortalIsValid(p) PointerIsValid(p)
212 
213 
214 /* Prototypes for functions in utils/mmgr/portalmem.c */
215 extern void EnablePortalManager(void);
216 extern bool PreCommit_Portals(bool isPrepare);
217 extern void AtAbort_Portals(void);
218 extern void AtCleanup_Portals(void);
219 extern void PortalErrorCleanup(void);
220 extern void AtSubCommit_Portals(SubTransactionId mySubid,
221  SubTransactionId parentSubid,
222  ResourceOwner parentXactOwner);
223 extern void AtSubAbort_Portals(SubTransactionId mySubid,
224  SubTransactionId parentSubid,
225  ResourceOwner myXactOwner,
226  ResourceOwner parentXactOwner);
227 extern void AtSubCleanup_Portals(SubTransactionId mySubid);
228 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
229 extern Portal CreateNewPortal(void);
230 extern void PinPortal(Portal portal);
231 extern void UnpinPortal(Portal portal);
232 extern void MarkPortalActive(Portal portal);
233 extern void MarkPortalDone(Portal portal);
234 extern void MarkPortalFailed(Portal portal);
235 extern void PortalDrop(Portal portal, bool isTopCommit);
236 extern Portal GetPortalByName(const char *name);
237 extern void PortalDefineQuery(Portal portal,
238  const char *prepStmtName,
239  const char *sourceText,
241  List *stmts,
242  CachedPlan *cplan);
243 extern PlannedStmt *PortalGetPrimaryStmt(Portal portal);
244 extern void PortalCreateHoldStore(Portal portal);
245 extern void PortalHashTableDeleteAll(void);
246 extern bool ThereAreNoReadyPortals(void);
247 extern void HoldPinnedPortals(void);
248 extern void ForgetPortalSnapshots(void);
249 
250 #endif /* PORTAL_H */
signed short int16
Definition: c.h:428
CommandTag
Definition: cmdtag.h:20
bool atEnd
Definition: portal.h:199
CommandTag commandTag
Definition: portal.h:136
bool visible
Definition: portal.h:204
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:467
void MarkPortalActive(Portal portal)
Definition: portalmem.c:394
bool autoHeld
Definition: portal.h:152
void(* cleanup)(Portal portal)
Definition: portal.h:122
Portal CreatePortal(const char *name, bool allowDup, bool dupSilent)
Definition: portalmem.c:175
int64 TimestampTz
Definition: timestamp.h:39
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:675
void HoldPinnedPortals(void)
Definition: portalmem.c:1250
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner parentXactOwner)
Definition: portalmem.c:941
CachedPlan * cplan
Definition: portal.h:139
MemoryContext holdContext
Definition: portal.h:177
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:151
uint32 SubTransactionId
Definition: c.h:591
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
void AtAbort_Portals(void)
Definition: portalmem.c:779
List * stmts
Definition: portal.h:138
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1088
MemoryContext portalContext
Definition: portal.h:120
bool ThereAreNoReadyPortals(void)
Definition: portalmem.c:1214
bool run_once
Definition: portal.h:147
ParamListInfo portalParams
Definition: portal.h:141
const char * name
Definition: portal.h:118
void UnpinPortal(Portal portal)
Definition: portalmem.c:379
struct PortalData * Portal
Definition: portal.h:113
PortalStrategy
Definition: portal.h:89
bool portalPinned
Definition: portal.h:151
PortalStrategy strategy
Definition: portal.h:145
void EnablePortalManager(void)
Definition: portalmem.c:104
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan)
Definition: portalmem.c:281
SubTransactionId createSubid
Definition: portal.h:131
TimestampTz creation_time
Definition: portal.h:203
QueryDesc * queryDesc
Definition: portal.h:156
void ForgetPortalSnapshots(void)
Definition: portalmem.c:1299
int16 * formats
Definition: portal.h:161
void PortalCreateHoldStore(Portal portal)
Definition: portalmem.c:330
void MarkPortalDone(Portal portal)
Definition: portalmem.c:413
SubTransactionId activeSubid
Definition: portal.h:132
const char * sourceText
Definition: portal.h:135
TupleDesc tupDesc
Definition: portal.h:159
Portal CreateNewPortal(void)
Definition: portalmem.c:234
struct PortalData PortalData
QueryCompletion qc
Definition: portal.h:137
Snapshot portalSnapshot
Definition: portal.h:169
Snapshot holdSnapshot
Definition: portal.h:187
void PinPortal(Portal portal)
Definition: portalmem.c:370
void PortalHashTableDeleteAll(void)
Definition: portalmem.c:606
PortalStatus status
Definition: portal.h:150
QueryEnvironment * queryEnv
Definition: portal.h:142
ResourceOwner resowner
Definition: portal.h:121
bool atStart
Definition: portal.h:198
Tuplestorestate * holdStore
Definition: portal.h:176
PortalStatus
Definition: portal.h:103
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:975
int cursorOptions
Definition: portal.h:146
void PortalErrorCleanup(void)
Definition: portalmem.c:915
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:441
Definition: pg_list.h:50
void AtCleanup_Portals(void)
Definition: portalmem.c:856
const char * prepStmtName
Definition: portal.h:119
uint64 portalPos
Definition: portal.h:200