|
- /*-------------------------------------------------------------------------
- *
- * plpgsql.h - Definitions for the PL/pgSQL
- * procedural language
- *
- * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * src/pl/plpgsql/src/plpgsql.h
- *
- *-------------------------------------------------------------------------
- */
-
- #ifndef PLPGSQL_H
- #define PLPGSQL_H
-
- #include "access/xact.h"
- #include "commands/event_trigger.h"
- #include "commands/trigger.h"
- #include "executor/spi.h"
- #include "utils/expandedrecord.h"
- #include "utils/typcache.h"
-
-
- /**********************************************************************
- * Definitions
- **********************************************************************/
-
- /* define our text domain for translations */
- #undef TEXTDOMAIN
- #define TEXTDOMAIN PG_TEXTDOMAIN("plpgsql")
-
- #undef _
- #define _(x) dgettext(TEXTDOMAIN, x)
-
- /*
- * Compiler's namespace item types
- */
- typedef enum PLpgSQL_nsitem_type
- {
- PLPGSQL_NSTYPE_LABEL, /* block label */
- PLPGSQL_NSTYPE_VAR, /* scalar variable */
- PLPGSQL_NSTYPE_REC /* composite variable */
- } PLpgSQL_nsitem_type;
-
- /*
- * A PLPGSQL_NSTYPE_LABEL stack entry must be one of these types
- */
- typedef enum PLpgSQL_label_type
- {
- PLPGSQL_LABEL_BLOCK, /* DECLARE/BEGIN block */
- PLPGSQL_LABEL_LOOP, /* looping construct */
- PLPGSQL_LABEL_OTHER /* anything else */
- } PLpgSQL_label_type;
-
- /*
- * Datum array node types
- */
- typedef enum PLpgSQL_datum_type
- {
- PLPGSQL_DTYPE_VAR,
- PLPGSQL_DTYPE_ROW,
- PLPGSQL_DTYPE_REC,
- PLPGSQL_DTYPE_RECFIELD,
- PLPGSQL_DTYPE_ARRAYELEM,
- PLPGSQL_DTYPE_PROMISE
- } PLpgSQL_datum_type;
-
- /*
- * DTYPE_PROMISE datums have these possible ways of computing the promise
- */
- typedef enum PLpgSQL_promise_type
- {
- PLPGSQL_PROMISE_NONE = 0, /* not a promise, or promise satisfied */
- PLPGSQL_PROMISE_TG_NAME,
- PLPGSQL_PROMISE_TG_WHEN,
- PLPGSQL_PROMISE_TG_LEVEL,
- PLPGSQL_PROMISE_TG_OP,
- PLPGSQL_PROMISE_TG_RELID,
- PLPGSQL_PROMISE_TG_TABLE_NAME,
- PLPGSQL_PROMISE_TG_TABLE_SCHEMA,
- PLPGSQL_PROMISE_TG_NARGS,
- PLPGSQL_PROMISE_TG_ARGV,
- PLPGSQL_PROMISE_TG_EVENT,
- PLPGSQL_PROMISE_TG_TAG
- } PLpgSQL_promise_type;
-
- /*
- * Variants distinguished in PLpgSQL_type structs
- */
- typedef enum PLpgSQL_type_type
- {
- PLPGSQL_TTYPE_SCALAR, /* scalar types and domains */
- PLPGSQL_TTYPE_REC, /* composite types, including RECORD */
- PLPGSQL_TTYPE_PSEUDO /* pseudotypes */
- } PLpgSQL_type_type;
-
- /*
- * Execution tree node types
- */
- typedef enum PLpgSQL_stmt_type
- {
- PLPGSQL_STMT_BLOCK,
- PLPGSQL_STMT_ASSIGN,
- PLPGSQL_STMT_IF,
- PLPGSQL_STMT_CASE,
- PLPGSQL_STMT_LOOP,
- PLPGSQL_STMT_WHILE,
- PLPGSQL_STMT_FORI,
- PLPGSQL_STMT_FORS,
- PLPGSQL_STMT_FORC,
- PLPGSQL_STMT_FOREACH_A,
- PLPGSQL_STMT_EXIT,
- PLPGSQL_STMT_RETURN,
- PLPGSQL_STMT_RETURN_NEXT,
- PLPGSQL_STMT_RETURN_QUERY,
- PLPGSQL_STMT_RAISE,
- PLPGSQL_STMT_ASSERT,
- PLPGSQL_STMT_EXECSQL,
- PLPGSQL_STMT_DYNEXECUTE,
- PLPGSQL_STMT_DYNFORS,
- PLPGSQL_STMT_GETDIAG,
- PLPGSQL_STMT_OPEN,
- PLPGSQL_STMT_FETCH,
- PLPGSQL_STMT_CLOSE,
- PLPGSQL_STMT_PERFORM,
- PLPGSQL_STMT_CALL,
- PLPGSQL_STMT_COMMIT,
- PLPGSQL_STMT_ROLLBACK,
- PLPGSQL_STMT_SET
- } PLpgSQL_stmt_type;
-
- /*
- * Execution node return codes
- */
- enum
- {
- PLPGSQL_RC_OK,
- PLPGSQL_RC_EXIT,
- PLPGSQL_RC_RETURN,
- PLPGSQL_RC_CONTINUE
- };
-
- /*
- * GET DIAGNOSTICS information items
- */
- typedef enum PLpgSQL_getdiag_kind
- {
- PLPGSQL_GETDIAG_ROW_COUNT,
- PLPGSQL_GETDIAG_CONTEXT,
- PLPGSQL_GETDIAG_ERROR_CONTEXT,
- PLPGSQL_GETDIAG_ERROR_DETAIL,
- PLPGSQL_GETDIAG_ERROR_HINT,
- PLPGSQL_GETDIAG_RETURNED_SQLSTATE,
- PLPGSQL_GETDIAG_COLUMN_NAME,
- PLPGSQL_GETDIAG_CONSTRAINT_NAME,
- PLPGSQL_GETDIAG_DATATYPE_NAME,
- PLPGSQL_GETDIAG_MESSAGE_TEXT,
- PLPGSQL_GETDIAG_TABLE_NAME,
- PLPGSQL_GETDIAG_SCHEMA_NAME
- } PLpgSQL_getdiag_kind;
-
- /*
- * RAISE statement options
- */
- typedef enum PLpgSQL_raise_option_type
- {
- PLPGSQL_RAISEOPTION_ERRCODE,
- PLPGSQL_RAISEOPTION_MESSAGE,
- PLPGSQL_RAISEOPTION_DETAIL,
- PLPGSQL_RAISEOPTION_HINT,
- PLPGSQL_RAISEOPTION_COLUMN,
- PLPGSQL_RAISEOPTION_CONSTRAINT,
- PLPGSQL_RAISEOPTION_DATATYPE,
- PLPGSQL_RAISEOPTION_TABLE,
- PLPGSQL_RAISEOPTION_SCHEMA
- } PLpgSQL_raise_option_type;
-
- /*
- * Behavioral modes for plpgsql variable resolution
- */
- typedef enum PLpgSQL_resolve_option
- {
- PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */
- PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */
- PLPGSQL_RESOLVE_COLUMN /* prefer table column to plpgsql var */
- } PLpgSQL_resolve_option;
-
-
- /**********************************************************************
- * Node and structure definitions
- **********************************************************************/
-
- /*
- * Postgres data type
- */
- typedef struct PLpgSQL_type
- {
- char *typname; /* (simple) name of the type */
- Oid typoid; /* OID of the data type */
- PLpgSQL_type_type ttype; /* PLPGSQL_TTYPE_ code */
- int16 typlen; /* stuff copied from its pg_type entry */
- bool typbyval;
- char typtype;
- Oid collation; /* from pg_type, but can be overridden */
- bool typisarray; /* is "true" array, or domain over one */
- int32 atttypmod; /* typmod (taken from someplace else) */
- /* Remaining fields are used only for named composite types (not RECORD) */
- TypeName *origtypname; /* type name as written by user */
- TypeCacheEntry *tcache; /* typcache entry for composite type */
- uint64 tupdesc_id; /* last-seen tupdesc identifier */
- } PLpgSQL_type;
-
- /*
- * SQL Query to plan and execute
- */
- typedef struct PLpgSQL_expr
- {
- char *query;
- SPIPlanPtr plan;
- Bitmapset *paramnos; /* all dnos referenced by this query */
- int rwparam; /* dno of read/write param, or -1 if none */
-
- /* function containing this expr (not set until we first parse query) */
- struct PLpgSQL_function *func;
-
- /* namespace chain visible to this expr */
- struct PLpgSQL_nsitem *ns;
-
- /* fields for "simple expression" fast-path execution: */
- Expr *expr_simple_expr; /* NULL means not a simple expr */
- int expr_simple_generation; /* plancache generation we checked */
- Oid expr_simple_type; /* result type Oid, if simple */
- int32 expr_simple_typmod; /* result typmod, if simple */
-
- /*
- * if expr is simple AND prepared in current transaction,
- * expr_simple_state and expr_simple_in_use are valid. Test validity by
- * seeing if expr_simple_lxid matches current LXID. (If not,
- * expr_simple_state probably points at garbage!)
- */
- ExprState *expr_simple_state; /* eval tree for expr_simple_expr */
- bool expr_simple_in_use; /* true if eval tree is active */
- LocalTransactionId expr_simple_lxid;
- } PLpgSQL_expr;
-
- /*
- * Generic datum array item
- *
- * PLpgSQL_datum is the common supertype for PLpgSQL_var, PLpgSQL_row,
- * PLpgSQL_rec, PLpgSQL_recfield, and PLpgSQL_arrayelem.
- */
- typedef struct PLpgSQL_datum
- {
- PLpgSQL_datum_type dtype;
- int dno;
- } PLpgSQL_datum;
-
- /*
- * Scalar or composite variable
- *
- * The variants PLpgSQL_var, PLpgSQL_row, and PLpgSQL_rec share these
- * fields.
- */
- typedef struct PLpgSQL_variable
- {
- PLpgSQL_datum_type dtype;
- int dno;
- char *refname;
- int lineno;
- bool isconst;
- bool notnull;
- PLpgSQL_expr *default_val;
- } PLpgSQL_variable;
-
- /*
- * Scalar variable
- *
- * DTYPE_VAR and DTYPE_PROMISE datums both use this struct type.
- * A PROMISE datum works exactly like a VAR datum for most purposes,
- * but if it is read without having previously been assigned to, then
- * a special "promised" value is computed and assigned to the datum
- * before the read is performed. This technique avoids the overhead of
- * computing the variable's value in cases where we expect that many
- * functions will never read it.
- */
- typedef struct PLpgSQL_var
- {
- PLpgSQL_datum_type dtype;
- int dno;
- char *refname;
- int lineno;
- bool isconst;
- bool notnull;
- PLpgSQL_expr *default_val;
- /* end of PLpgSQL_variable fields */
-
- PLpgSQL_type *datatype;
-
- /*
- * Variables declared as CURSOR FOR <query> are mostly like ordinary
- * scalar variables of type refcursor, but they have these additional
- * properties:
- */
- PLpgSQL_expr *cursor_explicit_expr;
- int cursor_explicit_argrow;
- int cursor_options;
-
- /* Fields below here can change at runtime */
-
- Datum value;
- bool isnull;
- bool freeval;
-
- /*
- * The promise field records which "promised" value to assign if the
- * promise must be honored. If it's a normal variable, or the promise has
- * been fulfilled, this is PLPGSQL_PROMISE_NONE.
- */
- PLpgSQL_promise_type promise;
- } PLpgSQL_var;
-
- /*
- * Row variable - this represents one or more variables that are listed in an
- * INTO clause, FOR-loop targetlist, cursor argument list, etc. We also use
- * a row to represent a function's OUT parameters when there's more than one.
- *
- * Note that there's no way to name the row as such from PL/pgSQL code,
- * so many functions don't need to support these.
- *
- * That also means that there's no real name for the row variable, so we
- * conventionally set refname to "(unnamed row)". We could leave it NULL,
- * but it's too convenient to be able to assume that refname is valid in
- * all variants of PLpgSQL_variable.
- *
- * isconst, notnull, and default_val are unsupported (and hence
- * always zero/null) for a row. The member variables of a row should have
- * been checked to be writable at compile time, so isconst is correctly set
- * to false. notnull and default_val aren't applicable.
- */
- typedef struct PLpgSQL_row
- {
- PLpgSQL_datum_type dtype;
- int dno;
- char *refname;
- int lineno;
- bool isconst;
- bool notnull;
- PLpgSQL_expr *default_val;
- /* end of PLpgSQL_variable fields */
-
- /*
- * rowtupdesc is only set up if we might need to convert the row into a
- * composite datum, which currently only happens for OUT parameters.
- * Otherwise it is NULL.
- */
- TupleDesc rowtupdesc;
-
- int nfields;
- char **fieldnames;
- int *varnos;
- } PLpgSQL_row;
-
- /*
- * Record variable (any composite type, including RECORD)
- */
- typedef struct PLpgSQL_rec
- {
- PLpgSQL_datum_type dtype;
- int dno;
- char *refname;
- int lineno;
- bool isconst;
- bool notnull;
- PLpgSQL_expr *default_val;
- /* end of PLpgSQL_variable fields */
-
- /*
- * Note: for non-RECORD cases, we may from time to time re-look-up the
- * composite type, using datatype->origtypname. That can result in
- * changing rectypeid.
- */
-
- PLpgSQL_type *datatype; /* can be NULL, if rectypeid is RECORDOID */
- Oid rectypeid; /* declared type of variable */
- /* RECFIELDs for this record are chained together for easy access */
- int firstfield; /* dno of first RECFIELD, or -1 if none */
-
- /* Fields below here can change at runtime */
-
- /* We always store record variables as "expanded" records */
- ExpandedRecordHeader *erh;
- } PLpgSQL_rec;
-
- /*
- * Field in record
- */
- typedef struct PLpgSQL_recfield
- {
- PLpgSQL_datum_type dtype;
- int dno;
- /* end of PLpgSQL_datum fields */
-
- char *fieldname; /* name of field */
- int recparentno; /* dno of parent record */
- int nextfield; /* dno of next child, or -1 if none */
- uint64 rectupledescid; /* record's tupledesc ID as of last lookup */
- ExpandedRecordFieldInfo finfo; /* field's attnum and type info */
- /* if rectupledescid == INVALID_TUPLEDESC_IDENTIFIER, finfo isn't valid */
- } PLpgSQL_recfield;
-
- /*
- * Element of array variable
- */
- typedef struct PLpgSQL_arrayelem
- {
- PLpgSQL_datum_type dtype;
- int dno;
- /* end of PLpgSQL_datum fields */
-
- PLpgSQL_expr *subscript;
- int arrayparentno; /* dno of parent array variable */
-
- /* Remaining fields are cached info about the array variable's type */
- Oid parenttypoid; /* type of array variable; 0 if not yet set */
- int32 parenttypmod; /* typmod of array variable */
- Oid arraytypoid; /* OID of actual array type */
- int32 arraytypmod; /* typmod of array (and its elements too) */
- int16 arraytyplen; /* typlen of array type */
- Oid elemtypoid; /* OID of array element type */
- int16 elemtyplen; /* typlen of element type */
- bool elemtypbyval; /* element type is pass-by-value? */
- char elemtypalign; /* typalign of element type */
- } PLpgSQL_arrayelem;
-
- /*
- * Item in the compilers namespace tree
- */
- typedef struct PLpgSQL_nsitem
- {
- PLpgSQL_nsitem_type itemtype;
-
- /*
- * For labels, itemno is a value of enum PLpgSQL_label_type. For other
- * itemtypes, itemno is the associated PLpgSQL_datum's dno.
- */
- int itemno;
- struct PLpgSQL_nsitem *prev;
- char name[FLEXIBLE_ARRAY_MEMBER]; /* nul-terminated string */
- } PLpgSQL_nsitem;
-
- /*
- * Generic execution node
- */
- typedef struct PLpgSQL_stmt
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
-
- /*
- * Unique statement ID in this function (starting at 1; 0 is invalid/not
- * set). This can be used by a profiler as the index for an array of
- * per-statement metrics.
- */
- unsigned int stmtid;
- } PLpgSQL_stmt;
-
- /*
- * One EXCEPTION condition name
- */
- typedef struct PLpgSQL_condition
- {
- int sqlerrstate; /* SQLSTATE code */
- char *condname; /* condition name (for debugging) */
- struct PLpgSQL_condition *next;
- } PLpgSQL_condition;
-
- /*
- * EXCEPTION block
- */
- typedef struct PLpgSQL_exception_block
- {
- int sqlstate_varno;
- int sqlerrm_varno;
- List *exc_list; /* List of WHEN clauses */
- } PLpgSQL_exception_block;
-
- /*
- * One EXCEPTION ... WHEN clause
- */
- typedef struct PLpgSQL_exception
- {
- int lineno;
- PLpgSQL_condition *conditions;
- List *action; /* List of statements */
- } PLpgSQL_exception;
-
- /*
- * Block of statements
- */
- typedef struct PLpgSQL_stmt_block
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- List *body; /* List of statements */
- int n_initvars; /* Length of initvarnos[] */
- int *initvarnos; /* dnos of variables declared in this block */
- PLpgSQL_exception_block *exceptions;
- } PLpgSQL_stmt_block;
-
- /*
- * Assign statement
- */
- typedef struct PLpgSQL_stmt_assign
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- int varno;
- PLpgSQL_expr *expr;
- } PLpgSQL_stmt_assign;
-
- /*
- * PERFORM statement
- */
- typedef struct PLpgSQL_stmt_perform
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *expr;
- } PLpgSQL_stmt_perform;
-
- /*
- * CALL statement
- */
- typedef struct PLpgSQL_stmt_call
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *expr;
- bool is_call;
- PLpgSQL_variable *target;
- } PLpgSQL_stmt_call;
-
- /*
- * COMMIT statement
- */
- typedef struct PLpgSQL_stmt_commit
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- bool chain;
- } PLpgSQL_stmt_commit;
-
- /*
- * ROLLBACK statement
- */
- typedef struct PLpgSQL_stmt_rollback
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- bool chain;
- } PLpgSQL_stmt_rollback;
-
- /*
- * SET statement
- */
- typedef struct PLpgSQL_stmt_set
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *expr;
- } PLpgSQL_stmt_set;
-
- /*
- * GET DIAGNOSTICS item
- */
- typedef struct PLpgSQL_diag_item
- {
- PLpgSQL_getdiag_kind kind; /* id for diagnostic value desired */
- int target; /* where to assign it */
- } PLpgSQL_diag_item;
-
- /*
- * GET DIAGNOSTICS statement
- */
- typedef struct PLpgSQL_stmt_getdiag
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- bool is_stacked; /* STACKED or CURRENT diagnostics area? */
- List *diag_items; /* List of PLpgSQL_diag_item */
- } PLpgSQL_stmt_getdiag;
-
- /*
- * IF statement
- */
- typedef struct PLpgSQL_stmt_if
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *cond; /* boolean expression for THEN */
- List *then_body; /* List of statements */
- List *elsif_list; /* List of PLpgSQL_if_elsif structs */
- List *else_body; /* List of statements */
- } PLpgSQL_stmt_if;
-
- /*
- * one ELSIF arm of IF statement
- */
- typedef struct PLpgSQL_if_elsif
- {
- int lineno;
- PLpgSQL_expr *cond; /* boolean expression for this case */
- List *stmts; /* List of statements */
- } PLpgSQL_if_elsif;
-
- /*
- * CASE statement
- */
- typedef struct PLpgSQL_stmt_case
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *t_expr; /* test expression, or NULL if none */
- int t_varno; /* var to store test expression value into */
- List *case_when_list; /* List of PLpgSQL_case_when structs */
- bool have_else; /* flag needed because list could be empty */
- List *else_stmts; /* List of statements */
- } PLpgSQL_stmt_case;
-
- /*
- * one arm of CASE statement
- */
- typedef struct PLpgSQL_case_when
- {
- int lineno;
- PLpgSQL_expr *expr; /* boolean expression for this case */
- List *stmts; /* List of statements */
- } PLpgSQL_case_when;
-
- /*
- * Unconditional LOOP statement
- */
- typedef struct PLpgSQL_stmt_loop
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- List *body; /* List of statements */
- } PLpgSQL_stmt_loop;
-
- /*
- * WHILE cond LOOP statement
- */
- typedef struct PLpgSQL_stmt_while
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_expr *cond;
- List *body; /* List of statements */
- } PLpgSQL_stmt_while;
-
- /*
- * FOR statement with integer loopvar
- */
- typedef struct PLpgSQL_stmt_fori
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_var *var;
- PLpgSQL_expr *lower;
- PLpgSQL_expr *upper;
- PLpgSQL_expr *step; /* NULL means default (ie, BY 1) */
- int reverse;
- List *body; /* List of statements */
- } PLpgSQL_stmt_fori;
-
- /*
- * PLpgSQL_stmt_forq represents a FOR statement running over a SQL query.
- * It is the common supertype of PLpgSQL_stmt_fors, PLpgSQL_stmt_forc
- * and PLpgSQL_dynfors.
- */
- typedef struct PLpgSQL_stmt_forq
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_variable *var; /* Loop variable (record or row) */
- List *body; /* List of statements */
- } PLpgSQL_stmt_forq;
-
- /*
- * FOR statement running over SELECT
- */
- typedef struct PLpgSQL_stmt_fors
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_variable *var; /* Loop variable (record or row) */
- List *body; /* List of statements */
- /* end of fields that must match PLpgSQL_stmt_forq */
- PLpgSQL_expr *query;
- } PLpgSQL_stmt_fors;
-
- /*
- * FOR statement running over cursor
- */
- typedef struct PLpgSQL_stmt_forc
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_variable *var; /* Loop variable (record or row) */
- List *body; /* List of statements */
- /* end of fields that must match PLpgSQL_stmt_forq */
- int curvar;
- PLpgSQL_expr *argquery; /* cursor arguments if any */
- } PLpgSQL_stmt_forc;
-
- /*
- * FOR statement running over EXECUTE
- */
- typedef struct PLpgSQL_stmt_dynfors
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- PLpgSQL_variable *var; /* Loop variable (record or row) */
- List *body; /* List of statements */
- /* end of fields that must match PLpgSQL_stmt_forq */
- PLpgSQL_expr *query;
- List *params; /* USING expressions */
- } PLpgSQL_stmt_dynfors;
-
- /*
- * FOREACH item in array loop
- */
- typedef struct PLpgSQL_stmt_foreach_a
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- char *label;
- int varno; /* loop target variable */
- int slice; /* slice dimension, or 0 */
- PLpgSQL_expr *expr; /* array expression */
- List *body; /* List of statements */
- } PLpgSQL_stmt_foreach_a;
-
- /*
- * OPEN a curvar
- */
- typedef struct PLpgSQL_stmt_open
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- int curvar;
- int cursor_options;
- PLpgSQL_expr *argquery;
- PLpgSQL_expr *query;
- PLpgSQL_expr *dynquery;
- List *params; /* USING expressions */
- } PLpgSQL_stmt_open;
-
- /*
- * FETCH or MOVE statement
- */
- typedef struct PLpgSQL_stmt_fetch
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_variable *target; /* target (record or row) */
- int curvar; /* cursor variable to fetch from */
- FetchDirection direction; /* fetch direction */
- long how_many; /* count, if constant (expr is NULL) */
- PLpgSQL_expr *expr; /* count, if expression */
- bool is_move; /* is this a fetch or move? */
- bool returns_multiple_rows; /* can return more than one row? */
- } PLpgSQL_stmt_fetch;
-
- /*
- * CLOSE curvar
- */
- typedef struct PLpgSQL_stmt_close
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- int curvar;
- } PLpgSQL_stmt_close;
-
- /*
- * EXIT or CONTINUE statement
- */
- typedef struct PLpgSQL_stmt_exit
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- bool is_exit; /* Is this an exit or a continue? */
- char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
- PLpgSQL_expr *cond;
- } PLpgSQL_stmt_exit;
-
- /*
- * RETURN statement
- */
- typedef struct PLpgSQL_stmt_return
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *expr;
- int retvarno;
- } PLpgSQL_stmt_return;
-
- /*
- * RETURN NEXT statement
- */
- typedef struct PLpgSQL_stmt_return_next
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *expr;
- int retvarno;
- } PLpgSQL_stmt_return_next;
-
- /*
- * RETURN QUERY statement
- */
- typedef struct PLpgSQL_stmt_return_query
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *query; /* if static query */
- PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
- List *params; /* USING arguments for dynamic query */
- } PLpgSQL_stmt_return_query;
-
- /*
- * RAISE statement
- */
- typedef struct PLpgSQL_stmt_raise
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- int elog_level;
- char *condname; /* condition name, SQLSTATE, or NULL */
- char *message; /* old-style message format literal, or NULL */
- List *params; /* list of expressions for old-style message */
- List *options; /* list of PLpgSQL_raise_option */
- } PLpgSQL_stmt_raise;
-
- /*
- * RAISE statement option
- */
- typedef struct PLpgSQL_raise_option
- {
- PLpgSQL_raise_option_type opt_type;
- PLpgSQL_expr *expr;
- } PLpgSQL_raise_option;
-
- /*
- * ASSERT statement
- */
- typedef struct PLpgSQL_stmt_assert
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *cond;
- PLpgSQL_expr *message;
- } PLpgSQL_stmt_assert;
-
- /*
- * Generic SQL statement to execute
- */
- typedef struct PLpgSQL_stmt_execsql
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *sqlstmt;
- bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
- * mod_stmt is set when we plan the query */
- bool into; /* INTO supplied? */
- bool strict; /* INTO STRICT flag */
- PLpgSQL_variable *target; /* INTO target (record or row) */
- } PLpgSQL_stmt_execsql;
-
- /*
- * Dynamic SQL string to execute
- */
- typedef struct PLpgSQL_stmt_dynexecute
- {
- PLpgSQL_stmt_type cmd_type;
- int lineno;
- unsigned int stmtid;
- PLpgSQL_expr *query; /* string expression */
- bool into; /* INTO supplied? */
- bool strict; /* INTO STRICT flag */
- PLpgSQL_variable *target; /* INTO target (record or row) */
- List *params; /* USING expressions */
- } PLpgSQL_stmt_dynexecute;
-
- /*
- * Hash lookup key for functions
- */
- typedef struct PLpgSQL_func_hashkey
- {
- Oid funcOid;
-
- bool isTrigger; /* true if called as a DML trigger */
- bool isEventTrigger; /* true if called as an event trigger */
-
- /* be careful that pad bytes in this struct get zeroed! */
-
- /*
- * For a trigger function, the OID of the trigger is part of the hash key
- * --- we want to compile the trigger function separately for each trigger
- * it is used with, in case the rowtype or transition table names are
- * different. Zero if not called as a DML trigger.
- */
- Oid trigOid;
-
- /*
- * We must include the input collation as part of the hash key too,
- * because we have to generate different plans (with different Param
- * collations) for different collation settings.
- */
- Oid inputCollation;
-
- /*
- * We include actual argument types in the hash key to support polymorphic
- * PLpgSQL functions. Be careful that extra positions are zeroed!
- */
- Oid argtypes[FUNC_MAX_ARGS];
- } PLpgSQL_func_hashkey;
-
- /*
- * Trigger type
- */
- typedef enum PLpgSQL_trigtype
- {
- PLPGSQL_DML_TRIGGER,
- PLPGSQL_EVENT_TRIGGER,
- PLPGSQL_NOT_TRIGGER
- } PLpgSQL_trigtype;
-
- /*
- * Complete compiled function
- */
- typedef struct PLpgSQL_function
- {
- char *fn_signature;
- Oid fn_oid;
- TransactionId fn_xmin;
- ItemPointerData fn_tid;
- PLpgSQL_trigtype fn_is_trigger;
- Oid fn_input_collation;
- PLpgSQL_func_hashkey *fn_hashkey; /* back-link to hashtable key */
- MemoryContext fn_cxt;
-
- Oid fn_rettype;
- int fn_rettyplen;
- bool fn_retbyval;
- bool fn_retistuple;
- bool fn_retisdomain;
- bool fn_retset;
- bool fn_readonly;
- char fn_prokind;
-
- int fn_nargs;
- int fn_argvarnos[FUNC_MAX_ARGS];
- int out_param_varno;
- int found_varno;
- int new_varno;
- int old_varno;
-
- PLpgSQL_resolve_option resolve_option;
-
- bool print_strict_params;
-
- /* extra checks */
- int extra_warnings;
- int extra_errors;
-
- /* count of statements inside function */
- unsigned int nstatements;
-
- /* the datums representing the function's local variables */
- int ndatums;
- PLpgSQL_datum **datums;
- Size copiable_size; /* space for locally instantiated datums */
-
- /* function body parsetree */
- PLpgSQL_stmt_block *action;
-
- /* these fields change when the function is used */
- struct PLpgSQL_execstate *cur_estate;
- unsigned long use_count;
- } PLpgSQL_function;
-
- /*
- * Runtime execution data
- */
- typedef struct PLpgSQL_execstate
- {
- PLpgSQL_function *func; /* function being executed */
-
- TriggerData *trigdata; /* if regular trigger, data about firing */
- EventTriggerData *evtrigdata; /* if event trigger, data about firing */
-
- Datum retval;
- bool retisnull;
- Oid rettype; /* type of current retval */
-
- Oid fn_rettype; /* info about declared function rettype */
- bool retistuple;
- bool retisset;
-
- bool readonly_func;
- bool atomic;
-
- char *exitlabel; /* the "target" label of the current EXIT or
- * CONTINUE stmt, if any */
- ErrorData *cur_error; /* current exception handler's error */
-
- Tuplestorestate *tuple_store; /* SRFs accumulate results here */
- TupleDesc tuple_store_desc; /* descriptor for tuples in tuple_store */
- MemoryContext tuple_store_cxt;
- ResourceOwner tuple_store_owner;
- ReturnSetInfo *rsi;
-
- int found_varno;
-
- /*
- * The datums representing the function's local variables. Some of these
- * are local storage in this execstate, but some just point to the shared
- * copy belonging to the PLpgSQL_function, depending on whether or not we
- * need any per-execution state for the datum's dtype.
- */
- int ndatums;
- PLpgSQL_datum **datums;
- /* context containing variable values (same as func's SPI_proc context) */
- MemoryContext datum_context;
-
- /*
- * paramLI is what we use to pass local variable values to the executor.
- * It does not have a ParamExternData array; we just dynamically
- * instantiate parameter data as needed. By convention, PARAM_EXTERN
- * Params have paramid equal to the dno of the referenced local variable.
- */
- ParamListInfo paramLI;
-
- /* EState to use for "simple" expression evaluation */
- EState *simple_eval_estate;
-
- /* lookup table to use for executing type casts */
- HTAB *cast_hash;
- MemoryContext cast_hash_context;
-
- /* memory context for statement-lifespan temporary values */
- MemoryContext stmt_mcontext; /* current stmt context, or NULL if none */
- MemoryContext stmt_mcontext_parent; /* parent of current context */
-
- /* temporary state for results from evaluation of query or expr */
- SPITupleTable *eval_tuptable;
- uint64 eval_processed;
- ExprContext *eval_econtext; /* for executing simple expressions */
-
- /* status information for error context reporting */
- PLpgSQL_stmt *err_stmt; /* current stmt */
- const char *err_text; /* additional state info */
-
- void *plugin_info; /* reserved for use by optional plugin */
- } PLpgSQL_execstate;
-
- /*
- * A PLpgSQL_plugin structure represents an instrumentation plugin.
- * To instrument PL/pgSQL, a plugin library must access the rendezvous
- * variable "PLpgSQL_plugin" and set it to point to a PLpgSQL_plugin struct.
- * Typically the struct could just be static data in the plugin library.
- * We expect that a plugin would do this at library load time (_PG_init()).
- * It must also be careful to set the rendezvous variable back to NULL
- * if it is unloaded (_PG_fini()).
- *
- * This structure is basically a collection of function pointers --- at
- * various interesting points in pl_exec.c, we call these functions
- * (if the pointers are non-NULL) to give the plugin a chance to watch
- * what we are doing.
- *
- * func_setup is called when we start a function, before we've initialized
- * the local variables defined by the function.
- *
- * func_beg is called when we start a function, after we've initialized
- * the local variables.
- *
- * func_end is called at the end of a function.
- *
- * stmt_beg and stmt_end are called before and after (respectively) each
- * statement.
- *
- * Also, immediately before any call to func_setup, PL/pgSQL fills in the
- * error_callback and assign_expr fields with pointers to its own
- * plpgsql_exec_error_callback and exec_assign_expr functions. This is
- * a somewhat ad-hoc expedient to simplify life for debugger plugins.
- */
- typedef struct PLpgSQL_plugin
- {
- /* Function pointers set up by the plugin */
- void (*func_setup) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
- void (*func_beg) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
- void (*func_end) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
- void (*stmt_beg) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
- void (*stmt_end) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
-
- /* Function pointers set by PL/pgSQL itself */
- void (*error_callback) (void *arg);
- void (*assign_expr) (PLpgSQL_execstate *estate, PLpgSQL_datum *target,
- PLpgSQL_expr *expr);
- } PLpgSQL_plugin;
-
- /*
- * Struct types used during parsing
- */
-
- typedef struct PLword
- {
- char *ident; /* palloc'd converted identifier */
- bool quoted; /* Was it double-quoted? */
- } PLword;
-
- typedef struct PLcword
- {
- List *idents; /* composite identifiers (list of String) */
- } PLcword;
-
- typedef struct PLwdatum
- {
- PLpgSQL_datum *datum; /* referenced variable */
- char *ident; /* valid if simple name */
- bool quoted;
- List *idents; /* valid if composite name */
- } PLwdatum;
-
- /**********************************************************************
- * Global variable declarations
- **********************************************************************/
-
- typedef enum
- {
- IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
- IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
- IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */
- } IdentifierLookup;
-
- extern IdentifierLookup plpgsql_IdentifierLookup;
-
- extern int plpgsql_variable_conflict;
-
- extern bool plpgsql_print_strict_params;
-
- extern bool plpgsql_check_asserts;
-
- /* extra compile-time and run-time checks */
- #define PLPGSQL_XCHECK_NONE 0
- #define PLPGSQL_XCHECK_SHADOWVAR (1 << 1)
- #define PLPGSQL_XCHECK_TOOMANYROWS (1 << 2)
- #define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT (1 << 3)
- #define PLPGSQL_XCHECK_ALL ((int) ~0)
-
- extern int plpgsql_extra_warnings;
- extern int plpgsql_extra_errors;
-
- extern bool plpgsql_check_syntax;
- extern bool plpgsql_DumpExecTree;
-
- extern PLpgSQL_stmt_block *plpgsql_parse_result;
-
- extern int plpgsql_nDatums;
- extern PLpgSQL_datum **plpgsql_Datums;
-
- extern char *plpgsql_error_funcname;
-
- extern PLpgSQL_function *plpgsql_curr_compile;
- extern MemoryContext plpgsql_compile_tmp_cxt;
-
- extern PLpgSQL_plugin **plpgsql_plugin_ptr;
-
- /**********************************************************************
- * Function declarations
- **********************************************************************/
-
- /*
- * Functions in pl_comp.c
- */
- extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo,
- bool forValidator);
- extern PLpgSQL_function *plpgsql_compile_inline(char *proc_source);
- extern void plpgsql_parser_setup(struct ParseState *pstate,
- PLpgSQL_expr *expr);
- extern bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup,
- PLwdatum *wdatum, PLword *word);
- extern bool plpgsql_parse_dblword(char *word1, char *word2,
- PLwdatum *wdatum, PLcword *cword);
- extern bool plpgsql_parse_tripword(char *word1, char *word2, char *word3,
- PLwdatum *wdatum, PLcword *cword);
- extern PLpgSQL_type *plpgsql_parse_wordtype(char *ident);
- extern PLpgSQL_type *plpgsql_parse_cwordtype(List *idents);
- extern PLpgSQL_type *plpgsql_parse_wordrowtype(char *ident);
- extern PLpgSQL_type *plpgsql_parse_cwordrowtype(List *idents);
- extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod,
- Oid collation,
- TypeName *origtypname);
- extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno,
- PLpgSQL_type *dtype,
- bool add2namespace);
- extern PLpgSQL_rec *plpgsql_build_record(const char *refname, int lineno,
- PLpgSQL_type *dtype, Oid rectypeid,
- bool add2namespace);
- extern PLpgSQL_recfield *plpgsql_build_recfield(PLpgSQL_rec *rec,
- const char *fldname);
- extern int plpgsql_recognize_err_condition(const char *condname,
- bool allow_sqlstate);
- extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname);
- extern void plpgsql_adddatum(PLpgSQL_datum *newdatum);
- extern int plpgsql_add_initdatums(int **varnos);
- extern void plpgsql_HashTableInit(void);
-
- /*
- * Functions in pl_handler.c
- */
- extern void _PG_init(void);
-
- /*
- * Functions in pl_exec.c
- */
- extern Datum plpgsql_exec_function(PLpgSQL_function *func,
- FunctionCallInfo fcinfo,
- EState *simple_eval_estate,
- bool atomic);
- extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func,
- TriggerData *trigdata);
- extern void plpgsql_exec_event_trigger(PLpgSQL_function *func,
- EventTriggerData *trigdata);
- extern void plpgsql_xact_cb(XactEvent event, void *arg);
- extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
- SubTransactionId parentSubid, void *arg);
- extern Oid plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate,
- PLpgSQL_datum *datum);
- extern void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate,
- PLpgSQL_datum *datum,
- Oid *typeId, int32 *typMod,
- Oid *collation);
-
- /*
- * Functions for namespace handling in pl_funcs.c
- */
- extern void plpgsql_ns_init(void);
- extern void plpgsql_ns_push(const char *label,
- PLpgSQL_label_type label_type);
- extern void plpgsql_ns_pop(void);
- extern PLpgSQL_nsitem *plpgsql_ns_top(void);
- extern void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name);
- extern PLpgSQL_nsitem *plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode,
- const char *name1, const char *name2,
- const char *name3, int *names_used);
- extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur,
- const char *name);
- extern PLpgSQL_nsitem *plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur);
-
- /*
- * Other functions in pl_funcs.c
- */
- extern const char *plpgsql_stmt_typename(PLpgSQL_stmt *stmt);
- extern const char *plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind);
- extern void plpgsql_free_function_memory(PLpgSQL_function *func);
- extern void plpgsql_dumptree(PLpgSQL_function *func);
-
- /*
- * Scanner functions in pl_scanner.c
- */
- extern int plpgsql_base_yylex(void);
- extern int plpgsql_yylex(void);
- extern void plpgsql_push_back_token(int token);
- extern bool plpgsql_token_is_unreserved_keyword(int token);
- extern void plpgsql_append_source_text(StringInfo buf,
- int startlocation, int endlocation);
- extern int plpgsql_peek(void);
- extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,
- int *tok2_loc);
- extern int plpgsql_scanner_errposition(int location);
- extern void plpgsql_yyerror(const char *message) pg_attribute_noreturn();
- extern int plpgsql_location_to_lineno(int location);
- extern int plpgsql_latest_lineno(void);
- extern void plpgsql_scanner_init(const char *str);
- extern void plpgsql_scanner_finish(void);
-
- /*
- * Externs in gram.y
- */
- extern int plpgsql_yyparse(void);
-
- #endif /* PLPGSQL_H */
|