38 #define PORTALS_PER_USER 16
46 #define MAX_PORTALNAME_LEN NAMEDATALEN
56 #define PortalHashTableLookup(NAME, PORTAL) \
58 PortalHashEnt *hentry; \
60 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
61 (NAME), HASH_FIND, NULL); \
63 PORTAL = hentry->portal; \
68 #define PortalHashTableInsert(PORTAL, NAME) \
70 PortalHashEnt *hentry; bool found; \
72 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
73 (NAME), HASH_ENTER, &found); \
75 elog(ERROR, "duplicate portal name"); \
76 hentry->portal = PORTAL; \
78 PORTAL->name = hentry->portalname; \
81 #define PortalHashTableDelete(PORTAL) \
83 PortalHashEnt *hentry; \
85 hentry = (PortalHashEnt *) hash_search(PortalHashTable, \
86 PORTAL->name, HASH_REMOVE, NULL); \
88 elog(WARNING, "trying to delete portal name that does not exist"); \
155 foreach(lc, portal->
stmts)
186 (
errcode(ERRCODE_DUPLICATE_CURSOR),
187 errmsg(
"cursor \"%s\" already exists",
name)));
190 (
errcode(ERRCODE_DUPLICATE_CURSOR),
191 errmsg(
"closing existing cursor \"%s\"",
217 portal->
atEnd =
true;
237 static unsigned int unnamed_portal_count = 0;
244 unnamed_portal_count++;
245 sprintf(portalname,
"<unnamed portal %u>", unnamed_portal_count);
283 const char *prepStmtName,
284 const char *sourceText,
292 Assert(sourceText != NULL);
293 Assert(commandTag != CMDTAG_UNKNOWN || stmts ==
NIL);
300 portal->
stmts = stmts;
301 portal->
cplan = cplan;
315 portal->
cplan = NULL;
400 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
401 errmsg(
"portal \"%s\" cannot be run", portal->
name)));
478 (
errcode(ERRCODE_INVALID_CURSOR_STATE),
479 errmsg(
"cannot drop pinned portal \"%s\"", portal->
name)));
486 (
errcode(ERRCODE_INVALID_CURSOR_STATE),
487 errmsg(
"cannot drop active portal \"%s\"", portal->
name)));
695 elog(
ERROR,
"cannot commit while a portal is pinned");
737 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
738 errmsg(
"cannot PREPARE a transaction that has created a cursor WITH HOLD")));
1146 Portal portal = hentry->portal;
1148 bool nulls[6] = {0};
1231 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1232 errmsg(
"cannot perform transaction commands inside a cursor loop that is not read-only")));
1236 elog(
ERROR,
"pinned portal is not ready to be auto-held");
1260 int numPortalSnaps = 0;
1261 int numActiveSnaps = 0;
1290 if (numPortalSnaps != numActiveSnaps)
1291 elog(
ERROR,
"portal snapshots (%d) did not account for all active snapshots (%d)",
1292 numPortalSnaps, numActiveSnaps);
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define InvalidSubTransactionId
#define Assert(condition)
#define PointerIsValid(pointer)
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
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
#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)
MemoryContextSwitchTo(old_ctx)
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)