Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
portal.h253 linesDownload Raw Back to utils
1/*-------------------------------------------------------------------------2 *3 * portal.h4 *	  POSTGRES portal definitions.5 *6 * A portal is an abstraction which represents the execution state of7 * a running or runnable query.  Portals support both SQL-level CURSORs8 * and protocol-level portals.9 *10 * Scrolling (nonsequential access) and suspension of execution are allowed11 * only for portals that contain a single SELECT-type query.  We do not want12 * to let the client suspend an update-type query partway through!	Because13 * the query rewriter does not allow arbitrary ON SELECT rewrite rules,14 * only queries that were originally update-type could produce multiple15 * plan trees; so the restriction to a single query is not a problem16 * 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 backward21 *	   compatible, we allow backward fetches here, unless it would22 *	   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, even27 *	   if we need to take a performance hit to do so.  (The planner sticks28 *	   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 and31 * determining if scrollability can be supported without additional32 * overhead.33 *34 * Protocol-level portals have no nonsequential-fetch API and so the35 * distinction doesn't matter for them.  They are always initialized36 * to look like NO SCROLL cursors.37 *38 *39 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group40 * Portions Copyright (c) 1994, Regents of the University of California41 *42 * src/include/utils/portal.h43 *44 *-------------------------------------------------------------------------45 */46#ifndef PORTAL_H47#define PORTAL_H48 49#include "datatype/timestamp.h"50#include "executor/execdesc.h"51#include "tcop/cmdtag.h"52#include "utils/plancache.h"53#include "utils/resowner.h"54 55/*56 * We have several execution strategies for Portals, depending on what57 * query or queries are to be executed.  (Note: in all cases, a Portal58 * executes just a single source-SQL query, and thus produces just a59 * single result from the user's viewpoint.  However, the rule rewriter60 * may expand the single source query to zero or many actual queries.)61 *62 * PORTAL_ONE_SELECT: the portal contains one single SELECT query.  We run63 * the Executor incrementally as results are demanded.  This strategy also64 * supports holdable cursors (the Executor results can be dumped into a65 * tuplestore for access after transaction completion).66 *67 * PORTAL_ONE_RETURNING: the portal contains a single INSERT/UPDATE/DELETE68 * query with a RETURNING clause (plus possibly auxiliary queries added by69 * rule rewriting).  On first execution, we run the portal to completion70 * and dump the primary query's results into the portal tuplestore; the71 * results are then returned to the client as demanded.  (We can't support72 * suspension of the query partway through, because the AFTER TRIGGER code73 * can't cope, and also because we don't want to risk failing to execute74 * all the auxiliary queries.)75 *76 * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but77 * it has data-modifying CTEs.  This is currently treated the same as the78 * PORTAL_ONE_RETURNING case because of the possibility of needing to fire79 * triggers.  It may act more like PORTAL_ONE_SELECT in future.80 *81 * PORTAL_UTIL_SELECT: the portal contains a utility statement that returns82 * a SELECT-like result (for example, EXPLAIN or SHOW).  On first execution,83 * we run the statement and dump its results into the portal tuplestore;84 * the results are then returned to the client as demanded.85 *86 * PORTAL_MULTI_QUERY: all other cases.  Here, we do not support partial87 * execution: the portal's queries will be run to completion on first call.88 */89typedef enum PortalStrategy90{91	PORTAL_ONE_SELECT,92	PORTAL_ONE_RETURNING,93	PORTAL_ONE_MOD_WITH,94	PORTAL_UTIL_SELECT,95	PORTAL_MULTI_QUERY96} PortalStrategy;97 98/*99 * A portal is always in one of these states.  It is possible to transit100 * from ACTIVE back to READY if the query is not run to completion;101 * otherwise we never back up in status.102 */103typedef enum PortalStatus104{105	PORTAL_NEW,					/* freshly created */106	PORTAL_DEFINED,				/* PortalDefineQuery done */107	PORTAL_READY,				/* PortalStart complete, can run it */108	PORTAL_ACTIVE,				/* portal is running (can't delete it) */109	PORTAL_DONE,				/* portal is finished (don't re-run it) */110	PORTAL_FAILED				/* portal got error (can't re-run it) */111} PortalStatus;112 113typedef struct PortalData *Portal;114 115typedef struct PortalData116{117	/* Bookkeeping data */118	const char *name;			/* portal's name */119	const char *prepStmtName;	/* source prepared statement (NULL if none) */120	MemoryContext portalContext;	/* subsidiary memory for portal */121	ResourceOwner resowner;		/* resources owned by portal */122	void		(*cleanup) (Portal portal); /* cleanup hook */123 124	/*125	 * State data for remembering which subtransaction(s) the portal was126	 * created or used in.  If the portal is held over from a previous127	 * transaction, both subxids are InvalidSubTransactionId.  Otherwise,128	 * createSubid is the creating subxact and activeSubid is the last subxact129	 * in which we ran the portal.130	 */131	SubTransactionId createSubid;	/* the creating subxact */132	SubTransactionId activeSubid;	/* the last subxact with activity */133	int			createLevel;	/* creating subxact's nesting level */134 135	/* The query or queries the portal will execute */136	const char *sourceText;		/* text of query (as of 8.4, never NULL) */137	CommandTag	commandTag;		/* command tag for original query */138	QueryCompletion qc;			/* command completion data for executed query */139	List	   *stmts;			/* list of PlannedStmts */140	CachedPlan *cplan;			/* CachedPlan, if stmts are from one */141 142	ParamListInfo portalParams; /* params to pass to query */143	QueryEnvironment *queryEnv; /* environment for query */144 145	/* Features/options */146	PortalStrategy strategy;	/* see above */147	int			cursorOptions;	/* DECLARE CURSOR option bits */148	bool		run_once;		/* portal will only be run once */149 150	/* Status data */151	PortalStatus status;		/* see above */152	bool		portalPinned;	/* a pinned portal can't be dropped */153	bool		autoHeld;		/* was automatically converted from pinned to154								 * held (see HoldPinnedPortals()) */155 156	/* If not NULL, Executor is active; call ExecutorEnd eventually: */157	QueryDesc  *queryDesc;		/* info needed for executor invocation */158 159	/* If portal returns tuples, this is their tupdesc: */160	TupleDesc	tupDesc;		/* descriptor for result tuples */161	/* and these are the format codes to use for the columns: */162	int16	   *formats;		/* a format code for each column */163 164	/*165	 * Outermost ActiveSnapshot for execution of the portal's queries.  For166	 * all but a few utility commands, we require such a snapshot to exist.167	 * This ensures that TOAST references in query results can be detoasted,168	 * and helps to reduce thrashing of the process's exposed xmin.169	 */170	Snapshot	portalSnapshot; /* active snapshot, or NULL if none */171 172	/*173	 * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING or174	 * PORTAL_UTIL_SELECT query.  (A cursor held past the end of its175	 * transaction no longer has any active executor state.)176	 */177	Tuplestorestate *holdStore; /* store for holdable cursors */178	MemoryContext holdContext;	/* memory containing holdStore */179 180	/*181	 * Snapshot under which tuples in the holdStore were read.  We must keep a182	 * reference to this snapshot if there is any possibility that the tuples183	 * contain TOAST references, because releasing the snapshot could allow184	 * recently-dead rows to be vacuumed away, along with any toast data185	 * belonging to them.  In the case of a held cursor, we avoid needing to186	 * keep such a snapshot by forcibly detoasting the data.187	 */188	Snapshot	holdSnapshot;	/* registered snapshot, or NULL if none */189 190	/*191	 * atStart, atEnd and portalPos indicate the current cursor position.192	 * portalPos is zero before the first row, N after fetching N'th row of193	 * query.  After we run off the end, portalPos = # of rows in query, and194	 * atEnd is true.  Note that atStart implies portalPos == 0, but not the195	 * reverse: we might have backed up only as far as the first row, not to196	 * the start.  Also note that various code inspects atStart and atEnd, but197	 * only the portal movement routines should touch portalPos.198	 */199	bool		atStart;200	bool		atEnd;201	uint64		portalPos;202 203	/* Presentation data, primarily used by the pg_cursors system view */204	TimestampTz creation_time;	/* time at which this portal was defined */205	bool		visible;		/* include this portal in pg_cursors? */206}			PortalData;207 208/*209 * PortalIsValid210 *		True iff portal is valid.211 */212#define PortalIsValid(p) PointerIsValid(p)213 214 215/* Prototypes for functions in utils/mmgr/portalmem.c */216extern void EnablePortalManager(void);217extern bool PreCommit_Portals(bool isPrepare);218extern void AtAbort_Portals(void);219extern void AtCleanup_Portals(void);220extern void PortalErrorCleanup(void);221extern void AtSubCommit_Portals(SubTransactionId mySubid,222								SubTransactionId parentSubid,223								int parentLevel,224								ResourceOwner parentXactOwner);225extern void AtSubAbort_Portals(SubTransactionId mySubid,226							   SubTransactionId parentSubid,227							   ResourceOwner myXactOwner,228							   ResourceOwner parentXactOwner);229extern void AtSubCleanup_Portals(SubTransactionId mySubid);230extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);231extern Portal CreateNewPortal(void);232extern void PinPortal(Portal portal);233extern void UnpinPortal(Portal portal);234extern void MarkPortalActive(Portal portal);235extern void MarkPortalDone(Portal portal);236extern void MarkPortalFailed(Portal portal);237extern void PortalDrop(Portal portal, bool isTopCommit);238extern Portal GetPortalByName(const char *name);239extern void PortalDefineQuery(Portal portal,240							  const char *prepStmtName,241							  const char *sourceText,242							  CommandTag commandTag,243							  List *stmts,244							  CachedPlan *cplan);245extern PlannedStmt *PortalGetPrimaryStmt(Portal portal);246extern void PortalCreateHoldStore(Portal portal);247extern void PortalHashTableDeleteAll(void);248extern bool ThereAreNoReadyPortals(void);249extern void HoldPinnedPortals(void);250extern void ForgetPortalSnapshots(void);251 252#endif							/* PORTAL_H */253 
codekingpro/portable-devtools · Team Ai