]> granicus.if.org Git - postgresql/blob - src/include/utils/portal.h
Back out RESET CONNECTION until there is more discussion.
[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  * parse/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-2006, PostgreSQL Global Development Group
40  * Portions Copyright (c) 1994, Regents of the University of California
41  *
42  * $PostgreSQL: pgsql/src/include/utils/portal.h,v 1.61 2006/04/25 14:11:59 momjian Exp $
43  *
44  *-------------------------------------------------------------------------
45  */
46 #ifndef PORTAL_H
47 #define PORTAL_H
48
49 #include "executor/execdesc.h"
50 #include "nodes/memnodes.h"
51 #include "utils/resowner.h"
52 #include "utils/tuplestore.h"
53
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_UTIL_SELECT: the portal contains a utility statement that returns
68  * a SELECT-like result (for example, EXPLAIN or SHOW).  On first execution,
69  * we run the statement and dump its results into the portal tuplestore;
70  * the results are then returned to the client as demanded.
71  *
72  * PORTAL_MULTI_QUERY: all other cases.  Here, we do not support partial
73  * execution: the portal's queries will be run to completion on first call.
74  */
75 typedef enum PortalStrategy
76 {
77         PORTAL_ONE_SELECT,
78         PORTAL_UTIL_SELECT,
79         PORTAL_MULTI_QUERY
80 } PortalStrategy;
81
82 /*
83  * A portal is always in one of these states.  It is possible to transit
84  * from ACTIVE back to READY if the query is not run to completion;
85  * otherwise we never back up in status.
86  */
87 typedef enum PortalStatus
88 {
89         PORTAL_NEW,                                     /* in process of creation */
90         PORTAL_READY,                           /* PortalStart complete, can run it */
91         PORTAL_ACTIVE,                          /* portal is running (can't delete it) */
92         PORTAL_DONE,                            /* portal is finished (don't re-run it) */
93         PORTAL_FAILED                           /* portal got error (can't re-run it) */
94 } PortalStatus;
95
96 /*
97  * Note: typedef Portal is declared in tcop/dest.h as
98  *              typedef struct PortalData *Portal;
99  */
100
101 typedef struct PortalData
102 {
103         /* Bookkeeping data */
104         const char *name;                       /* portal's name */
105         MemoryContext heap;                     /* subsidiary memory for portal */
106         ResourceOwner resowner;         /* resources owned by portal */
107         void            (*cleanup) (Portal portal);             /* cleanup hook */
108         SubTransactionId createSubid;           /* the ID of the creating subxact */
109
110         /*
111          * if createSubid is InvalidSubTransactionId, the portal is held over from
112          * a previous transaction
113          */
114
115         /* The query or queries the portal will execute */
116         const char *sourceText;         /* text of query, if known (may be NULL) */
117         const char *commandTag;         /* command tag for original query */
118         List       *parseTrees;         /* parse tree(s) */
119         List       *planTrees;          /* plan tree(s) */
120         MemoryContext queryContext; /* where the above trees live */
121
122         /*
123          * Note: queryContext effectively identifies which prepared statement the
124          * portal depends on, if any.  The queryContext is *not* owned by the
125          * portal and is not to be deleted by portal destruction.  (But for a
126          * cursor it is the same as "heap", and that context is deleted by portal
127          * destruction.)
128          */
129         ParamListInfo portalParams; /* params to pass to query */
130
131         /* Features/options */
132         PortalStrategy strategy;        /* see above */
133         int                     cursorOptions;  /* DECLARE CURSOR option bits */
134
135         /* Status data */
136         PortalStatus status;            /* see above */
137         bool            portalUtilReady;        /* PortalRunUtility complete? */
138
139         /* If not NULL, Executor is active; call ExecutorEnd eventually: */
140         QueryDesc  *queryDesc;          /* info needed for executor invocation */
141
142         /* If portal returns tuples, this is their tupdesc: */
143         TupleDesc       tupDesc;                /* descriptor for result tuples */
144         /* and these are the format codes to use for the columns: */
145         int16      *formats;            /* a format code for each column */
146
147         /*
148          * Where we store tuples for a held cursor or a PORTAL_UTIL_SELECT query.
149          * (A cursor held past the end of its transaction no longer has any active
150          * executor state.)
151          */
152         Tuplestorestate *holdStore; /* store for holdable cursors */
153         MemoryContext holdContext;      /* memory containing holdStore */
154
155         /*
156          * atStart, atEnd and portalPos indicate the current cursor position.
157          * portalPos is zero before the first row, N after fetching N'th row of
158          * query.  After we run off the end, portalPos = # of rows in query, and
159          * atEnd is true.  If portalPos overflows, set posOverflow (this causes us
160          * to stop relying on its value for navigation).  Note that atStart
161          * implies portalPos == 0, but not the reverse (portalPos could have
162          * overflowed).
163          */
164         bool            atStart;
165         bool            atEnd;
166         bool            posOverflow;
167         long            portalPos;
168
169         /* Presentation data, primarily used by the pg_cursors system view */
170         TimestampTz     creation_time;  /* time at which this portal was defined */
171         bool            visible;                /* include this portal in pg_cursors? */
172 } PortalData;
173
174 /*
175  * PortalIsValid
176  *              True iff portal is valid.
177  */
178 #define PortalIsValid(p) PointerIsValid(p)
179
180 /*
181  * Access macros for Portal ... use these in preference to field access.
182  */
183 #define PortalGetQueryDesc(portal)      ((portal)->queryDesc)
184 #define PortalGetHeapMemory(portal) ((portal)->heap)
185
186
187 /* Prototypes for functions in utils/mmgr/portalmem.c */
188 extern void EnablePortalManager(void);
189 extern bool CommitHoldablePortals(void);
190 extern bool PrepareHoldablePortals(void);
191 extern void AtCommit_Portals(void);
192 extern void AtAbort_Portals(void);
193 extern void AtCleanup_Portals(void);
194 extern void AtSubCommit_Portals(SubTransactionId mySubid,
195                                         SubTransactionId parentSubid,
196                                         ResourceOwner parentXactOwner);
197 extern void AtSubAbort_Portals(SubTransactionId mySubid,
198                                    SubTransactionId parentSubid,
199                                    ResourceOwner parentXactOwner);
200 extern void AtSubCleanup_Portals(SubTransactionId mySubid);
201 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
202 extern Portal CreateNewPortal(void);
203 extern void PortalDrop(Portal portal, bool isTopCommit);
204 extern void DropDependentPortals(MemoryContext queryContext);
205 extern Portal GetPortalByName(const char *name);
206 extern void PortalDefineQuery(Portal portal,
207                                   const char *sourceText,
208                                   const char *commandTag,
209                                   List *parseTrees,
210                                   List *planTrees,
211                                   MemoryContext queryContext);
212 extern void PortalCreateHoldStore(Portal portal);
213
214 #endif   /* PORTAL_H */