Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
plpgsql.h1340 linesDownload Raw Back to server
1/*-------------------------------------------------------------------------2 *3 * plpgsql.h		- Definitions for the PL/pgSQL4 *			  procedural language5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 *10 * IDENTIFICATION11 *	  src/pl/plpgsql/src/plpgsql.h12 *13 *-------------------------------------------------------------------------14 */15 16#ifndef PLPGSQL_H17#define PLPGSQL_H18 19#include "access/xact.h"20#include "commands/event_trigger.h"21#include "commands/trigger.h"22#include "executor/spi.h"23#include "utils/expandedrecord.h"24#include "utils/typcache.h"25 26 27/**********************************************************************28 * Definitions29 **********************************************************************/30 31/* define our text domain for translations */32#undef TEXTDOMAIN33#define TEXTDOMAIN PG_TEXTDOMAIN("plpgsql")34 35#undef _36#define _(x) dgettext(TEXTDOMAIN, x)37 38/*39 * Compiler's namespace item types40 */41typedef enum PLpgSQL_nsitem_type42{43	PLPGSQL_NSTYPE_LABEL,		/* block label */44	PLPGSQL_NSTYPE_VAR,			/* scalar variable */45	PLPGSQL_NSTYPE_REC			/* composite variable */46} PLpgSQL_nsitem_type;47 48/*49 * A PLPGSQL_NSTYPE_LABEL stack entry must be one of these types50 */51typedef enum PLpgSQL_label_type52{53	PLPGSQL_LABEL_BLOCK,		/* DECLARE/BEGIN block */54	PLPGSQL_LABEL_LOOP,			/* looping construct */55	PLPGSQL_LABEL_OTHER			/* anything else */56} PLpgSQL_label_type;57 58/*59 * Datum array node types60 */61typedef enum PLpgSQL_datum_type62{63	PLPGSQL_DTYPE_VAR,64	PLPGSQL_DTYPE_ROW,65	PLPGSQL_DTYPE_REC,66	PLPGSQL_DTYPE_RECFIELD,67	PLPGSQL_DTYPE_PROMISE68} PLpgSQL_datum_type;69 70/*71 * DTYPE_PROMISE datums have these possible ways of computing the promise72 */73typedef enum PLpgSQL_promise_type74{75	PLPGSQL_PROMISE_NONE = 0,	/* not a promise, or promise satisfied */76	PLPGSQL_PROMISE_TG_NAME,77	PLPGSQL_PROMISE_TG_WHEN,78	PLPGSQL_PROMISE_TG_LEVEL,79	PLPGSQL_PROMISE_TG_OP,80	PLPGSQL_PROMISE_TG_RELID,81	PLPGSQL_PROMISE_TG_TABLE_NAME,82	PLPGSQL_PROMISE_TG_TABLE_SCHEMA,83	PLPGSQL_PROMISE_TG_NARGS,84	PLPGSQL_PROMISE_TG_ARGV,85	PLPGSQL_PROMISE_TG_EVENT,86	PLPGSQL_PROMISE_TG_TAG87} PLpgSQL_promise_type;88 89/*90 * Variants distinguished in PLpgSQL_type structs91 */92typedef enum PLpgSQL_type_type93{94	PLPGSQL_TTYPE_SCALAR,		/* scalar types and domains */95	PLPGSQL_TTYPE_REC,			/* composite types, including RECORD */96	PLPGSQL_TTYPE_PSEUDO		/* pseudotypes */97} PLpgSQL_type_type;98 99/*100 * Execution tree node types101 */102typedef enum PLpgSQL_stmt_type103{104	PLPGSQL_STMT_BLOCK,105	PLPGSQL_STMT_ASSIGN,106	PLPGSQL_STMT_IF,107	PLPGSQL_STMT_CASE,108	PLPGSQL_STMT_LOOP,109	PLPGSQL_STMT_WHILE,110	PLPGSQL_STMT_FORI,111	PLPGSQL_STMT_FORS,112	PLPGSQL_STMT_FORC,113	PLPGSQL_STMT_FOREACH_A,114	PLPGSQL_STMT_EXIT,115	PLPGSQL_STMT_RETURN,116	PLPGSQL_STMT_RETURN_NEXT,117	PLPGSQL_STMT_RETURN_QUERY,118	PLPGSQL_STMT_RAISE,119	PLPGSQL_STMT_ASSERT,120	PLPGSQL_STMT_EXECSQL,121	PLPGSQL_STMT_DYNEXECUTE,122	PLPGSQL_STMT_DYNFORS,123	PLPGSQL_STMT_GETDIAG,124	PLPGSQL_STMT_OPEN,125	PLPGSQL_STMT_FETCH,126	PLPGSQL_STMT_CLOSE,127	PLPGSQL_STMT_PERFORM,128	PLPGSQL_STMT_CALL,129	PLPGSQL_STMT_COMMIT,130	PLPGSQL_STMT_ROLLBACK131} PLpgSQL_stmt_type;132 133/*134 * Execution node return codes135 */136enum137{138	PLPGSQL_RC_OK,139	PLPGSQL_RC_EXIT,140	PLPGSQL_RC_RETURN,141	PLPGSQL_RC_CONTINUE142};143 144/*145 * GET DIAGNOSTICS information items146 */147typedef enum PLpgSQL_getdiag_kind148{149	PLPGSQL_GETDIAG_ROW_COUNT,150	PLPGSQL_GETDIAG_ROUTINE_OID,151	PLPGSQL_GETDIAG_CONTEXT,152	PLPGSQL_GETDIAG_ERROR_CONTEXT,153	PLPGSQL_GETDIAG_ERROR_DETAIL,154	PLPGSQL_GETDIAG_ERROR_HINT,155	PLPGSQL_GETDIAG_RETURNED_SQLSTATE,156	PLPGSQL_GETDIAG_COLUMN_NAME,157	PLPGSQL_GETDIAG_CONSTRAINT_NAME,158	PLPGSQL_GETDIAG_DATATYPE_NAME,159	PLPGSQL_GETDIAG_MESSAGE_TEXT,160	PLPGSQL_GETDIAG_TABLE_NAME,161	PLPGSQL_GETDIAG_SCHEMA_NAME162} PLpgSQL_getdiag_kind;163 164/*165 * RAISE statement options166 */167typedef enum PLpgSQL_raise_option_type168{169	PLPGSQL_RAISEOPTION_ERRCODE,170	PLPGSQL_RAISEOPTION_MESSAGE,171	PLPGSQL_RAISEOPTION_DETAIL,172	PLPGSQL_RAISEOPTION_HINT,173	PLPGSQL_RAISEOPTION_COLUMN,174	PLPGSQL_RAISEOPTION_CONSTRAINT,175	PLPGSQL_RAISEOPTION_DATATYPE,176	PLPGSQL_RAISEOPTION_TABLE,177	PLPGSQL_RAISEOPTION_SCHEMA178} PLpgSQL_raise_option_type;179 180/*181 * Behavioral modes for plpgsql variable resolution182 */183typedef enum PLpgSQL_resolve_option184{185	PLPGSQL_RESOLVE_ERROR,		/* throw error if ambiguous */186	PLPGSQL_RESOLVE_VARIABLE,	/* prefer plpgsql var to table column */187	PLPGSQL_RESOLVE_COLUMN		/* prefer table column to plpgsql var */188} PLpgSQL_resolve_option;189 190 191/**********************************************************************192 * Node and structure definitions193 **********************************************************************/194 195/*196 * Postgres data type197 */198typedef struct PLpgSQL_type199{200	char	   *typname;		/* (simple) name of the type */201	Oid			typoid;			/* OID of the data type */202	PLpgSQL_type_type ttype;	/* PLPGSQL_TTYPE_ code */203	int16		typlen;			/* stuff copied from its pg_type entry */204	bool		typbyval;205	char		typtype;206	Oid			collation;		/* from pg_type, but can be overridden */207	bool		typisarray;		/* is "true" array, or domain over one */208	int32		atttypmod;		/* typmod (taken from someplace else) */209	/* Remaining fields are used only for named composite types (not RECORD) */210	TypeName   *origtypname;	/* type name as written by user */211	TypeCacheEntry *tcache;		/* typcache entry for composite type */212	uint64		tupdesc_id;		/* last-seen tupdesc identifier */213} PLpgSQL_type;214 215/*216 * SQL Query to plan and execute217 */218typedef struct PLpgSQL_expr219{220	char	   *query;			/* query string, verbatim from function body */221	RawParseMode parseMode;		/* raw_parser() mode to use */222	SPIPlanPtr	plan;			/* plan, or NULL if not made yet */223	Bitmapset  *paramnos;		/* all dnos referenced by this query */224 225	/* function containing this expr (not set until we first parse query) */226	struct PLpgSQL_function *func;227 228	/* namespace chain visible to this expr */229	struct PLpgSQL_nsitem *ns;230 231	/* fields for "simple expression" fast-path execution: */232	Expr	   *expr_simple_expr;	/* NULL means not a simple expr */233	Oid			expr_simple_type;	/* result type Oid, if simple */234	int32		expr_simple_typmod; /* result typmod, if simple */235	bool		expr_simple_mutable;	/* true if simple expr is mutable */236 237	/*238	 * These fields are used to optimize assignments to expanded-datum239	 * variables.  If this expression is the source of an assignment to a240	 * simple variable, target_param holds that variable's dno; else it's -1.241	 * If we match a Param within expr_simple_expr to such a variable, that242	 * Param's address is stored in expr_rw_param; then expression code243	 * generation will allow the value for that Param to be passed read/write.244	 */245	int			target_param;	/* dno of assign target, or -1 if none */246	Param	   *expr_rw_param;	/* read/write Param within expr, if any */247 248	/*249	 * If the expression was ever determined to be simple, we remember its250	 * CachedPlanSource and CachedPlan here.  If expr_simple_plan_lxid matches251	 * current LXID, then we hold a refcount on expr_simple_plan in the252	 * current transaction.  Otherwise we need to get one before re-using it.253	 */254	CachedPlanSource *expr_simple_plansource;	/* extracted from "plan" */255	CachedPlan *expr_simple_plan;	/* extracted from "plan" */256	LocalTransactionId expr_simple_plan_lxid;257 258	/*259	 * if expr is simple AND prepared in current transaction,260	 * expr_simple_state and expr_simple_in_use are valid. Test validity by261	 * seeing if expr_simple_lxid matches current LXID.  (If not,262	 * expr_simple_state probably points at garbage!)263	 */264	ExprState  *expr_simple_state;	/* eval tree for expr_simple_expr */265	bool		expr_simple_in_use; /* true if eval tree is active */266	LocalTransactionId expr_simple_lxid;267} PLpgSQL_expr;268 269/*270 * Generic datum array item271 *272 * PLpgSQL_datum is the common supertype for PLpgSQL_var, PLpgSQL_row,273 * PLpgSQL_rec, and PLpgSQL_recfield.274 */275typedef struct PLpgSQL_datum276{277	PLpgSQL_datum_type dtype;278	int			dno;279} PLpgSQL_datum;280 281/*282 * Scalar or composite variable283 *284 * The variants PLpgSQL_var, PLpgSQL_row, and PLpgSQL_rec share these285 * fields.286 */287typedef struct PLpgSQL_variable288{289	PLpgSQL_datum_type dtype;290	int			dno;291	char	   *refname;292	int			lineno;293	bool		isconst;294	bool		notnull;295	PLpgSQL_expr *default_val;296} PLpgSQL_variable;297 298/*299 * Scalar variable300 *301 * DTYPE_VAR and DTYPE_PROMISE datums both use this struct type.302 * A PROMISE datum works exactly like a VAR datum for most purposes,303 * but if it is read without having previously been assigned to, then304 * a special "promised" value is computed and assigned to the datum305 * before the read is performed.  This technique avoids the overhead of306 * computing the variable's value in cases where we expect that many307 * functions will never read it.308 */309typedef struct PLpgSQL_var310{311	PLpgSQL_datum_type dtype;312	int			dno;313	char	   *refname;314	int			lineno;315	bool		isconst;316	bool		notnull;317	PLpgSQL_expr *default_val;318	/* end of PLpgSQL_variable fields */319 320	PLpgSQL_type *datatype;321 322	/*323	 * Variables declared as CURSOR FOR <query> are mostly like ordinary324	 * scalar variables of type refcursor, but they have these additional325	 * properties:326	 */327	PLpgSQL_expr *cursor_explicit_expr;328	int			cursor_explicit_argrow;329	int			cursor_options;330 331	/* Fields below here can change at runtime */332 333	Datum		value;334	bool		isnull;335	bool		freeval;336 337	/*338	 * The promise field records which "promised" value to assign if the339	 * promise must be honored.  If it's a normal variable, or the promise has340	 * been fulfilled, this is PLPGSQL_PROMISE_NONE.341	 */342	PLpgSQL_promise_type promise;343} PLpgSQL_var;344 345/*346 * Row variable - this represents one or more variables that are listed in an347 * INTO clause, FOR-loop targetlist, cursor argument list, etc.  We also use348 * a row to represent a function's OUT parameters when there's more than one.349 *350 * Note that there's no way to name the row as such from PL/pgSQL code,351 * so many functions don't need to support these.352 *353 * That also means that there's no real name for the row variable, so we354 * conventionally set refname to "(unnamed row)".  We could leave it NULL,355 * but it's too convenient to be able to assume that refname is valid in356 * all variants of PLpgSQL_variable.357 *358 * isconst, notnull, and default_val are unsupported (and hence359 * always zero/null) for a row.  The member variables of a row should have360 * been checked to be writable at compile time, so isconst is correctly set361 * to false.  notnull and default_val aren't applicable.362 */363typedef struct PLpgSQL_row364{365	PLpgSQL_datum_type dtype;366	int			dno;367	char	   *refname;368	int			lineno;369	bool		isconst;370	bool		notnull;371	PLpgSQL_expr *default_val;372	/* end of PLpgSQL_variable fields */373 374	/*375	 * rowtupdesc is only set up if we might need to convert the row into a376	 * composite datum, which currently only happens for OUT parameters.377	 * Otherwise it is NULL.378	 */379	TupleDesc	rowtupdesc;380 381	int			nfields;382	char	  **fieldnames;383	int		   *varnos;384} PLpgSQL_row;385 386/*387 * Record variable (any composite type, including RECORD)388 */389typedef struct PLpgSQL_rec390{391	PLpgSQL_datum_type dtype;392	int			dno;393	char	   *refname;394	int			lineno;395	bool		isconst;396	bool		notnull;397	PLpgSQL_expr *default_val;398	/* end of PLpgSQL_variable fields */399 400	/*401	 * Note: for non-RECORD cases, we may from time to time re-look-up the402	 * composite type, using datatype->origtypname.  That can result in403	 * changing rectypeid.404	 */405 406	PLpgSQL_type *datatype;		/* can be NULL, if rectypeid is RECORDOID */407	Oid			rectypeid;		/* declared type of variable */408	/* RECFIELDs for this record are chained together for easy access */409	int			firstfield;		/* dno of first RECFIELD, or -1 if none */410 411	/* Fields below here can change at runtime */412 413	/* We always store record variables as "expanded" records */414	ExpandedRecordHeader *erh;415} PLpgSQL_rec;416 417/*418 * Field in record419 */420typedef struct PLpgSQL_recfield421{422	PLpgSQL_datum_type dtype;423	int			dno;424	/* end of PLpgSQL_datum fields */425 426	char	   *fieldname;		/* name of field */427	int			recparentno;	/* dno of parent record */428	int			nextfield;		/* dno of next child, or -1 if none */429	uint64		rectupledescid; /* record's tupledesc ID as of last lookup */430	ExpandedRecordFieldInfo finfo;	/* field's attnum and type info */431	/* if rectupledescid == INVALID_TUPLEDESC_IDENTIFIER, finfo isn't valid */432} PLpgSQL_recfield;433 434/*435 * Item in the compilers namespace tree436 */437typedef struct PLpgSQL_nsitem438{439	PLpgSQL_nsitem_type itemtype;440 441	/*442	 * For labels, itemno is a value of enum PLpgSQL_label_type. For other443	 * itemtypes, itemno is the associated PLpgSQL_datum's dno.444	 */445	int			itemno;446	struct PLpgSQL_nsitem *prev;447	char		name[FLEXIBLE_ARRAY_MEMBER];	/* nul-terminated string */448} PLpgSQL_nsitem;449 450/*451 * Generic execution node452 */453typedef struct PLpgSQL_stmt454{455	PLpgSQL_stmt_type cmd_type;456	int			lineno;457 458	/*459	 * Unique statement ID in this function (starting at 1; 0 is invalid/not460	 * set).  This can be used by a profiler as the index for an array of461	 * per-statement metrics.462	 */463	unsigned int stmtid;464} PLpgSQL_stmt;465 466/*467 * One EXCEPTION condition name468 */469typedef struct PLpgSQL_condition470{471	int			sqlerrstate;	/* SQLSTATE code */472	char	   *condname;		/* condition name (for debugging) */473	struct PLpgSQL_condition *next;474} PLpgSQL_condition;475 476/*477 * EXCEPTION block478 */479typedef struct PLpgSQL_exception_block480{481	int			sqlstate_varno;482	int			sqlerrm_varno;483	List	   *exc_list;		/* List of WHEN clauses */484} PLpgSQL_exception_block;485 486/*487 * One EXCEPTION ... WHEN clause488 */489typedef struct PLpgSQL_exception490{491	int			lineno;492	PLpgSQL_condition *conditions;493	List	   *action;			/* List of statements */494} PLpgSQL_exception;495 496/*497 * Block of statements498 */499typedef struct PLpgSQL_stmt_block500{501	PLpgSQL_stmt_type cmd_type;502	int			lineno;503	unsigned int stmtid;504	char	   *label;505	List	   *body;			/* List of statements */506	int			n_initvars;		/* Length of initvarnos[] */507	int		   *initvarnos;		/* dnos of variables declared in this block */508	PLpgSQL_exception_block *exceptions;509} PLpgSQL_stmt_block;510 511/*512 * Assign statement513 */514typedef struct PLpgSQL_stmt_assign515{516	PLpgSQL_stmt_type cmd_type;517	int			lineno;518	unsigned int stmtid;519	int			varno;520	PLpgSQL_expr *expr;521} PLpgSQL_stmt_assign;522 523/*524 * PERFORM statement525 */526typedef struct PLpgSQL_stmt_perform527{528	PLpgSQL_stmt_type cmd_type;529	int			lineno;530	unsigned int stmtid;531	PLpgSQL_expr *expr;532} PLpgSQL_stmt_perform;533 534/*535 * CALL statement536 */537typedef struct PLpgSQL_stmt_call538{539	PLpgSQL_stmt_type cmd_type;540	int			lineno;541	unsigned int stmtid;542	PLpgSQL_expr *expr;543	bool		is_call;544	PLpgSQL_variable *target;545} PLpgSQL_stmt_call;546 547/*548 * COMMIT statement549 */550typedef struct PLpgSQL_stmt_commit551{552	PLpgSQL_stmt_type cmd_type;553	int			lineno;554	unsigned int stmtid;555	bool		chain;556} PLpgSQL_stmt_commit;557 558/*559 * ROLLBACK statement560 */561typedef struct PLpgSQL_stmt_rollback562{563	PLpgSQL_stmt_type cmd_type;564	int			lineno;565	unsigned int stmtid;566	bool		chain;567} PLpgSQL_stmt_rollback;568 569/*570 * GET DIAGNOSTICS item571 */572typedef struct PLpgSQL_diag_item573{574	PLpgSQL_getdiag_kind kind;	/* id for diagnostic value desired */575	int			target;			/* where to assign it */576} PLpgSQL_diag_item;577 578/*579 * GET DIAGNOSTICS statement580 */581typedef struct PLpgSQL_stmt_getdiag582{583	PLpgSQL_stmt_type cmd_type;584	int			lineno;585	unsigned int stmtid;586	bool		is_stacked;		/* STACKED or CURRENT diagnostics area? */587	List	   *diag_items;		/* List of PLpgSQL_diag_item */588} PLpgSQL_stmt_getdiag;589 590/*591 * IF statement592 */593typedef struct PLpgSQL_stmt_if594{595	PLpgSQL_stmt_type cmd_type;596	int			lineno;597	unsigned int stmtid;598	PLpgSQL_expr *cond;			/* boolean expression for THEN */599	List	   *then_body;		/* List of statements */600	List	   *elsif_list;		/* List of PLpgSQL_if_elsif structs */601	List	   *else_body;		/* List of statements */602} PLpgSQL_stmt_if;603 604/*605 * one ELSIF arm of IF statement606 */607typedef struct PLpgSQL_if_elsif608{609	int			lineno;610	PLpgSQL_expr *cond;			/* boolean expression for this case */611	List	   *stmts;			/* List of statements */612} PLpgSQL_if_elsif;613 614/*615 * CASE statement616 */617typedef struct PLpgSQL_stmt_case618{619	PLpgSQL_stmt_type cmd_type;620	int			lineno;621	unsigned int stmtid;622	PLpgSQL_expr *t_expr;		/* test expression, or NULL if none */623	int			t_varno;		/* var to store test expression value into */624	List	   *case_when_list; /* List of PLpgSQL_case_when structs */625	bool		have_else;		/* flag needed because list could be empty */626	List	   *else_stmts;		/* List of statements */627} PLpgSQL_stmt_case;628 629/*630 * one arm of CASE statement631 */632typedef struct PLpgSQL_case_when633{634	int			lineno;635	PLpgSQL_expr *expr;			/* boolean expression for this case */636	List	   *stmts;			/* List of statements */637} PLpgSQL_case_when;638 639/*640 * Unconditional LOOP statement641 */642typedef struct PLpgSQL_stmt_loop643{644	PLpgSQL_stmt_type cmd_type;645	int			lineno;646	unsigned int stmtid;647	char	   *label;648	List	   *body;			/* List of statements */649} PLpgSQL_stmt_loop;650 651/*652 * WHILE cond LOOP statement653 */654typedef struct PLpgSQL_stmt_while655{656	PLpgSQL_stmt_type cmd_type;657	int			lineno;658	unsigned int stmtid;659	char	   *label;660	PLpgSQL_expr *cond;661	List	   *body;			/* List of statements */662} PLpgSQL_stmt_while;663 664/*665 * FOR statement with integer loopvar666 */667typedef struct PLpgSQL_stmt_fori668{669	PLpgSQL_stmt_type cmd_type;670	int			lineno;671	unsigned int stmtid;672	char	   *label;673	PLpgSQL_var *var;674	PLpgSQL_expr *lower;675	PLpgSQL_expr *upper;676	PLpgSQL_expr *step;			/* NULL means default (ie, BY 1) */677	int			reverse;678	List	   *body;			/* List of statements */679} PLpgSQL_stmt_fori;680 681/*682 * PLpgSQL_stmt_forq represents a FOR statement running over a SQL query.683 * It is the common supertype of PLpgSQL_stmt_fors, PLpgSQL_stmt_forc684 * and PLpgSQL_stmt_dynfors.685 */686typedef struct PLpgSQL_stmt_forq687{688	PLpgSQL_stmt_type cmd_type;689	int			lineno;690	unsigned int stmtid;691	char	   *label;692	PLpgSQL_variable *var;		/* Loop variable (record or row) */693	List	   *body;			/* List of statements */694} PLpgSQL_stmt_forq;695 696/*697 * FOR statement running over SELECT698 */699typedef struct PLpgSQL_stmt_fors700{701	PLpgSQL_stmt_type cmd_type;702	int			lineno;703	unsigned int stmtid;704	char	   *label;705	PLpgSQL_variable *var;		/* Loop variable (record or row) */706	List	   *body;			/* List of statements */707	/* end of fields that must match PLpgSQL_stmt_forq */708	PLpgSQL_expr *query;709} PLpgSQL_stmt_fors;710 711/*712 * FOR statement running over cursor713 */714typedef struct PLpgSQL_stmt_forc715{716	PLpgSQL_stmt_type cmd_type;717	int			lineno;718	unsigned int stmtid;719	char	   *label;720	PLpgSQL_variable *var;		/* Loop variable (record or row) */721	List	   *body;			/* List of statements */722	/* end of fields that must match PLpgSQL_stmt_forq */723	int			curvar;724	PLpgSQL_expr *argquery;		/* cursor arguments if any */725} PLpgSQL_stmt_forc;726 727/*728 * FOR statement running over EXECUTE729 */730typedef struct PLpgSQL_stmt_dynfors731{732	PLpgSQL_stmt_type cmd_type;733	int			lineno;734	unsigned int stmtid;735	char	   *label;736	PLpgSQL_variable *var;		/* Loop variable (record or row) */737	List	   *body;			/* List of statements */738	/* end of fields that must match PLpgSQL_stmt_forq */739	PLpgSQL_expr *query;740	List	   *params;			/* USING expressions */741} PLpgSQL_stmt_dynfors;742 743/*744 * FOREACH item in array loop745 */746typedef struct PLpgSQL_stmt_foreach_a747{748	PLpgSQL_stmt_type cmd_type;749	int			lineno;750	unsigned int stmtid;751	char	   *label;752	int			varno;			/* loop target variable */753	int			slice;			/* slice dimension, or 0 */754	PLpgSQL_expr *expr;			/* array expression */755	List	   *body;			/* List of statements */756} PLpgSQL_stmt_foreach_a;757 758/*759 * OPEN a curvar760 */761typedef struct PLpgSQL_stmt_open762{763	PLpgSQL_stmt_type cmd_type;764	int			lineno;765	unsigned int stmtid;766	int			curvar;767	int			cursor_options;768	PLpgSQL_expr *argquery;769	PLpgSQL_expr *query;770	PLpgSQL_expr *dynquery;771	List	   *params;			/* USING expressions */772} PLpgSQL_stmt_open;773 774/*775 * FETCH or MOVE statement776 */777typedef struct PLpgSQL_stmt_fetch778{779	PLpgSQL_stmt_type cmd_type;780	int			lineno;781	unsigned int stmtid;782	PLpgSQL_variable *target;	/* target (record or row) */783	int			curvar;			/* cursor variable to fetch from */784	FetchDirection direction;	/* fetch direction */785	long		how_many;		/* count, if constant (expr is NULL) */786	PLpgSQL_expr *expr;			/* count, if expression */787	bool		is_move;		/* is this a fetch or move? */788	bool		returns_multiple_rows;	/* can return more than one row? */789} PLpgSQL_stmt_fetch;790 791/*792 * CLOSE curvar793 */794typedef struct PLpgSQL_stmt_close795{796	PLpgSQL_stmt_type cmd_type;797	int			lineno;798	unsigned int stmtid;799	int			curvar;800} PLpgSQL_stmt_close;801 802/*803 * EXIT or CONTINUE statement804 */805typedef struct PLpgSQL_stmt_exit806{807	PLpgSQL_stmt_type cmd_type;808	int			lineno;809	unsigned int stmtid;810	bool		is_exit;		/* Is this an exit or a continue? */811	char	   *label;			/* NULL if it's an unlabeled EXIT/CONTINUE */812	PLpgSQL_expr *cond;813} PLpgSQL_stmt_exit;814 815/*816 * RETURN statement817 */818typedef struct PLpgSQL_stmt_return819{820	PLpgSQL_stmt_type cmd_type;821	int			lineno;822	unsigned int stmtid;823	PLpgSQL_expr *expr;824	int			retvarno;825} PLpgSQL_stmt_return;826 827/*828 * RETURN NEXT statement829 */830typedef struct PLpgSQL_stmt_return_next831{832	PLpgSQL_stmt_type cmd_type;833	int			lineno;834	unsigned int stmtid;835	PLpgSQL_expr *expr;836	int			retvarno;837} PLpgSQL_stmt_return_next;838 839/*840 * RETURN QUERY statement841 */842typedef struct PLpgSQL_stmt_return_query843{844	PLpgSQL_stmt_type cmd_type;845	int			lineno;846	unsigned int stmtid;847	PLpgSQL_expr *query;		/* if static query */848	PLpgSQL_expr *dynquery;		/* if dynamic query (RETURN QUERY EXECUTE) */849	List	   *params;			/* USING arguments for dynamic query */850} PLpgSQL_stmt_return_query;851 852/*853 * RAISE statement854 */855typedef struct PLpgSQL_stmt_raise856{857	PLpgSQL_stmt_type cmd_type;858	int			lineno;859	unsigned int stmtid;860	int			elog_level;861	char	   *condname;		/* condition name, SQLSTATE, or NULL */862	char	   *message;		/* old-style message format literal, or NULL */863	List	   *params;			/* list of expressions for old-style message */864	List	   *options;		/* list of PLpgSQL_raise_option */865} PLpgSQL_stmt_raise;866 867/*868 * RAISE statement option869 */870typedef struct PLpgSQL_raise_option871{872	PLpgSQL_raise_option_type opt_type;873	PLpgSQL_expr *expr;874} PLpgSQL_raise_option;875 876/*877 * ASSERT statement878 */879typedef struct PLpgSQL_stmt_assert880{881	PLpgSQL_stmt_type cmd_type;882	int			lineno;883	unsigned int stmtid;884	PLpgSQL_expr *cond;885	PLpgSQL_expr *message;886} PLpgSQL_stmt_assert;887 888/*889 * Generic SQL statement to execute890 */891typedef struct PLpgSQL_stmt_execsql892{893	PLpgSQL_stmt_type cmd_type;894	int			lineno;895	unsigned int stmtid;896	PLpgSQL_expr *sqlstmt;897	bool		mod_stmt;		/* is the stmt INSERT/UPDATE/DELETE/MERGE? */898	bool		mod_stmt_set;	/* is mod_stmt valid yet? */899	bool		into;			/* INTO supplied? */900	bool		strict;			/* INTO STRICT flag */901	PLpgSQL_variable *target;	/* INTO target (record or row) */902} PLpgSQL_stmt_execsql;903 904/*905 * Dynamic SQL string to execute906 */907typedef struct PLpgSQL_stmt_dynexecute908{909	PLpgSQL_stmt_type cmd_type;910	int			lineno;911	unsigned int stmtid;912	PLpgSQL_expr *query;		/* string expression */913	bool		into;			/* INTO supplied? */914	bool		strict;			/* INTO STRICT flag */915	PLpgSQL_variable *target;	/* INTO target (record or row) */916	List	   *params;			/* USING expressions */917} PLpgSQL_stmt_dynexecute;918 919/*920 * Hash lookup key for functions921 */922typedef struct PLpgSQL_func_hashkey923{924	Oid			funcOid;925 926	bool		isTrigger;		/* true if called as a DML trigger */927	bool		isEventTrigger; /* true if called as an event trigger */928 929	/* be careful that pad bytes in this struct get zeroed! */930 931	/*932	 * For a trigger function, the OID of the trigger is part of the hash key933	 * --- we want to compile the trigger function separately for each trigger934	 * it is used with, in case the rowtype or transition table names are935	 * different.  Zero if not called as a DML trigger.936	 */937	Oid			trigOid;938 939	/*940	 * We must include the input collation as part of the hash key too,941	 * because we have to generate different plans (with different Param942	 * collations) for different collation settings.943	 */944	Oid			inputCollation;945 946	/*947	 * We include actual argument types in the hash key to support polymorphic948	 * PLpgSQL functions.  Be careful that extra positions are zeroed!949	 */950	Oid			argtypes[FUNC_MAX_ARGS];951} PLpgSQL_func_hashkey;952 953/*954 * Trigger type955 */956typedef enum PLpgSQL_trigtype957{958	PLPGSQL_DML_TRIGGER,959	PLPGSQL_EVENT_TRIGGER,960	PLPGSQL_NOT_TRIGGER961} PLpgSQL_trigtype;962 963/*964 * Complete compiled function965 */966typedef struct PLpgSQL_function967{968	char	   *fn_signature;969	Oid			fn_oid;970	TransactionId fn_xmin;971	ItemPointerData fn_tid;972	PLpgSQL_trigtype fn_is_trigger;973	Oid			fn_input_collation;974	PLpgSQL_func_hashkey *fn_hashkey;	/* back-link to hashtable key */975	MemoryContext fn_cxt;976 977	Oid			fn_rettype;978	int			fn_rettyplen;979	bool		fn_retbyval;980	bool		fn_retistuple;981	bool		fn_retisdomain;982	bool		fn_retset;983	bool		fn_readonly;984	char		fn_prokind;985 986	int			fn_nargs;987	int			fn_argvarnos[FUNC_MAX_ARGS];988	int			out_param_varno;989	int			found_varno;990	int			new_varno;991	int			old_varno;992 993	PLpgSQL_resolve_option resolve_option;994 995	bool		print_strict_params;996 997	/* extra checks */998	int			extra_warnings;999	int			extra_errors;1000 1001	/* the datums representing the function's local variables */1002	int			ndatums;1003	PLpgSQL_datum **datums;1004	Size		copiable_size;	/* space for locally instantiated datums */1005 1006	/* function body parsetree */1007	PLpgSQL_stmt_block *action;1008 1009	/* data derived while parsing body */1010	unsigned int nstatements;	/* counter for assigning stmtids */1011	bool		requires_procedure_resowner;	/* contains CALL or DO? */1012 1013	/* these fields change when the function is used */1014	struct PLpgSQL_execstate *cur_estate;1015	unsigned long use_count;1016} PLpgSQL_function;1017 1018/*1019 * Runtime execution data1020 */1021typedef struct PLpgSQL_execstate1022{1023	PLpgSQL_function *func;		/* function being executed */1024 1025	TriggerData *trigdata;		/* if regular trigger, data about firing */1026	EventTriggerData *evtrigdata;	/* if event trigger, data about firing */1027 1028	Datum		retval;1029	bool		retisnull;1030	Oid			rettype;		/* type of current retval */1031 1032	Oid			fn_rettype;		/* info about declared function rettype */1033	bool		retistuple;1034	bool		retisset;1035 1036	bool		readonly_func;1037	bool		atomic;1038 1039	char	   *exitlabel;		/* the "target" label of the current EXIT or1040								 * CONTINUE stmt, if any */1041	ErrorData  *cur_error;		/* current exception handler's error */1042 1043	Tuplestorestate *tuple_store;	/* SRFs accumulate results here */1044	TupleDesc	tuple_store_desc;	/* descriptor for tuples in tuple_store */1045	MemoryContext tuple_store_cxt;1046	ResourceOwner tuple_store_owner;1047	ReturnSetInfo *rsi;1048 1049	int			found_varno;1050 1051	/*1052	 * The datums representing the function's local variables.  Some of these1053	 * are local storage in this execstate, but some just point to the shared1054	 * copy belonging to the PLpgSQL_function, depending on whether or not we1055	 * need any per-execution state for the datum's dtype.1056	 */1057	int			ndatums;1058	PLpgSQL_datum **datums;1059	/* context containing variable values (same as func's SPI_proc context) */1060	MemoryContext datum_context;1061 1062	/*1063	 * paramLI is what we use to pass local variable values to the executor.1064	 * It does not have a ParamExternData array; we just dynamically1065	 * instantiate parameter data as needed.  By convention, PARAM_EXTERN1066	 * Params have paramid equal to the dno of the referenced local variable.1067	 */1068	ParamListInfo paramLI;1069 1070	/* EState and resowner to use for "simple" expression evaluation */1071	EState	   *simple_eval_estate;1072	ResourceOwner simple_eval_resowner;1073 1074	/* if running nonatomic procedure or DO block, resowner to use for CALL */1075	ResourceOwner procedure_resowner;1076 1077	/* lookup table to use for executing type casts */1078	HTAB	   *cast_hash;1079 1080	/* memory context for statement-lifespan temporary values */1081	MemoryContext stmt_mcontext;	/* current stmt context, or NULL if none */1082	MemoryContext stmt_mcontext_parent; /* parent of current context */1083 1084	/* temporary state for results from evaluation of query or expr */1085	SPITupleTable *eval_tuptable;1086	uint64		eval_processed;1087	ExprContext *eval_econtext; /* for executing simple expressions */1088 1089	/* status information for error context reporting */1090	PLpgSQL_stmt *err_stmt;		/* current stmt */1091	PLpgSQL_variable *err_var;	/* current variable, if in a DECLARE section */1092	const char *err_text;		/* additional state info */1093 1094	void	   *plugin_info;	/* reserved for use by optional plugin */1095} PLpgSQL_execstate;1096 1097/*1098 * A PLpgSQL_plugin structure represents an instrumentation plugin.1099 * To instrument PL/pgSQL, a plugin library must access the rendezvous1100 * variable "PLpgSQL_plugin" and set it to point to a PLpgSQL_plugin struct.1101 * Typically the struct could just be static data in the plugin library.1102 * We expect that a plugin would do this at library load time (_PG_init()).1103 *1104 * This structure is basically a collection of function pointers --- at1105 * various interesting points in pl_exec.c, we call these functions1106 * (if the pointers are non-NULL) to give the plugin a chance to watch1107 * what we are doing.1108 *1109 * func_setup is called when we start a function, before we've initialized1110 * the local variables defined by the function.1111 *1112 * func_beg is called when we start a function, after we've initialized1113 * the local variables.1114 *1115 * func_end is called at the end of a function.1116 *1117 * stmt_beg and stmt_end are called before and after (respectively) each1118 * statement.1119 *1120 * Also, immediately before any call to func_setup, PL/pgSQL fills in the1121 * remaining fields with pointers to some of its own functions, allowing the1122 * plugin to invoke those functions conveniently.  The exposed functions are:1123 *		plpgsql_exec_error_callback1124 *		exec_assign_expr1125 *		exec_assign_value1126 *		exec_eval_datum1127 *		exec_cast_value1128 * (plpgsql_exec_error_callback is not actually meant to be called by the1129 * plugin, but rather to allow it to identify PL/pgSQL error context stack1130 * frames.  The others are useful for debugger-like plugins to examine and1131 * set variables.)1132 */1133typedef struct PLpgSQL_plugin1134{1135	/* Function pointers set up by the plugin */1136	void		(*func_setup) (PLpgSQL_execstate *estate, PLpgSQL_function *func);1137	void		(*func_beg) (PLpgSQL_execstate *estate, PLpgSQL_function *func);1138	void		(*func_end) (PLpgSQL_execstate *estate, PLpgSQL_function *func);1139	void		(*stmt_beg) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);1140	void		(*stmt_end) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);1141 1142	/* Function pointers set by PL/pgSQL itself */1143	void		(*error_callback) (void *arg);1144	void		(*assign_expr) (PLpgSQL_execstate *estate,1145								PLpgSQL_datum *target,1146								PLpgSQL_expr *expr);1147	void		(*assign_value) (PLpgSQL_execstate *estate,1148								 PLpgSQL_datum *target,1149								 Datum value, bool isNull,1150								 Oid valtype, int32 valtypmod);1151	void		(*eval_datum) (PLpgSQL_execstate *estate, PLpgSQL_datum *datum,1152							   Oid *typeId, int32 *typetypmod,1153							   Datum *value, bool *isnull);1154	Datum		(*cast_value) (PLpgSQL_execstate *estate,1155							   Datum value, bool *isnull,1156							   Oid valtype, int32 valtypmod,1157							   Oid reqtype, int32 reqtypmod);1158} PLpgSQL_plugin;1159 1160/*1161 * Struct types used during parsing1162 */1163 1164typedef struct PLword1165{1166	char	   *ident;			/* palloc'd converted identifier */1167	bool		quoted;			/* Was it double-quoted? */1168} PLword;1169 1170typedef struct PLcword1171{1172	List	   *idents;			/* composite identifiers (list of String) */1173} PLcword;1174 1175typedef struct PLwdatum1176{1177	PLpgSQL_datum *datum;		/* referenced variable */1178	char	   *ident;			/* valid if simple name */1179	bool		quoted;1180	List	   *idents;			/* valid if composite name */1181} PLwdatum;1182 1183/**********************************************************************1184 * Global variable declarations1185 **********************************************************************/1186 1187typedef enum1188{1189	IDENTIFIER_LOOKUP_NORMAL,	/* normal processing of var names */1190	IDENTIFIER_LOOKUP_DECLARE,	/* In DECLARE --- don't look up names */1191	IDENTIFIER_LOOKUP_EXPR		/* In SQL expression --- special case */1192} IdentifierLookup;1193 1194extern IdentifierLookup plpgsql_IdentifierLookup;1195 1196extern int	plpgsql_variable_conflict;1197 1198extern bool plpgsql_print_strict_params;1199 1200extern bool plpgsql_check_asserts;

Showing the first 1,200 of 1340 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai