1 /*-------------------------------------------------------------------------
4 * POSTGRES portal definitions.
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.
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
18 * For SQL cursors, we support three kinds of scroll behavior:
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.
24 * (2) NO SCROLL was specified: don't allow any backward fetches.
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.)
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
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.
39 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
40 * Portions Copyright (c) 1994, Regents of the University of California
42 * $PostgreSQL: pgsql/src/include/utils/portal.h,v 1.61 2006/04/25 14:11:59 momjian Exp $
44 *-------------------------------------------------------------------------
49 #include "executor/execdesc.h"
50 #include "nodes/memnodes.h"
51 #include "utils/resowner.h"
52 #include "utils/tuplestore.h"
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.)
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).
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.
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.
75 typedef enum PortalStrategy
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.
87 typedef enum PortalStatus
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) */
97 * Note: typedef Portal is declared in tcop/dest.h as
98 * typedef struct PortalData *Portal;
101 typedef struct PortalData
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 */
111 * if createSubid is InvalidSubTransactionId, the portal is held over from
112 * a previous transaction
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 */
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
129 ParamListInfo portalParams; /* params to pass to query */
131 /* Features/options */
132 PortalStrategy strategy; /* see above */
133 int cursorOptions; /* DECLARE CURSOR option bits */
136 PortalStatus status; /* see above */
137 bool portalUtilReady; /* PortalRunUtility complete? */
139 /* If not NULL, Executor is active; call ExecutorEnd eventually: */
140 QueryDesc *queryDesc; /* info needed for executor invocation */
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 */
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
152 Tuplestorestate *holdStore; /* store for holdable cursors */
153 MemoryContext holdContext; /* memory containing holdStore */
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
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? */
176 * True iff portal is valid.
178 #define PortalIsValid(p) PointerIsValid(p)
181 * Access macros for Portal ... use these in preference to field access.
183 #define PortalGetQueryDesc(portal) ((portal)->queryDesc)
184 #define PortalGetHeapMemory(portal) ((portal)->heap)
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,
211 MemoryContext queryContext);
212 extern void PortalCreateHoldStore(Portal portal);
214 #endif /* PORTAL_H */