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-2004, 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.52 2004/08/29 05:06: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.
76 typedef enum PortalStrategy
84 * A portal is always in one of these states. It is possible to transit
85 * from ACTIVE back to READY if the query is not run to completion;
86 * otherwise we never back up in status.
88 typedef enum PortalStatus
90 PORTAL_NEW, /* in process of creation */
91 PORTAL_READY, /* PortalStart complete, can run it */
92 PORTAL_ACTIVE, /* portal is running (can't delete it) */
93 PORTAL_DONE, /* portal is finished (don't re-run it) */
94 PORTAL_FAILED /* portal got error (can't re-run it) */
98 * Note: typedef Portal is declared in tcop/dest.h as
99 * typedef struct PortalData *Portal;
102 typedef struct PortalData
104 /* Bookkeeping data */
105 const char *name; /* portal's name */
106 MemoryContext heap; /* subsidiary memory for portal */
107 ResourceOwner resowner; /* resources owned by portal */
108 void (*cleanup) (Portal portal); /* cleanup hook */
109 TransactionId createXact; /* the xid of the creating xact */
111 /* The query or queries the portal will execute */
112 const char *sourceText; /* text of query, if known (may be NULL) */
113 const char *commandTag; /* command tag for original query */
114 List *parseTrees; /* parse tree(s) */
115 List *planTrees; /* plan tree(s) */
116 MemoryContext queryContext; /* where the above trees live */
119 * Note: queryContext effectively identifies which prepared statement
120 * the portal depends on, if any. The queryContext is *not* owned by
121 * the portal and is not to be deleted by portal destruction. (But
122 * for a cursor it is the same as "heap", and that context is deleted
123 * by portal destruction.)
125 ParamListInfo portalParams; /* params to pass to query */
127 /* Features/options */
128 PortalStrategy strategy; /* see above */
129 int cursorOptions; /* DECLARE CURSOR option bits */
132 PortalStatus status; /* see above */
133 bool portalUtilReady; /* PortalRunUtility complete? */
135 /* If not NULL, Executor is active; call ExecutorEnd eventually: */
136 QueryDesc *queryDesc; /* info needed for executor invocation */
138 /* If portal returns tuples, this is their tupdesc: */
139 TupleDesc tupDesc; /* descriptor for result tuples */
140 /* and these are the format codes to use for the columns: */
141 int16 *formats; /* a format code for each column */
144 * Where we store tuples for a held cursor or a PORTAL_UTIL_SELECT
145 * query. (A cursor held past the end of its transaction no longer has
146 * any active executor state.)
148 Tuplestorestate *holdStore; /* store for holdable cursors */
149 MemoryContext holdContext; /* memory containing holdStore */
152 * atStart, atEnd and portalPos indicate the current cursor position.
153 * portalPos is zero before the first row, N after fetching N'th row
154 * of query. After we run off the end, portalPos = # of rows in
155 * query, and atEnd is true. If portalPos overflows, set posOverflow
156 * (this causes us to stop relying on its value for navigation). Note
157 * that atStart implies portalPos == 0, but not the reverse (portalPos
158 * could have overflowed).
168 * True iff portal is valid.
170 #define PortalIsValid(p) PointerIsValid(p)
173 * Access macros for Portal ... use these in preference to field access.
175 #define PortalGetQueryDesc(portal) ((portal)->queryDesc)
176 #define PortalGetHeapMemory(portal) ((portal)->heap)
179 /* Prototypes for functions in utils/mmgr/portalmem.c */
180 extern void EnablePortalManager(void);
181 extern void AtCommit_Portals(void);
182 extern void AtAbort_Portals(void);
183 extern void AtCleanup_Portals(void);
184 extern void AtSubCommit_Portals(TransactionId parentXid,
185 ResourceOwner parentXactOwner);
186 extern void AtSubAbort_Portals(TransactionId parentXid,
187 ResourceOwner parentXactOwner);
188 extern void AtSubCleanup_Portals(void);
189 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
190 extern Portal CreateNewPortal(void);
191 extern void PortalDrop(Portal portal, bool isTopCommit);
192 extern void DropDependentPortals(MemoryContext queryContext);
193 extern Portal GetPortalByName(const char *name);
194 extern void PortalDefineQuery(Portal portal,
195 const char *sourceText,
196 const char *commandTag,
199 MemoryContext queryContext);
200 extern void PortalCreateHoldStore(Portal portal);
202 #endif /* PORTAL_H */