]> granicus.if.org Git - postgresql/blobdiff - src/pl/plpgsql/src/plpgsql.h
Add support for invoking parser callback hooks via SPI and in cached plans.
[postgresql] / src / pl / plpgsql / src / plpgsql.h
index a50d5721f437dc93b2e9e9cd5eb4fe61dd5b3cc7..3d0f155a884142d477b8a4fbe55ece44478ad84f 100644 (file)
@@ -3,12 +3,12 @@
  * plpgsql.h           - Definitions for the PL/pgSQL
  *                       procedural language
  *
- * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.97 2008/04/06 23:43:29 tgl Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.118 2009/11/04 22:26:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
 
+#include "access/xact.h"
 #include "fmgr.h"
-#include "miscadmin.h"
 #include "commands/trigger.h"
 #include "executor/spi.h"
+#include "nodes/bitmapset.h"
 #include "utils/tuplestore.h"
 
 /**********************************************************************
  * Definitions
  **********************************************************************/
 
+/* define our text domain for translations */
+#undef TEXTDOMAIN
+#define TEXTDOMAIN PG_TEXTDOMAIN("plpgsql")
+
+#undef _
+#define _(x) dgettext(TEXTDOMAIN, x)
+
 /* ----------
  * Compiler's namestack item types
  * ----------
@@ -51,8 +59,7 @@ enum
        PLPGSQL_DTYPE_REC,
        PLPGSQL_DTYPE_RECFIELD,
        PLPGSQL_DTYPE_ARRAYELEM,
-       PLPGSQL_DTYPE_EXPR,
-       PLPGSQL_DTYPE_TRIGARG
+       PLPGSQL_DTYPE_EXPR
 };
 
 /* ----------
@@ -71,11 +78,12 @@ enum
  * Execution tree node types
  * ----------
  */
-enum
+enum PLpgSQL_stmt_types
 {
        PLPGSQL_STMT_BLOCK,
        PLPGSQL_STMT_ASSIGN,
        PLPGSQL_STMT_IF,
+       PLPGSQL_STMT_CASE,
        PLPGSQL_STMT_LOOP,
        PLPGSQL_STMT_WHILE,
        PLPGSQL_STMT_FORI,
@@ -106,7 +114,8 @@ enum
        PLPGSQL_RC_OK,
        PLPGSQL_RC_EXIT,
        PLPGSQL_RC_RETURN,
-       PLPGSQL_RC_CONTINUE
+       PLPGSQL_RC_CONTINUE,
+       PLPGSQL_RC_RERAISE
 };
 
 /* ----------
@@ -119,20 +128,24 @@ enum
        PLPGSQL_GETDIAG_RESULT_OID
 };
 
+/* --------
+ * RAISE statement options
+ * --------
+ */
+enum
+{
+       PLPGSQL_RAISEOPTION_ERRCODE,
+       PLPGSQL_RAISEOPTION_MESSAGE,
+       PLPGSQL_RAISEOPTION_DETAIL,
+       PLPGSQL_RAISEOPTION_HINT
+};
+
 
 /**********************************************************************
  * Node and structure definitions
  **********************************************************************/
 
 
-typedef struct
-{                                                              /* Dynamic string control structure */
-       int                     alloc;
-       int                     used;                   /* Including NUL terminator */
-       char       *value;
-} PLpgSQL_dstring;
-
-
 typedef struct
 {                                                              /* Postgres data type */
        char       *typname;            /* (simple) name of the type */
@@ -149,8 +162,7 @@ typedef struct
 
 /*
  * PLpgSQL_datum is the common supertype for PLpgSQL_expr, PLpgSQL_var,
- * PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, PLpgSQL_arrayelem, and
- * PLpgSQL_trigarg
+ * PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, and PLpgSQL_arrayelem
  */
 typedef struct
 {                                                              /* Generic datum array item             */
@@ -173,33 +185,33 @@ typedef struct
 typedef struct PLpgSQL_expr
 {                                                              /* SQL Query to plan and execute        */
        int                     dtype;
-       int                     exprno;
+       int                     dno;
        char       *query;
        SPIPlanPtr      plan;
-       Oid                *plan_argtypes;
+       Bitmapset  *paramnos;           /* all dnos referenced by this query */
+
+       /* function containing this expr (not set until we first parse query) */
+       struct PLpgSQL_function *func;
+
        /* 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 */
 
        /*
-        * if expr is simple AND prepared in current eval_estate,
-        * expr_simple_state is valid.  Test validity by seeing if expr_simple_id
-        * matches eval_estate_simple_id.
+        * if expr is simple AND prepared in current transaction,
+        * expr_simple_state is valid. Test validity by seeing if expr_simple_lxid
+        * matches current LXID.
         */
        ExprState  *expr_simple_state;
-       long int        expr_simple_id;
-
-       /* params to pass to expr */
-       int                     nparams;
-       int                     params[1];              /* VARIABLE SIZE ARRAY ... must be last */
+       LocalTransactionId expr_simple_lxid;
 } PLpgSQL_expr;
 
 
 typedef struct
 {                                                              /* Scalar variable */
        int                     dtype;
-       int                     varno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -220,7 +232,7 @@ typedef struct
 typedef struct
 {                                                              /* Row variable */
        int                     dtype;
-       int                     rowno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -242,7 +254,7 @@ typedef struct
 typedef struct
 {                                                              /* Record variable (non-fixed structure) */
        int                     dtype;
-       int                     recno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -256,7 +268,7 @@ typedef struct
 typedef struct
 {                                                              /* Field in record */
        int                     dtype;
-       int                     rfno;
+       int                     dno;
        char       *fieldname;
        int                     recparentno;    /* dno of parent record */
 } PLpgSQL_recfield;
@@ -271,14 +283,6 @@ typedef struct
 } PLpgSQL_arrayelem;
 
 
-typedef struct
-{                                                              /* Positional argument to trigger       */
-       int                     dtype;
-       int                     dno;
-       PLpgSQL_expr *argnum;
-} PLpgSQL_trigarg;
-
-
 typedef struct
 {                                                              /* Item in the compilers namestack      */
        int                     itemtype;
@@ -377,6 +381,25 @@ typedef struct
 } PLpgSQL_stmt_if;
 
 
+typedef struct                                 /* CASE statement */
+{
+       int                     cmd_type;
+       int                     lineno;
+       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;
+
+typedef struct                                 /* one arm of CASE statement */
+{
+       int                     lineno;
+       PLpgSQL_expr *expr;                     /* boolean expression for this case */
+       List       *stmts;                      /* List of statements */
+} PLpgSQL_case_when;
+
+
 typedef struct
 {                                                              /* Unconditional LOOP statement         */
        int                     cmd_type;
@@ -485,9 +508,10 @@ typedef struct
        PLpgSQL_row *row;
        int                     curvar;                 /* cursor variable to fetch from */
        FetchDirection direction;       /* fetch direction */
-       int                     how_many;               /* count, if constant (expr is NULL) */
+       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;
 
 
@@ -529,7 +553,9 @@ typedef struct
 {                                                              /* RETURN QUERY statement */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_expr *query;
+       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;
 
 typedef struct
@@ -537,10 +563,18 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        int                     elog_level;
-       char       *message;
-       List       *params;                     /* list of expressions */
+       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;
 
+typedef struct
+{                                                              /* RAISE statement option */
+       int                     opt_type;
+       PLpgSQL_expr *expr;
+} PLpgSQL_raise_option;
+
 
 typedef struct
 {                                                              /* Generic SQL statement to execute */
@@ -573,6 +607,10 @@ typedef struct PLpgSQL_func_hashkey
 {                                                              /* Hash lookup key for functions */
        Oid                     funcOid;
 
+       bool            isTrigger;              /* true if called as a trigger */
+
+       /* be careful that pad bytes in this struct get zeroed! */
+
        /*
         * For a trigger function, the OID of the relation triggered on is part of
         * the hashkey --- we want to compile the trigger separately for each
@@ -595,7 +633,7 @@ typedef struct PLpgSQL_function
        Oid                     fn_oid;
        TransactionId fn_xmin;
        ItemPointerData fn_tid;
-       int                     fn_functype;
+       bool            fn_is_trigger;
        PLpgSQL_func_hashkey *fn_hashkey;       /* back-link to hashtable key */
        MemoryContext fn_cxt;
 
@@ -623,17 +661,22 @@ typedef struct PLpgSQL_function
        int                     tg_table_name_varno;
        int                     tg_table_schema_varno;
        int                     tg_nargs_varno;
+       int                     tg_argv_varno;
 
        int                     ndatums;
        PLpgSQL_datum **datums;
        PLpgSQL_stmt_block *action;
 
+       /* these fields change when the function is used */
+       struct PLpgSQL_execstate *cur_estate;
        unsigned long use_count;
 } PLpgSQL_function;
 
 
-typedef struct
+typedef struct PLpgSQL_execstate
 {                                                              /* Runtime execution data       */
+       PLpgSQL_function *func;         /* function being executed */
+
        Datum           retval;
        bool            retisnull;
        Oid                     rettype;                /* type of current retval */
@@ -652,9 +695,6 @@ typedef struct
        MemoryContext tuple_store_cxt;
        ReturnSetInfo *rsi;
 
-       int                     trig_nargs;
-       Datum      *trig_argv;
-
        int                     found_varno;
        int                     ndatums;
        PLpgSQL_datum **datums;
@@ -664,13 +704,12 @@ typedef struct
        uint32          eval_processed;
        Oid                     eval_lastoid;
        ExprContext *eval_econtext; /* for executing simple expressions */
-       EState     *eval_estate;        /* EState containing eval_econtext */
-       long int        eval_estate_simple_id;  /* ID for eval_estate */
+       PLpgSQL_expr *cur_expr;         /* current query/expr being evaluated */
 
        /* status information for error context reporting */
-       PLpgSQL_function *err_func; /* current func */
        PLpgSQL_stmt *err_stmt;         /* current stmt */
        const char *err_text;           /* additional state info */
+
        void       *plugin_info;        /* reserved for use by optional plugin */
 } PLpgSQL_execstate;
 
@@ -755,6 +794,7 @@ extern PLpgSQL_plugin **plugin_ptr;
  */
 extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo,
                                bool forValidator);
+extern PLpgSQL_function *plpgsql_compile_inline(char *proc_source);
 extern int     plpgsql_parse_word(const char *word);
 extern int     plpgsql_parse_dblword(const char *word);
 extern int     plpgsql_parse_tripword(const char *word);
@@ -769,7 +809,9 @@ 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,
-                                                                                bool add2namespace);
+                                        bool add2namespace);
+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 *new);
 extern int     plpgsql_add_initdatums(int **varnos);
@@ -782,6 +824,7 @@ extern void plpgsql_compile_error_callback(void *arg);
  */
 extern void _PG_init(void);
 extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
+extern Datum plpgsql_inline_handler(PG_FUNCTION_ARGS);
 extern Datum plpgsql_validator(PG_FUNCTION_ARGS);
 
 /* ----------
@@ -796,16 +839,6 @@ extern void plpgsql_xact_cb(XactEvent event, void *arg);
 extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
                                   SubTransactionId parentSubid, void *arg);
 
-/* ----------
- * Functions for the dynamic string handling in pl_funcs.c
- * ----------
- */
-extern void plpgsql_dstring_init(PLpgSQL_dstring *ds);
-extern void plpgsql_dstring_free(PLpgSQL_dstring *ds);
-extern void plpgsql_dstring_append(PLpgSQL_dstring *ds, const char *str);
-extern void plpgsql_dstring_append_char(PLpgSQL_dstring *ds, char c);
-extern char *plpgsql_dstring_get(PLpgSQL_dstring *ds);
-
 /* ----------
  * Functions for namestack handling in pl_funcs.c
  * ----------
@@ -816,7 +849,7 @@ extern void plpgsql_ns_push(const char *label);
 extern void plpgsql_ns_pop(void);
 extern void plpgsql_ns_additem(int itemtype, int itemno, const char *name);
 extern PLpgSQL_nsitem *plpgsql_ns_lookup(const char *name1, const char *name2,
-                                                                                const char *name3, int *names_used);
+                                 const char *name3, int *names_used);
 extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(const char *name);
 extern void plpgsql_ns_rename(char *oldname, char *newname);
 
@@ -839,8 +872,7 @@ extern int  plpgsql_yylex(void);
 extern void plpgsql_push_back_token(int token);
 extern void plpgsql_yyerror(const char *message);
 extern int     plpgsql_scanner_lineno(void);
-extern void plpgsql_scanner_init(const char *str, int functype);
+extern void plpgsql_scanner_init(const char *str);
 extern void plpgsql_scanner_finish(void);
-extern char *plpgsql_get_string_value(void);
 
 #endif   /* PLPGSQL_H */