00001 /*------------------------------------------------------------------------- 00002 * 00003 * portal.h 00004 * POSTGRES portal definitions. 00005 * 00006 * A portal is an abstraction which represents the execution state of 00007 * a running or runnable query. Portals support both SQL-level CURSORs 00008 * and protocol-level portals. 00009 * 00010 * Scrolling (nonsequential access) and suspension of execution are allowed 00011 * only for portals that contain a single SELECT-type query. We do not want 00012 * to let the client suspend an update-type query partway through! Because 00013 * the query rewriter does not allow arbitrary ON SELECT rewrite rules, 00014 * only queries that were originally update-type could produce multiple 00015 * plan trees; so the restriction to a single query is not a problem 00016 * in practice. 00017 * 00018 * For SQL cursors, we support three kinds of scroll behavior: 00019 * 00020 * (1) Neither NO SCROLL nor SCROLL was specified: to remain backward 00021 * compatible, we allow backward fetches here, unless it would 00022 * impose additional runtime overhead to do so. 00023 * 00024 * (2) NO SCROLL was specified: don't allow any backward fetches. 00025 * 00026 * (3) SCROLL was specified: allow all kinds of backward fetches, even 00027 * if we need to take a performance hit to do so. (The planner sticks 00028 * a Materialize node atop the query plan if needed.) 00029 * 00030 * Case #1 is converted to #2 or #3 by looking at the query itself and 00031 * determining if scrollability can be supported without additional 00032 * overhead. 00033 * 00034 * Protocol-level portals have no nonsequential-fetch API and so the 00035 * distinction doesn't matter for them. They are always initialized 00036 * to look like NO SCROLL cursors. 00037 * 00038 * 00039 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00040 * Portions Copyright (c) 1994, Regents of the University of California 00041 * 00042 * src/include/utils/portal.h 00043 * 00044 *------------------------------------------------------------------------- 00045 */ 00046 #ifndef PORTAL_H 00047 #define PORTAL_H 00048 00049 #include "datatype/timestamp.h" 00050 #include "executor/execdesc.h" 00051 #include "utils/plancache.h" 00052 #include "utils/resowner.h" 00053 00054 /* 00055 * We have several execution strategies for Portals, depending on what 00056 * query or queries are to be executed. (Note: in all cases, a Portal 00057 * executes just a single source-SQL query, and thus produces just a 00058 * single result from the user's viewpoint. However, the rule rewriter 00059 * may expand the single source query to zero or many actual queries.) 00060 * 00061 * PORTAL_ONE_SELECT: the portal contains one single SELECT query. We run 00062 * the Executor incrementally as results are demanded. This strategy also 00063 * supports holdable cursors (the Executor results can be dumped into a 00064 * tuplestore for access after transaction completion). 00065 * 00066 * PORTAL_ONE_RETURNING: the portal contains a single INSERT/UPDATE/DELETE 00067 * query with a RETURNING clause (plus possibly auxiliary queries added by 00068 * rule rewriting). On first execution, we run the portal to completion 00069 * and dump the primary query's results into the portal tuplestore; the 00070 * results are then returned to the client as demanded. (We can't support 00071 * suspension of the query partway through, because the AFTER TRIGGER code 00072 * can't cope, and also because we don't want to risk failing to execute 00073 * all the auxiliary queries.) 00074 * 00075 * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but 00076 * it has data-modifying CTEs. This is currently treated the same as the 00077 * PORTAL_ONE_RETURNING case because of the possibility of needing to fire 00078 * triggers. It may act more like PORTAL_ONE_SELECT in future. 00079 * 00080 * PORTAL_UTIL_SELECT: the portal contains a utility statement that returns 00081 * a SELECT-like result (for example, EXPLAIN or SHOW). On first execution, 00082 * we run the statement and dump its results into the portal tuplestore; 00083 * the results are then returned to the client as demanded. 00084 * 00085 * PORTAL_MULTI_QUERY: all other cases. Here, we do not support partial 00086 * execution: the portal's queries will be run to completion on first call. 00087 */ 00088 typedef enum PortalStrategy 00089 { 00090 PORTAL_ONE_SELECT, 00091 PORTAL_ONE_RETURNING, 00092 PORTAL_ONE_MOD_WITH, 00093 PORTAL_UTIL_SELECT, 00094 PORTAL_MULTI_QUERY 00095 } PortalStrategy; 00096 00097 /* 00098 * A portal is always in one of these states. It is possible to transit 00099 * from ACTIVE back to READY if the query is not run to completion; 00100 * otherwise we never back up in status. 00101 */ 00102 typedef enum PortalStatus 00103 { 00104 PORTAL_NEW, /* freshly created */ 00105 PORTAL_DEFINED, /* PortalDefineQuery done */ 00106 PORTAL_READY, /* PortalStart complete, can run it */ 00107 PORTAL_ACTIVE, /* portal is running (can't delete it) */ 00108 PORTAL_DONE, /* portal is finished (don't re-run it) */ 00109 PORTAL_FAILED /* portal got error (can't re-run it) */ 00110 } PortalStatus; 00111 00112 typedef struct PortalData *Portal; 00113 00114 typedef struct PortalData 00115 { 00116 /* Bookkeeping data */ 00117 const char *name; /* portal's name */ 00118 const char *prepStmtName; /* source prepared statement (NULL if none) */ 00119 MemoryContext heap; /* subsidiary memory for portal */ 00120 ResourceOwner resowner; /* resources owned by portal */ 00121 void (*cleanup) (Portal portal); /* cleanup hook */ 00122 SubTransactionId createSubid; /* the ID of the creating subxact */ 00123 00124 /* 00125 * if createSubid is InvalidSubTransactionId, the portal is held over from 00126 * a previous transaction 00127 */ 00128 00129 /* The query or queries the portal will execute */ 00130 const char *sourceText; /* text of query (as of 8.4, never NULL) */ 00131 const char *commandTag; /* command tag for original query */ 00132 List *stmts; /* PlannedStmts and/or utility statements */ 00133 CachedPlan *cplan; /* CachedPlan, if stmts are from one */ 00134 00135 ParamListInfo portalParams; /* params to pass to query */ 00136 00137 /* Features/options */ 00138 PortalStrategy strategy; /* see above */ 00139 int cursorOptions; /* DECLARE CURSOR option bits */ 00140 00141 /* Status data */ 00142 PortalStatus status; /* see above */ 00143 bool portalPinned; /* a pinned portal can't be dropped */ 00144 00145 /* If not NULL, Executor is active; call ExecutorEnd eventually: */ 00146 QueryDesc *queryDesc; /* info needed for executor invocation */ 00147 00148 /* If portal returns tuples, this is their tupdesc: */ 00149 TupleDesc tupDesc; /* descriptor for result tuples */ 00150 /* and these are the format codes to use for the columns: */ 00151 int16 *formats; /* a format code for each column */ 00152 00153 /* 00154 * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING or 00155 * PORTAL_UTIL_SELECT query. (A cursor held past the end of its 00156 * transaction no longer has any active executor state.) 00157 */ 00158 Tuplestorestate *holdStore; /* store for holdable cursors */ 00159 MemoryContext holdContext; /* memory containing holdStore */ 00160 00161 /* 00162 * atStart, atEnd and portalPos indicate the current cursor position. 00163 * portalPos is zero before the first row, N after fetching N'th row of 00164 * query. After we run off the end, portalPos = # of rows in query, and 00165 * atEnd is true. If portalPos overflows, set posOverflow (this causes us 00166 * to stop relying on its value for navigation). Note that atStart 00167 * implies portalPos == 0, but not the reverse (portalPos could have 00168 * overflowed). 00169 */ 00170 bool atStart; 00171 bool atEnd; 00172 bool posOverflow; 00173 long portalPos; 00174 00175 /* Presentation data, primarily used by the pg_cursors system view */ 00176 TimestampTz creation_time; /* time at which this portal was defined */ 00177 bool visible; /* include this portal in pg_cursors? */ 00178 } PortalData; 00179 00180 /* 00181 * PortalIsValid 00182 * True iff portal is valid. 00183 */ 00184 #define PortalIsValid(p) PointerIsValid(p) 00185 00186 /* 00187 * Access macros for Portal ... use these in preference to field access. 00188 */ 00189 #define PortalGetQueryDesc(portal) ((portal)->queryDesc) 00190 #define PortalGetHeapMemory(portal) ((portal)->heap) 00191 #define PortalGetPrimaryStmt(portal) PortalListGetPrimaryStmt((portal)->stmts) 00192 00193 00194 /* Prototypes for functions in utils/mmgr/portalmem.c */ 00195 extern void EnablePortalManager(void); 00196 extern bool PreCommit_Portals(bool isPrepare); 00197 extern void AtAbort_Portals(void); 00198 extern void AtCleanup_Portals(void); 00199 extern void AtSubCommit_Portals(SubTransactionId mySubid, 00200 SubTransactionId parentSubid, 00201 ResourceOwner parentXactOwner); 00202 extern void AtSubAbort_Portals(SubTransactionId mySubid, 00203 SubTransactionId parentSubid, 00204 ResourceOwner parentXactOwner); 00205 extern void AtSubCleanup_Portals(SubTransactionId mySubid); 00206 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent); 00207 extern Portal CreateNewPortal(void); 00208 extern void PinPortal(Portal portal); 00209 extern void UnpinPortal(Portal portal); 00210 extern void MarkPortalDone(Portal portal); 00211 extern void MarkPortalFailed(Portal portal); 00212 extern void PortalDrop(Portal portal, bool isTopCommit); 00213 extern Portal GetPortalByName(const char *name); 00214 extern void PortalDefineQuery(Portal portal, 00215 const char *prepStmtName, 00216 const char *sourceText, 00217 const char *commandTag, 00218 List *stmts, 00219 CachedPlan *cplan); 00220 extern Node *PortalListGetPrimaryStmt(List *stmts); 00221 extern void PortalCreateHoldStore(Portal portal); 00222 extern void PortalHashTableDeleteAll(void); 00223 extern bool ThereAreNoReadyPortals(void); 00224 00225 #endif /* PORTAL_H */