39 #define PORTALS_PER_USER 16
47 #define MAX_PORTALNAME_LEN NAMEDATALEN
57 #define PortalHashTableLookup(NAME, PORTAL) \
59 PortalHashEnt *hentry; \
61 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
62 (NAME), HASH_FIND, NULL); \
64 PORTAL = hentry->portal; \
69 #define PortalHashTableInsert(PORTAL, NAME) \
71 PortalHashEnt *hentry; bool found; \
73 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
74 (NAME), HASH_ENTER, &found); \
76 elog(ERROR, "duplicate portal name"); \
77 hentry->portal = PORTAL; \
79 PORTAL->name = hentry->portalname; \
82 #define PortalHashTableDelete(PORTAL) \
84 PortalHashEnt *hentry; \
86 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
87 PORTAL->name, HASH_REMOVE, NULL); \
89 elog(WARNING, "trying to delete portal name that does not exist"); \
156 foreach(lc, portal->
stmts)
187 (
errcode(ERRCODE_DUPLICATE_CURSOR),
188 errmsg(
"cursor \"%s\" already exists",
name)));
191 (
errcode(ERRCODE_DUPLICATE_CURSOR),
192 errmsg(
"closing existing cursor \"%s\"",
218 portal->
atEnd =
true;
238 static unsigned int unnamed_portal_count = 0;
245 unnamed_portal_count++;
246 sprintf(portalname,
"<unnamed portal %u>", unnamed_portal_count);
284 const char *prepStmtName,
285 const char *sourceText,
293 Assert(sourceText != NULL);
294 Assert(commandTag != CMDTAG_UNKNOWN || stmts ==
NIL);
301 portal->
stmts = stmts;
302 portal->
cplan = cplan;
316 portal->
cplan = NULL;
401 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
402 errmsg(
"portal \"%s\" cannot be run", portal->
name)));
479 (
errcode(ERRCODE_INVALID_CURSOR_STATE),
480 errmsg(
"cannot drop pinned portal \"%s\"", portal->
name)));
487 (
errcode(ERRCODE_INVALID_CURSOR_STATE),
488 errmsg(
"cannot drop active portal \"%s\"", portal->
name)));
696 elog(
ERROR,
"cannot commit while a portal is pinned");
738 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
739 errmsg(
"cannot PREPARE a transaction that has created a cursor WITH HOLD")));
1147 Portal portal = hentry->portal;
1149 bool nulls[6] = {0};
1229 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1230 errmsg(
"cannot perform transaction commands inside a cursor loop that is not read-only")));
1234 elog(
ERROR,
"pinned portal is not ready to be auto-held");
1258 int numPortalSnaps = 0;
1259 int numActiveSnaps = 0;
1288 if (numPortalSnaps != numActiveSnaps)
1289 elog(
ERROR,
"portal snapshots (%d) did not account for all active snapshots (%d)",
1290 numPortalSnaps, numActiveSnaps);
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define InvalidSubTransactionId
#define PointerIsValid(pointer)
elog(ERROR, "%s: %s", p2, msg)
void hash_seq_term(HASH_SEQ_STATUS *status)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
bool shmem_exit_inprogress
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
void MemoryContextDeleteChildren(MemoryContext context)
MemoryContext TopMemoryContext
void * MemoryContextAllocZero(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define CURSOR_OPT_SCROLL
#define CURSOR_OPT_BINARY
#define CURSOR_OPT_NO_SCROLL
#define lfirst_node(type, lc)
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
struct PortalData * Portal
void PortalCleanup(Portal portal)
void PersistHoldablePortal(Portal portal)
void AtAbort_Portals(void)
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
void EnablePortalManager(void)
void MarkPortalDone(Portal portal)
#define MAX_PORTALNAME_LEN
void PinPortal(Portal portal)
Datum pg_cursor(PG_FUNCTION_ARGS)
static HTAB * PortalHashTable
#define PortalHashTableInsert(PORTAL, NAME)
Portal CreateNewPortal(void)
bool PreCommit_Portals(bool isPrepare)
static MemoryContext TopPortalContext
void MarkPortalFailed(Portal portal)
static void PortalReleaseCachedPlan(Portal portal)
void UnpinPortal(Portal portal)
void HoldPinnedPortals(void)
void MarkPortalActive(Portal portal)
void PortalDrop(Portal portal, bool isTopCommit)
#define PortalHashTableLookup(NAME, PORTAL)
bool ThereAreNoReadyPortals(void)
Portal GetPortalByName(const char *name)
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
#define PortalHashTableDelete(PORTAL)
void AtCleanup_Portals(void)
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan)
void PortalHashTableDeleteAll(void)
static void HoldPortal(Portal portal)
Portal CreatePortal(const char *name, bool allowDup, bool dupSilent)
void AtSubCleanup_Portals(SubTransactionId mySubid)
void PortalErrorCleanup(void)
void ForgetPortalSnapshots(void)
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
struct portalhashent PortalHashEnt
void PortalCreateHoldStore(Portal portal)
static Datum BoolGetDatum(bool X)
void ResourceOwnerNewParent(ResourceOwner owner, ResourceOwner newparent)
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
void ResourceOwnerDelete(ResourceOwner owner)
ResourceOwner CurTransactionResourceOwner
@ RESOURCE_RELEASE_BEFORE_LOCKS
@ RESOURCE_RELEASE_AFTER_LOCKS
void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
bool ActiveSnapshotSet(void)
void PopActiveSnapshot(void)
SubTransactionId createSubid
SubTransactionId activeSubid
TimestampTz creation_time
MemoryContext holdContext
MemoryContext portalContext
const char * prepStmtName
Tuplestorestate * holdStore
void(* cleanup)(Portal portal)
Tuplestorestate * setResult
char portalname[MAX_PORTALNAME_LEN]
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
void tuplestore_end(Tuplestorestate *state)
static Datum TimestampTzGetDatum(TimestampTz X)
SubTransactionId GetCurrentSubTransactionId(void)
int GetCurrentTransactionNestLevel(void)
TimestampTz GetCurrentStatementStartTimestamp(void)