1 /*-------------------------------------------------------------------------
3 * plpgsql.h - Definitions for the PL/pgSQL
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.130 2010/02/26 02:01:35 momjian Exp $
13 *-------------------------------------------------------------------------
21 #include "access/xact.h"
23 #include "commands/trigger.h"
24 #include "executor/spi.h"
25 #include "lib/stringinfo.h"
26 #include "nodes/bitmapset.h"
27 #include "utils/tuplestore.h"
29 /**********************************************************************
31 **********************************************************************/
33 /* define our text domain for translations */
35 #define TEXTDOMAIN PG_TEXTDOMAIN("plpgsql")
38 #define _(x) dgettext(TEXTDOMAIN, x)
41 * Compiler's namespace item types
53 * Datum array node types
61 PLPGSQL_DTYPE_RECFIELD,
62 PLPGSQL_DTYPE_ARRAYELEM,
67 * Variants distinguished in PLpgSQL_type structs
72 PLPGSQL_TTYPE_SCALAR, /* scalar types and domains */
73 PLPGSQL_TTYPE_ROW, /* composite types */
74 PLPGSQL_TTYPE_REC, /* RECORD pseudotype */
75 PLPGSQL_TTYPE_PSEUDO /* other pseudotypes */
79 * Execution tree node types
82 enum PLpgSQL_stmt_types
95 PLPGSQL_STMT_RETURN_NEXT,
96 PLPGSQL_STMT_RETURN_QUERY,
99 PLPGSQL_STMT_DYNEXECUTE,
100 PLPGSQL_STMT_DYNFORS,
101 PLPGSQL_STMT_GETDIAG,
110 * Execution node return codes
123 * GET DIAGNOSTICS system attrs
128 PLPGSQL_GETDIAG_ROW_COUNT,
129 PLPGSQL_GETDIAG_RESULT_OID
133 * RAISE statement options
138 PLPGSQL_RAISEOPTION_ERRCODE,
139 PLPGSQL_RAISEOPTION_MESSAGE,
140 PLPGSQL_RAISEOPTION_DETAIL,
141 PLPGSQL_RAISEOPTION_HINT
145 * Behavioral modes for plpgsql variable resolution
150 PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */
151 PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */
152 PLPGSQL_RESOLVE_COLUMN /* prefer table column to plpgsql var */
153 } PLpgSQL_resolve_option;
156 /**********************************************************************
157 * Node and structure definitions
158 **********************************************************************/
162 { /* Postgres data type */
163 char *typname; /* (simple) name of the type */
164 Oid typoid; /* OID of the data type */
165 int ttype; /* PLPGSQL_TTYPE_ code */
166 int16 typlen; /* stuff copied from its pg_type entry */
170 FmgrInfo typinput; /* lookup info for typinput function */
171 int32 atttypmod; /* typmod (taken from someplace else) */
176 * PLpgSQL_datum is the common supertype for PLpgSQL_expr, PLpgSQL_var,
177 * PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, and PLpgSQL_arrayelem
180 { /* Generic datum array item */
186 * The variants PLpgSQL_var, PLpgSQL_row, and PLpgSQL_rec share these
190 { /* Scalar or composite variable */
197 typedef struct PLpgSQL_expr
198 { /* SQL Query to plan and execute */
203 Bitmapset *paramnos; /* all dnos referenced by this query */
205 /* function containing this expr (not set until we first parse query) */
206 struct PLpgSQL_function *func;
208 /* namespace chain visible to this expr */
209 struct PLpgSQL_nsitem *ns;
211 /* fields for "simple expression" fast-path execution: */
212 Expr *expr_simple_expr; /* NULL means not a simple expr */
213 int expr_simple_generation; /* plancache generation we checked */
214 Oid expr_simple_type; /* result type Oid, if simple */
217 * if expr is simple AND prepared in current transaction,
218 * expr_simple_state and expr_simple_in_use are valid. Test validity by
219 * seeing if expr_simple_lxid matches current LXID. (If not,
220 * expr_simple_state probably points at garbage!)
222 ExprState *expr_simple_state; /* eval tree for expr_simple_expr */
223 bool expr_simple_in_use; /* true if eval tree is active */
224 LocalTransactionId expr_simple_lxid;
229 { /* Scalar variable */
235 PLpgSQL_type *datatype;
238 PLpgSQL_expr *default_val;
239 PLpgSQL_expr *cursor_explicit_expr;
240 int cursor_explicit_argrow;
256 TupleDesc rowtupdesc;
259 * Note: TupleDesc is only set up for named rowtypes, else it is NULL.
261 * Note: if the underlying rowtype contains a dropped column, the
262 * corresponding fieldnames[] entry will be NULL, and there is no
263 * corresponding var (varnos[] will be -1).
272 { /* Record variable (non-fixed structure) */
286 { /* Field in record */
290 int recparentno; /* dno of parent record */
295 { /* Element of array variable */
298 PLpgSQL_expr *subscript;
299 int arrayparentno; /* dno of parent array variable */
303 typedef struct PLpgSQL_nsitem
304 { /* Item in the compilers namespace tree */
307 struct PLpgSQL_nsitem *prev;
308 char name[1]; /* actually, as long as needed */
313 { /* Generic execution node */
319 typedef struct PLpgSQL_condition
320 { /* One EXCEPTION condition name */
321 int sqlerrstate; /* SQLSTATE code */
322 char *condname; /* condition name (for debugging) */
323 struct PLpgSQL_condition *next;
330 List *exc_list; /* List of WHEN clauses */
331 } PLpgSQL_exception_block;
334 { /* One EXCEPTION ... WHEN clause */
336 PLpgSQL_condition *conditions;
337 List *action; /* List of statements */
342 { /* Block of statements */
346 List *body; /* List of statements */
349 PLpgSQL_exception_block *exceptions;
350 } PLpgSQL_stmt_block;
354 { /* Assign statement */
359 } PLpgSQL_stmt_assign;
362 { /* PERFORM statement */
366 } PLpgSQL_stmt_perform;
369 { /* Get Diagnostics item */
370 int kind; /* id for diagnostic value desired */
371 int target; /* where to assign it */
375 { /* Get Diagnostics statement */
378 List *diag_items; /* List of PLpgSQL_diag_item */
379 } PLpgSQL_stmt_getdiag;
387 List *true_body; /* List of statements */
388 List *false_body; /* List of statements */
392 typedef struct /* CASE statement */
396 PLpgSQL_expr *t_expr; /* test expression, or NULL if none */
397 int t_varno; /* var to store test expression value into */
398 List *case_when_list; /* List of PLpgSQL_case_when structs */
399 bool have_else; /* flag needed because list could be empty */
400 List *else_stmts; /* List of statements */
403 typedef struct /* one arm of CASE statement */
406 PLpgSQL_expr *expr; /* boolean expression for this case */
407 List *stmts; /* List of statements */
412 { /* Unconditional LOOP statement */
416 List *body; /* List of statements */
421 { /* WHILE cond LOOP statement */
426 List *body; /* List of statements */
427 } PLpgSQL_stmt_while;
431 { /* FOR statement with integer loopvar */
438 PLpgSQL_expr *step; /* NULL means default (ie, BY 1) */
440 List *body; /* List of statements */
445 * PLpgSQL_stmt_forq represents a FOR statement running over a SQL query.
446 * It is the common supertype of PLpgSQL_stmt_fors, PLpgSQL_stmt_forc
447 * and PLpgSQL_dynfors.
456 List *body; /* List of statements */
460 { /* FOR statement running over SELECT */
466 List *body; /* List of statements */
467 /* end of fields that must match PLpgSQL_stmt_forq */
472 { /* FOR statement running over cursor */
478 List *body; /* List of statements */
479 /* end of fields that must match PLpgSQL_stmt_forq */
481 PLpgSQL_expr *argquery; /* cursor arguments if any */
485 { /* FOR statement running over EXECUTE */
491 List *body; /* List of statements */
492 /* end of fields that must match PLpgSQL_stmt_forq */
494 List *params; /* USING expressions */
495 } PLpgSQL_stmt_dynfors;
499 { /* OPEN a curvar */
504 PLpgSQL_row *returntype;
505 PLpgSQL_expr *argquery;
507 PLpgSQL_expr *dynquery;
508 List *params; /* USING expressions */
513 { /* FETCH or MOVE statement */
516 PLpgSQL_rec *rec; /* target, as record or row */
518 int curvar; /* cursor variable to fetch from */
519 FetchDirection direction; /* fetch direction */
520 long how_many; /* count, if constant (expr is NULL) */
521 PLpgSQL_expr *expr; /* count, if expression */
522 bool is_move; /* is this a fetch or move? */
523 bool returns_multiple_rows; /* can return more than one row? */
524 } PLpgSQL_stmt_fetch;
532 } PLpgSQL_stmt_close;
536 { /* EXIT or CONTINUE statement */
539 bool is_exit; /* Is this an exit or a continue? */
540 char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
546 { /* RETURN statement */
551 } PLpgSQL_stmt_return;
554 { /* RETURN NEXT statement */
559 } PLpgSQL_stmt_return_next;
562 { /* RETURN QUERY statement */
565 PLpgSQL_expr *query; /* if static query */
566 PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
567 List *params; /* USING arguments for dynamic query */
568 } PLpgSQL_stmt_return_query;
571 { /* RAISE statement */
575 char *condname; /* condition name, SQLSTATE, or NULL */
576 char *message; /* old-style message format literal, or NULL */
577 List *params; /* list of expressions for old-style message */
578 List *options; /* list of PLpgSQL_raise_option */
579 } PLpgSQL_stmt_raise;
582 { /* RAISE statement option */
585 } PLpgSQL_raise_option;
589 { /* Generic SQL statement to execute */
592 PLpgSQL_expr *sqlstmt;
593 bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? */
594 /* note: mod_stmt is set when we plan the query */
595 bool into; /* INTO supplied? */
596 bool strict; /* INTO STRICT flag */
597 PLpgSQL_rec *rec; /* INTO target, if record */
598 PLpgSQL_row *row; /* INTO target, if row */
599 } PLpgSQL_stmt_execsql;
603 { /* Dynamic SQL string to execute */
606 PLpgSQL_expr *query; /* string expression */
607 bool into; /* INTO supplied? */
608 bool strict; /* INTO STRICT flag */
609 PLpgSQL_rec *rec; /* INTO target, if record */
610 PLpgSQL_row *row; /* INTO target, if row */
611 List *params; /* USING expressions */
612 } PLpgSQL_stmt_dynexecute;
615 typedef struct PLpgSQL_func_hashkey
616 { /* Hash lookup key for functions */
619 bool isTrigger; /* true if called as a trigger */
621 /* be careful that pad bytes in this struct get zeroed! */
624 * For a trigger function, the OID of the relation triggered on is part of
625 * the hashkey --- we want to compile the trigger separately for each
626 * relation it is used with, in case the rowtype is different. Zero if
627 * not called as a trigger.
632 * We include actual argument types in the hash key to support polymorphic
633 * PLpgSQL functions. Be careful that extra positions are zeroed!
635 Oid argtypes[FUNC_MAX_ARGS];
636 } PLpgSQL_func_hashkey;
639 typedef struct PLpgSQL_function
640 { /* Complete compiled function */
643 TransactionId fn_xmin;
644 ItemPointerData fn_tid;
646 PLpgSQL_func_hashkey *fn_hashkey; /* back-link to hashtable key */
647 MemoryContext fn_cxt;
652 FmgrInfo fn_retinput;
653 Oid fn_rettypioparam;
659 int fn_argvarnos[FUNC_MAX_ARGS];
669 int tg_relname_varno;
670 int tg_table_name_varno;
671 int tg_table_schema_varno;
675 PLpgSQL_resolve_option resolve_option;
678 PLpgSQL_datum **datums;
679 PLpgSQL_stmt_block *action;
681 /* these fields change when the function is used */
682 struct PLpgSQL_execstate *cur_estate;
683 unsigned long use_count;
687 typedef struct PLpgSQL_execstate
688 { /* Runtime execution data */
689 PLpgSQL_function *func; /* function being executed */
693 Oid rettype; /* type of current retval */
695 Oid fn_rettype; /* info about declared function rettype */
701 TupleDesc rettupdesc;
702 char *exitlabel; /* the "target" label of the current EXIT or
703 * CONTINUE stmt, if any */
705 Tuplestorestate *tuple_store; /* SRFs accumulate results here */
706 MemoryContext tuple_store_cxt;
707 ResourceOwner tuple_store_owner;
712 PLpgSQL_datum **datums;
714 /* temporary state for results from evaluation of query or expr */
715 SPITupleTable *eval_tuptable;
716 uint32 eval_processed;
718 ExprContext *eval_econtext; /* for executing simple expressions */
719 PLpgSQL_expr *cur_expr; /* current query/expr being evaluated */
721 /* status information for error context reporting */
722 PLpgSQL_stmt *err_stmt; /* current stmt */
723 const char *err_text; /* additional state info */
725 void *plugin_info; /* reserved for use by optional plugin */
730 * A PLpgSQL_plugin structure represents an instrumentation plugin.
731 * To instrument PL/pgSQL, a plugin library must access the rendezvous
732 * variable "PLpgSQL_plugin" and set it to point to a PLpgSQL_plugin struct.
733 * Typically the struct could just be static data in the plugin library.
734 * We expect that a plugin would do this at library load time (_PG_init()).
735 * It must also be careful to set the rendezvous variable back to NULL
736 * if it is unloaded (_PG_fini()).
738 * This structure is basically a collection of function pointers --- at
739 * various interesting points in pl_exec.c, we call these functions
740 * (if the pointers are non-NULL) to give the plugin a chance to watch
743 * func_setup is called when we start a function, before we've initialized
744 * the local variables defined by the function.
746 * func_beg is called when we start a function, after we've initialized
747 * the local variables.
749 * func_end is called at the end of a function.
751 * stmt_beg and stmt_end are called before and after (respectively) each
754 * Also, immediately before any call to func_setup, PL/pgSQL fills in the
755 * error_callback and assign_expr fields with pointers to its own
756 * plpgsql_exec_error_callback and exec_assign_expr functions. This is
757 * a somewhat ad-hoc expedient to simplify life for debugger plugins.
762 /* Function pointers set up by the plugin */
763 void (*func_setup) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
764 void (*func_beg) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
765 void (*func_end) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
766 void (*stmt_beg) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
767 void (*stmt_end) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
769 /* Function pointers set by PL/pgSQL itself */
770 void (*error_callback) (void *arg);
771 void (*assign_expr) (PLpgSQL_execstate *estate, PLpgSQL_datum *target,
776 /* Struct types used during parsing */
780 char *ident; /* palloc'd converted identifier */
781 bool quoted; /* Was it double-quoted? */
786 List *idents; /* composite identifiers (list of String) */
791 PLpgSQL_datum *datum; /* referenced variable */
792 char *ident; /* valid if simple name */
794 List *idents; /* valid if composite name */
797 /**********************************************************************
798 * Global variable declarations
799 **********************************************************************/
803 IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
804 IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
805 IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */
808 extern IdentifierLookup plpgsql_IdentifierLookup;
810 extern int plpgsql_variable_conflict;
812 extern bool plpgsql_check_syntax;
813 extern bool plpgsql_DumpExecTree;
815 extern PLpgSQL_stmt_block *plpgsql_parse_result;
817 extern int plpgsql_nDatums;
818 extern PLpgSQL_datum **plpgsql_Datums;
820 extern char *plpgsql_error_funcname;
822 extern PLpgSQL_function *plpgsql_curr_compile;
823 extern MemoryContext compile_tmp_cxt;
825 extern PLpgSQL_plugin **plugin_ptr;
827 /**********************************************************************
828 * Function declarations
829 **********************************************************************/
832 * Functions in pl_comp.c
835 extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo,
837 extern PLpgSQL_function *plpgsql_compile_inline(char *proc_source);
838 extern void plpgsql_parser_setup(struct ParseState *pstate,
840 extern bool plpgsql_parse_word(char *word1, const char *yytxt,
841 PLwdatum *wdatum, PLword *word);
842 extern bool plpgsql_parse_dblword(char *word1, char *word2,
843 PLwdatum *wdatum, PLcword *cword);
844 extern bool plpgsql_parse_tripword(char *word1, char *word2, char *word3,
845 PLwdatum *wdatum, PLcword *cword);
846 extern PLpgSQL_type *plpgsql_parse_wordtype(char *ident);
847 extern PLpgSQL_type *plpgsql_parse_cwordtype(List *idents);
848 extern PLpgSQL_type *plpgsql_parse_wordrowtype(char *ident);
849 extern PLpgSQL_type *plpgsql_parse_cwordrowtype(List *idents);
850 extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod);
851 extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno,
854 extern PLpgSQL_rec *plpgsql_build_record(const char *refname, int lineno,
856 extern int plpgsql_recognize_err_condition(const char *condname,
857 bool allow_sqlstate);
858 extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname);
859 extern void plpgsql_adddatum(PLpgSQL_datum *new);
860 extern int plpgsql_add_initdatums(int **varnos);
861 extern void plpgsql_HashTableInit(void);
864 * Functions in pl_handler.c
867 extern void _PG_init(void);
868 extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
869 extern Datum plpgsql_inline_handler(PG_FUNCTION_ARGS);
870 extern Datum plpgsql_validator(PG_FUNCTION_ARGS);
873 * Functions in pl_exec.c
876 extern Datum plpgsql_exec_function(PLpgSQL_function *func,
877 FunctionCallInfo fcinfo);
878 extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func,
879 TriggerData *trigdata);
880 extern void plpgsql_xact_cb(XactEvent event, void *arg);
881 extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
882 SubTransactionId parentSubid, void *arg);
883 extern Oid exec_get_datum_type(PLpgSQL_execstate *estate,
884 PLpgSQL_datum *datum);
885 extern Oid exec_get_rec_fieldtype(PLpgSQL_rec *rec, const char *fieldname,
889 * Functions for namespace handling in pl_funcs.c
892 extern void plpgsql_ns_init(void);
893 extern void plpgsql_ns_push(const char *label);
894 extern void plpgsql_ns_pop(void);
895 extern PLpgSQL_nsitem *plpgsql_ns_top(void);
896 extern void plpgsql_ns_additem(int itemtype, int itemno, const char *name);
897 extern PLpgSQL_nsitem *plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode,
898 const char *name1, const char *name2,
899 const char *name3, int *names_used);
900 extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur,
904 * Other functions in pl_funcs.c
907 extern const char *plpgsql_stmt_typename(PLpgSQL_stmt *stmt);
908 extern void plpgsql_dumptree(PLpgSQL_function *func);
911 * Scanner functions in pl_scanner.c
914 extern int plpgsql_base_yylex(void);
915 extern int plpgsql_yylex(void);
916 extern void plpgsql_push_back_token(int token);
917 extern void plpgsql_append_source_text(StringInfo buf,
918 int startlocation, int endlocation);
919 extern int plpgsql_scanner_errposition(int location);
920 extern void plpgsql_yyerror(const char *message);
921 extern int plpgsql_location_to_lineno(int location);
922 extern int plpgsql_latest_lineno(void);
923 extern void plpgsql_scanner_init(const char *str);
924 extern void plpgsql_scanner_finish(void);
930 extern int plpgsql_yyparse(void);
932 #endif /* PLPGSQL_H */