/* *Behavioralmodesforplpgsqlvariableresolution
*/ typedefenum 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;
/* *Statusofoptimizationofassignmenttoaread/writeexpandedobject
*/ typedefenum PLpgSQL_rwopt
{
PLPGSQL_RWOPT_UNKNOWN = 0, /* applicability not determined yet */
PLPGSQL_RWOPT_NOPE, /* cannot do any optimization */
PLPGSQL_RWOPT_TRANSFER, /* transfer the old value into expr state */
PLPGSQL_RWOPT_INPLACE, /* pass value as R/W to top-level function */
} PLpgSQL_rwopt;
/* *Postgresdatatype
*/ typedefstruct 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;
/* *SQLQuerytoplanandexecute
*/ typedefstruct PLpgSQL_expr
{ char *query; /* query string, verbatim from function body */
RawParseMode parseMode; /* raw_parser() mode to use */ struct PLpgSQL_function *func; /* function containing this expr */ struct PLpgSQL_nsitem *ns; /* namespace chain visible to this expr */
/* *Thesefieldsareusedtohelpoptimizeassignmentstoexpanded-datum *variables.Ifthisexpressionisthesourceofanassignmenttoa *simplevariable,target_paramholdsthatvariable'sdno(elseit's-1), *andtarget_is_localindicateswhetherthetargetisdeclaredinsidethe *closestexceptionblockcontainingtheassignment.
*/ int target_param; /* dno of assign target, or -1 if none */ bool target_is_local; /* is it within nearest exception block? */
/* *Fieldsabovearesetduringplpgsqlparsing.Remainingfieldsareleft *aszeroes/NULLsuntilwefirstparse/planthequery.
*/
SPIPlanPtr plan; /* plan, or NULL if not made yet */
Bitmapset *paramnos; /* all dnos referenced by this query */
/* fields for "simple expression" fast-path execution: */
Expr *expr_simple_expr; /* NULL means not a simple expr */
Oid expr_simple_type; /* result type Oid, if simple */
int32 expr_simple_typmod; /* result typmod, if simple */ bool expr_simple_mutable; /* true if simple expr is mutable */
/* *expr_rwopttrackswhetherwehavedeterminedthatassignmenttoa *read/writeexpandedobject(storedinthetarget_paramdatum)canbe *optimizedbypassingittotheexprasaread/writeexpanded-object *pointer.Ifso,expr_rw_paramidentifiesthespecificParamthat *shouldemitaread/writepointer;anyotherswillemitread-only *pointers.
*/
PLpgSQL_rwopt expr_rwopt; /* can we apply R/W optimization? */
Param *expr_rw_param; /* read/write Param within expr, if any */
/* *ifexprissimpleANDpreparedincurrenttransaction, *expr_simple_stateandexpr_simple_in_usearevalid.Testvalidityby *seeingifexpr_simple_lxidmatchescurrentLXID.(Ifnot, *expr_simple_stateprobablypointsatgarbage!)
*/
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;
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;
/* *Fieldinrecord
*/ typedefstruct 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;
/* *OneEXCEPTIONconditionname
*/ typedefstruct PLpgSQL_condition
{ int sqlerrstate; /* SQLSTATE code, or PLPGSQL_OTHERS */ char *condname; /* condition name (for debugging) */ struct PLpgSQL_condition *next;
} PLpgSQL_condition;
/* This value mustn't match any possible output of MAKE_SQLSTATE() */ #define PLPGSQL_OTHERS (-1)
/* *EXCEPTIONblock
*/ typedefstruct PLpgSQL_exception_block
{ int sqlstate_varno; int sqlerrm_varno;
List *exc_list; /* List of WHEN clauses */
} PLpgSQL_exception_block;
/* *OneEXCEPTION...WHENclause
*/ typedefstruct PLpgSQL_exception
{ int lineno;
PLpgSQL_condition *conditions;
List *action; /* List of statements */
} PLpgSQL_exception;
/* *Blockofstatements
*/ typedefstruct PLpgSQL_stmt_block
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *Assignstatement
*/ typedefstruct PLpgSQL_stmt_assign
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; int varno;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
/* *GETDIAGNOSTICSitem
*/ typedefstruct PLpgSQL_diag_item
{
PLpgSQL_getdiag_kind kind; /* id for diagnostic value desired */ int target; /* where to assign it */
} PLpgSQL_diag_item;
/* *GETDIAGNOSTICSstatement
*/ typedefstruct PLpgSQL_stmt_getdiag
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; bool is_stacked; /* STACKED or CURRENT diagnostics area? */
List *diag_items; /* List of PLpgSQL_diag_item */
} PLpgSQL_stmt_getdiag;
/* *IFstatement
*/ typedefstruct PLpgSQL_stmt_if
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *oneELSIFarmofIFstatement
*/ typedefstruct PLpgSQL_if_elsif
{ int lineno;
PLpgSQL_expr *cond; /* boolean expression for this case */
List *stmts; /* List of statements */
} PLpgSQL_if_elsif;
/* *CASEstatement
*/ typedefstruct PLpgSQL_stmt_case
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *onearmofCASEstatement
*/ typedefstruct PLpgSQL_case_when
{ int lineno;
PLpgSQL_expr *expr; /* boolean expression for this case */
List *stmts; /* List of statements */
} PLpgSQL_case_when;
/* *UnconditionalLOOPstatement
*/ typedefstruct PLpgSQL_stmt_loop
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; char *label;
List *body; /* List of statements */
} PLpgSQL_stmt_loop;
/* *WHILEcondLOOPstatement
*/ typedefstruct PLpgSQL_stmt_while
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; char *label;
PLpgSQL_expr *cond;
List *body; /* List of statements */
} PLpgSQL_stmt_while;
/* *FORstatementwithintegerloopvar
*/ typedefstruct PLpgSQL_stmt_fori
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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_forqrepresentsaFORstatementrunningoveraSQLquery. *ItisthecommonsupertypeofPLpgSQL_stmt_fors,PLpgSQL_stmt_forc *andPLpgSQL_stmt_dynfors.
*/ typedefstruct PLpgSQL_stmt_forq
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
} PLpgSQL_stmt_forq;
/* *FORstatementrunningoverSELECT
*/ typedefstruct PLpgSQL_stmt_fors
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *FORstatementrunningovercursor
*/ typedefstruct PLpgSQL_stmt_forc
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *FORstatementrunningoverEXECUTE
*/ typedefstruct PLpgSQL_stmt_dynfors
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *FOREACHiteminarrayloop
*/ typedefstruct PLpgSQL_stmt_foreach_a
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *OPENacurvar
*/ typedefstruct PLpgSQL_stmt_open
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; int curvar; int cursor_options;
PLpgSQL_expr *argquery;
PLpgSQL_expr *query;
PLpgSQL_expr *dynquery;
List *params; /* USING expressions */
} PLpgSQL_stmt_open;
/* *FETCHorMOVEstatement
*/ typedefstruct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *CLOSEcurvar
*/ typedefstruct PLpgSQL_stmt_close
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; int curvar;
} PLpgSQL_stmt_close;
/* *EXITorCONTINUEstatement
*/ typedefstruct PLpgSQL_stmt_exit
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid; bool is_exit; /* Is this an exit or a continue? */ char *label; /* NULL if it's an unlabeled EXIT/CONTINUE */
PLpgSQL_expr *cond;
} PLpgSQL_stmt_exit;
/* *RETURNstatement
*/ typedefstruct PLpgSQL_stmt_return
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid;
PLpgSQL_expr *expr; int retvarno;
} PLpgSQL_stmt_return;
/* *RETURNNEXTstatement
*/ typedefstruct PLpgSQL_stmt_return_next
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint stmtid;
PLpgSQL_expr *expr; int retvarno;
} PLpgSQL_stmt_return_next;
/* *RETURNQUERYstatement
*/ typedefstruct PLpgSQL_stmt_return_query
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
/* *RAISEstatement
*/ typedefstruct PLpgSQL_stmt_raise
{
PLpgSQL_stmt_type cmd_type; int lineno; unsignedint 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;
char *fn_signature;
Oid fn_oid;
PLpgSQL_trigtype fn_is_trigger;
Oid fn_input_collation;
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;
/* 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;
/* data derived while parsing body */ unsignedint nstatements; /* counter for assigning stmtids */ bool requires_procedure_resowner; /* contains CALL or DO? */ bool has_exception_block; /* contains BEGIN...EXCEPTION? */
/* this field changes when the function is used */ struct PLpgSQL_execstate *cur_estate;
} PLpgSQL_function;
/* *Runtimeexecutiondata
*/ typedefstruct 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;
/* EState and resowner to use for "simple" expression evaluation */
EState *simple_eval_estate;
ResourceOwner simple_eval_resowner;
/* if running nonatomic procedure or DO block, resowner to use for CALL */
ResourceOwner procedure_resowner;
/* lookup table to use for executing type casts */
HTAB *cast_hash;
/* 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 */
PLpgSQL_variable *err_var; /* current variable, if in a DECLARE section */ constchar *err_text; /* additional state info */
void *plugin_info; /* reserved for use by optional plugin */
} PLpgSQL_execstate;
typedefenum
{
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;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.