codekingpro/portable-devtools
115k
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;