]> granicus.if.org Git - postgresql/blob - src/include/utils/portal.h
Fix initialization of fake LSN for unlogged relations
[postgresql] / src / include / utils / portal.h
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-2019, 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 "utils/plancache.h"
52 #include "utils/resowner.h"
53
54 /*
55  * We have several execution strategies for Portals, depending on what
56  * query or queries are to be executed.  (Note: in all cases, a Portal
57  * executes just a single source-SQL query, and thus produces just a
58  * single result from the user's viewpoint.  However, the rule rewriter
59  * may expand the single source query to zero or many actual queries.)
60  *
61  * PORTAL_ONE_SELECT: the portal contains one single SELECT query.  We run
62  * the Executor incrementally as results are demanded.  This strategy also
63  * supports holdable cursors (the Executor results can be dumped into a
64  * tuplestore for access after transaction completion).
65  *
66  * PORTAL_ONE_RETURNING: the portal contains a single INSERT/UPDATE/DELETE
67  * query with a RETURNING clause (plus possibly auxiliary queries added by
68  * rule rewriting).  On first execution, we run the portal to completion
69  * and dump the primary query's results into the portal tuplestore; the
70  * results are then returned to the client as demanded.  (We can't support
71  * suspension of the query partway through, because the AFTER TRIGGER code
72  * can't cope, and also because we don't want to risk failing to execute
73  * all the auxiliary queries.)
74  *
75  * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but
76  * it has data-modifying CTEs.  This is currently treated the same as the
77  * PORTAL_ONE_RETURNING case because of the possibility of needing to fire
78  * triggers.  It may act more like PORTAL_ONE_SELECT in future.
79  *
80  * PORTAL_UTIL_SELECT: the portal contains a utility statement that returns
81  * a SELECT-like result (for example, EXPLAIN or SHOW).  On first execution,
82  * we run the statement and dump its results into the portal tuplestore;
83  * the results are then returned to the client as demanded.
84  *
85  * PORTAL_MULTI_QUERY: all other cases.  Here, we do not support partial
86  * execution: the portal's queries will be run to completion on first call.
87  */
88 typedef enum PortalStrategy
89 {
90         PORTAL_ONE_SELECT,
91         PORTAL_ONE_RETURNING,
92         PORTAL_ONE_MOD_WITH,
93         PORTAL_UTIL_SELECT,
94         PORTAL_MULTI_QUERY
95 } PortalStrategy;
96
97 /*
98  * A portal is always in one of these states.  It is possible to transit
99  * from ACTIVE back to READY if the query is not run to completion;
100  * otherwise we never back up in status.
101  */
102 typedef enum PortalStatus
103 {
104         PORTAL_NEW,                                     /* freshly created */
105         PORTAL_DEFINED,                         /* PortalDefineQuery done */
106         PORTAL_READY,                           /* PortalStart complete, can run it */
107         PORTAL_ACTIVE,                          /* portal is running (can't delete it) */
108         PORTAL_DONE,                            /* portal is finished (don't re-run it) */
109         PORTAL_FAILED                           /* portal got error (can't re-run it) */
110 } PortalStatus;
111
112 typedef struct PortalData *Portal;
113
114 typedef struct PortalData
115 {
116         /* Bookkeeping data */
117         const char *name;                       /* portal's name */
118         const char *prepStmtName;       /* source prepared statement (NULL if none) */
119         MemoryContext portalContext;    /* subsidiary memory for portal */
120         ResourceOwner resowner;         /* resources owned by portal */
121         void            (*cleanup) (Portal portal); /* cleanup hook */
122
123         /*
124          * State data for remembering which subtransaction(s) the portal was
125          * created or used in.  If the portal is held over from a previous
126          * transaction, both subxids are InvalidSubTransactionId.  Otherwise,
127          * createSubid is the creating subxact and activeSubid is the last subxact
128          * in which we ran the portal.
129          */
130         SubTransactionId createSubid;   /* the creating subxact */
131         SubTransactionId activeSubid;   /* the last subxact with activity */
132
133         /* The query or queries the portal will execute */
134         const char *sourceText;         /* text of query (as of 8.4, never NULL) */
135         const char *commandTag;         /* command tag for original query */
136         List       *stmts;                      /* list of PlannedStmts */
137         CachedPlan *cplan;                      /* CachedPlan, if stmts are from one */
138
139         ParamListInfo portalParams; /* params to pass to query */
140         QueryEnvironment *queryEnv; /* environment for query */
141
142         /* Features/options */
143         PortalStrategy strategy;        /* see above */
144         int                     cursorOptions;  /* DECLARE CURSOR option bits */
145         bool            run_once;               /* portal will only be run once */
146
147         /* Status data */
148         PortalStatus status;            /* see above */
149         bool            portalPinned;   /* a pinned portal can't be dropped */
150         bool            autoHeld;               /* was automatically converted from pinned to
151                                                                  * held (see HoldPinnedPortals()) */
152
153         /* If not NULL, Executor is active; call ExecutorEnd eventually: */
154         QueryDesc  *queryDesc;          /* info needed for executor invocation */
155
156         /* If portal returns tuples, this is their tupdesc: */
157         TupleDesc       tupDesc;                /* descriptor for result tuples */
158         /* and these are the format codes to use for the columns: */
159         int16      *formats;            /* a format code for each column */
160
161         /*
162          * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING or
163          * PORTAL_UTIL_SELECT query.  (A cursor held past the end of its
164          * transaction no longer has any active executor state.)
165          */
166         Tuplestorestate *holdStore; /* store for holdable cursors */
167         MemoryContext holdContext;      /* memory containing holdStore */
168
169         /*
170          * Snapshot under which tuples in the holdStore were read.  We must keep a
171          * reference to this snapshot if there is any possibility that the tuples
172          * contain TOAST references, because releasing the snapshot could allow
173          * recently-dead rows to be vacuumed away, along with any toast data
174          * belonging to them.  In the case of a held cursor, we avoid needing to
175          * keep such a snapshot by forcibly detoasting the data.
176          */
177         Snapshot        holdSnapshot;   /* registered snapshot, or NULL if none */
178
179         /*
180          * atStart, atEnd and portalPos indicate the current cursor position.
181          * portalPos is zero before the first row, N after fetching N'th row of
182          * query.  After we run off the end, portalPos = # of rows in query, and
183          * atEnd is true.  Note that atStart implies portalPos == 0, but not the
184          * reverse: we might have backed up only as far as the first row, not to
185          * the start.  Also note that various code inspects atStart and atEnd, but
186          * only the portal movement routines should touch portalPos.
187          */
188         bool            atStart;
189         bool            atEnd;
190         uint64          portalPos;
191
192         /* Presentation data, primarily used by the pg_cursors system view */
193         TimestampTz creation_time;      /* time at which this portal was defined */
194         bool            visible;                /* include this portal in pg_cursors? */
195 }                       PortalData;
196
197 /*
198  * PortalIsValid
199  *              True iff portal is valid.
200  */
201 #define PortalIsValid(p) PointerIsValid(p)
202
203
204 /* Prototypes for functions in utils/mmgr/portalmem.c */
205 extern void EnablePortalManager(void);
206 extern bool PreCommit_Portals(bool isPrepare);
207 extern void AtAbort_Portals(void);
208 extern void AtCleanup_Portals(void);
209 extern void PortalErrorCleanup(void);
210 extern void AtSubCommit_Portals(SubTransactionId mySubid,
211                                                                 SubTransactionId parentSubid,
212                                                                 ResourceOwner parentXactOwner);
213 extern void AtSubAbort_Portals(SubTransactionId mySubid,
214                                                            SubTransactionId parentSubid,
215                                                            ResourceOwner myXactOwner,
216                                                            ResourceOwner parentXactOwner);
217 extern void AtSubCleanup_Portals(SubTransactionId mySubid);
218 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
219 extern Portal CreateNewPortal(void);
220 extern void PinPortal(Portal portal);
221 extern void UnpinPortal(Portal portal);
222 extern void MarkPortalActive(Portal portal);
223 extern void MarkPortalDone(Portal portal);
224 extern void MarkPortalFailed(Portal portal);
225 extern void PortalDrop(Portal portal, bool isTopCommit);
226 extern Portal GetPortalByName(const char *name);
227 extern void PortalDefineQuery(Portal portal,
228                                                           const char *prepStmtName,
229                                                           const char *sourceText,
230                                                           const char *commandTag,
231                                                           List *stmts,
232                                                           CachedPlan *cplan);
233 extern PlannedStmt *PortalGetPrimaryStmt(Portal portal);
234 extern void PortalCreateHoldStore(Portal portal);
235 extern void PortalHashTableDeleteAll(void);
236 extern bool ThereAreNoReadyPortals(void);
237 extern void HoldPinnedPortals(void);
238
239 #endif                                                  /* PORTAL_H */