~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/include/utils/portal.h

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

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