]> 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 6dec6d5c86cb33124c977f9cf9831f9abcce6b79..3d0f155a884142d477b8a4fbe55ece44478ad84f 100644 (file)
@@ -1,56 +1,43 @@
-/**********************************************************************
+/*-------------------------------------------------------------------------
+ *
  * plpgsql.h           - Definitions for the PL/pgSQL
  *                       procedural language
  *
- * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.55 2004/09/14 23:46:46 neilc Exp $
- *
- *       This software is copyrighted by Jan Wieck - Hamburg.
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
  *
- *       The author hereby grants permission  to  use,  copy,  modify,
- *       distribute,  and      license this software and its documentation
- *       for any purpose, provided that existing copyright notices are
- *       retained      in      all  copies  and  that  this notice is included
- *       verbatim in any distributions. No written agreement, license,
- *       or  royalty  fee      is required for any of the authorized uses.
- *       Modifications to this software may be  copyrighted  by  their
- *       author  and  need  not  follow  the licensing terms described
- *       here, provided that the new terms are  clearly  indicated  on
- *       the first page of each file where they apply.
  *
- *       IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
- *       PARTY  FOR  DIRECT,   INDIRECT,       SPECIAL,   INCIDENTAL,   OR
- *       CONSEQUENTIAL   DAMAGES  ARISING      OUT  OF  THE  USE  OF  THIS
- *       SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
- *       IF  THE  AUTHOR  HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- *       DAMAGE.
- *
- *       THE  AUTHOR  AND      DISTRIBUTORS  SPECIFICALLY       DISCLAIM       ANY
- *       WARRANTIES,  INCLUDING,  BUT  NOT  LIMITED  TO,  THE  IMPLIED
- *       WARRANTIES  OF  MERCHANTABILITY,      FITNESS  FOR  A  PARTICULAR
- *       PURPOSE,      AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON
- *       AN "AS IS" BASIS, AND THE AUTHOR      AND  DISTRIBUTORS  HAVE  NO
- *       OBLIGATION   TO       PROVIDE   MAINTENANCE,   SUPPORT,  UPDATES,
- *       ENHANCEMENTS, OR MODIFICATIONS.
+ * IDENTIFICATION
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.118 2009/11/04 22:26:07 tgl Exp $
  *
- **********************************************************************/
+ *-------------------------------------------------------------------------
+ */
+
 #ifndef PLPGSQL_H
 #define PLPGSQL_H
 
 #include "postgres.h"
 
+#include "access/xact.h"
 #include "fmgr.h"
-#include "miscadmin.h"
-#include "executor/spi.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)
+
 /* ----------
- * Compilers namestack item types
+ * Compiler's namestack item types
  * ----------
  */
 enum
@@ -72,8 +59,7 @@ enum
        PLPGSQL_DTYPE_REC,
        PLPGSQL_DTYPE_RECFIELD,
        PLPGSQL_DTYPE_ARRAYELEM,
-       PLPGSQL_DTYPE_EXPR,
-       PLPGSQL_DTYPE_TRIGARG
+       PLPGSQL_DTYPE_EXPR
 };
 
 /* ----------
@@ -92,19 +78,21 @@ 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,
        PLPGSQL_STMT_FORS,
-       PLPGSQL_STMT_SELECT,
+       PLPGSQL_STMT_FORC,
        PLPGSQL_STMT_EXIT,
        PLPGSQL_STMT_RETURN,
        PLPGSQL_STMT_RETURN_NEXT,
+       PLPGSQL_STMT_RETURN_QUERY,
        PLPGSQL_STMT_RAISE,
        PLPGSQL_STMT_EXECSQL,
        PLPGSQL_STMT_DYNEXECUTE,
@@ -125,7 +113,9 @@ enum
 {
        PLPGSQL_RC_OK,
        PLPGSQL_RC_EXIT,
-       PLPGSQL_RC_RETURN
+       PLPGSQL_RC_RETURN,
+       PLPGSQL_RC_CONTINUE,
+       PLPGSQL_RC_RERAISE
 };
 
 /* ----------
@@ -138,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;
-       char       *value;
-} PLpgSQL_dstring;
-
-
 typedef struct
 {                                                              /* Postgres data type */
        char       *typname;            /* (simple) name of the type */
@@ -168,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             */
@@ -192,26 +185,33 @@ typedef struct
 typedef struct PLpgSQL_expr
 {                                                              /* SQL Query to plan and execute        */
        int                     dtype;
-       int                     exprno;
+       int                     dno;
        char       *query;
-       void       *plan;
-       Oid                *plan_argtypes;
+       SPIPlanPtr      plan;
+       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 */
-       Oid                     expr_simple_type;
-       /* if expr is simple AND in use in current xact, these fields are set: */
+       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 transaction,
+        * expr_simple_state is valid. Test validity by seeing if expr_simple_lxid
+        * matches current LXID.
+        */
        ExprState  *expr_simple_state;
-       struct PLpgSQL_expr *expr_simple_next;
-       /* 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;
 
@@ -221,6 +221,7 @@ typedef struct
        PLpgSQL_expr *default_val;
        PLpgSQL_expr *cursor_explicit_expr;
        int                     cursor_explicit_argrow;
+       int                     cursor_options;
 
        Datum           value;
        bool            isnull;
@@ -231,7 +232,7 @@ typedef struct
 typedef struct
 {                                                              /* Row variable */
        int                     dtype;
-       int                     rowno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -253,7 +254,7 @@ typedef struct
 typedef struct
 {                                                              /* Record variable (non-fixed structure) */
        int                     dtype;
-       int                     recno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -267,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;
@@ -282,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;
@@ -298,6 +291,7 @@ typedef struct
 } PLpgSQL_nsitem;
 
 
+/* XXX: consider adapting this to use List */
 typedef struct PLpgSQL_ns
 {                                                              /* Compiler namestack level             */
        int                     items_alloc;
@@ -314,14 +308,6 @@ typedef struct
 } PLpgSQL_stmt;
 
 
-typedef struct
-{                                                              /* List of execution nodes              */
-       int                     stmts_alloc;    /* XXX this oughta just be a List ... */
-       int                     stmts_used;
-       PLpgSQL_stmt **stmts;
-} PLpgSQL_stmts;
-
-
 typedef struct PLpgSQL_condition
 {                                                              /* One EXCEPTION condition name */
        int                     sqlerrstate;    /* SQLSTATE code */
@@ -329,32 +315,30 @@ typedef struct PLpgSQL_condition
        struct PLpgSQL_condition *next;
 } PLpgSQL_condition;
 
+typedef struct
+{
+       int                     sqlstate_varno;
+       int                     sqlerrm_varno;
+       List       *exc_list;           /* List of WHEN clauses */
+} PLpgSQL_exception_block;
+
 typedef struct
 {                                                              /* One EXCEPTION ... WHEN clause */
        int                     lineno;
        PLpgSQL_condition *conditions;
-       PLpgSQL_stmts *action;
+       List       *action;                     /* List of statements */
 } PLpgSQL_exception;
 
 
-typedef struct
-{                                                              /* List of WHEN clauses                 */
-       int                     exceptions_alloc;               /* XXX this oughta just be a List
-                                                                                * ... */
-       int                     exceptions_used;
-       PLpgSQL_exception **exceptions;
-} PLpgSQL_exceptions;
-
-
 typedef struct
 {                                                              /* Block of statements                  */
        int                     cmd_type;
        int                     lineno;
        char       *label;
-       PLpgSQL_stmts *body;
-       PLpgSQL_exceptions *exceptions;
+       List       *body;                       /* List of statements */
        int                     n_initvars;
        int                *initvarnos;
+       PLpgSQL_exception_block *exceptions;
 } PLpgSQL_stmt_block;
 
 
@@ -375,7 +359,7 @@ typedef struct
 
 typedef struct
 {                                                              /* Get Diagnostics item         */
-       int                     item;                   /* id for diagnostic value desired */
+       int                     kind;                   /* id for diagnostic value desired */
        int                     target;                 /* where to assign it */
 } PLpgSQL_diag_item;
 
@@ -383,8 +367,7 @@ typedef struct
 {                                                              /* Get Diagnostics statement            */
        int                     cmd_type;
        int                     lineno;
-       int                     ndtitems;
-       PLpgSQL_diag_item *dtitems;
+       List       *diag_items;         /* List of PLpgSQL_diag_item */
 } PLpgSQL_stmt_getdiag;
 
 
@@ -393,17 +376,36 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *cond;
-       PLpgSQL_stmts *true_body;
-       PLpgSQL_stmts *false_body;
+       List       *true_body;          /* List of statements */
+       List       *false_body;         /* List of statements */
 } 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;
        int                     lineno;
        char       *label;
-       PLpgSQL_stmts *body;
+       List       *body;                       /* List of statements */
 } PLpgSQL_stmt_loop;
 
 
@@ -413,7 +415,7 @@ typedef struct
        int                     lineno;
        char       *label;
        PLpgSQL_expr *cond;
-       PLpgSQL_stmts *body;
+       List       *body;                       /* List of statements */
 } PLpgSQL_stmt_while;
 
 
@@ -425,11 +427,27 @@ typedef struct
        PLpgSQL_var *var;
        PLpgSQL_expr *lower;
        PLpgSQL_expr *upper;
+       PLpgSQL_expr *step;                     /* NULL means default (ie, BY 1) */
        int                     reverse;
-       PLpgSQL_stmts *body;
+       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
+{
+       int                     cmd_type;
+       int                     lineno;
+       char       *label;
+       PLpgSQL_rec *rec;
+       PLpgSQL_row *row;
+       List       *body;                       /* List of statements */
+} PLpgSQL_stmt_forq;
+
 typedef struct
 {                                                              /* FOR statement running over SELECT    */
        int                     cmd_type;
@@ -437,31 +455,36 @@ typedef struct
        char       *label;
        PLpgSQL_rec *rec;
        PLpgSQL_row *row;
+       List       *body;                       /* List of statements */
+       /* end of fields that must match PLpgSQL_stmt_forq */
        PLpgSQL_expr *query;
-       PLpgSQL_stmts *body;
 } PLpgSQL_stmt_fors;
 
-
 typedef struct
-{                                                              /* FOR statement running over EXECUTE   */
+{                                                              /* FOR statement running over cursor    */
        int                     cmd_type;
        int                     lineno;
        char       *label;
        PLpgSQL_rec *rec;
        PLpgSQL_row *row;
-       PLpgSQL_expr *query;
-       PLpgSQL_stmts *body;
-} PLpgSQL_stmt_dynfors;
-
+       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;
 
 typedef struct
-{                                                              /* SELECT ... INTO statement            */
+{                                                              /* FOR statement running over EXECUTE   */
        int                     cmd_type;
        int                     lineno;
+       char       *label;
        PLpgSQL_rec *rec;
        PLpgSQL_row *row;
+       List       *body;                       /* List of statements */
+       /* end of fields that must match PLpgSQL_stmt_forq */
        PLpgSQL_expr *query;
-} PLpgSQL_stmt_select;
+       List       *params;                     /* USING expressions */
+} PLpgSQL_stmt_dynfors;
 
 
 typedef struct
@@ -469,6 +492,7 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        int                     curvar;
+       int                     cursor_options;
        PLpgSQL_row *returntype;
        PLpgSQL_expr *argquery;
        PLpgSQL_expr *query;
@@ -477,12 +501,17 @@ typedef struct
 
 
 typedef struct
-{                                                              /* FETCH curvar INTO statement          */
+{                                                              /* FETCH or MOVE statement */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_rec *rec;
+       PLpgSQL_rec *rec;                       /* target, as record or row */
        PLpgSQL_row *row;
-       int                     curvar;
+       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;
 
 
@@ -495,10 +524,11 @@ typedef struct
 
 
 typedef struct
-{                                                              /* EXIT statement                       */
+{                                                              /* EXIT or CONTINUE statement                   */
        int                     cmd_type;
        int                     lineno;
-       char       *label;
+       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;
 
@@ -508,35 +538,55 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *expr;
-       int                     retrecno;
-       int                     retrowno;
+       int                     retvarno;
 } PLpgSQL_stmt_return;
 
 typedef struct
 {                                                              /* RETURN NEXT statement */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_rec *rec;
-       PLpgSQL_row *row;
        PLpgSQL_expr *expr;
+       int                     retvarno;
 } PLpgSQL_stmt_return_next;
 
+typedef struct
+{                                                              /* RETURN QUERY statement */
+       int                     cmd_type;
+       int                     lineno;
+       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
 {                                                              /* RAISE statement                      */
        int                     cmd_type;
        int                     lineno;
        int                     elog_level;
-       char       *message;
-       int                     nparams;
-       int                *params;
+       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 */
        int                     cmd_type;
        int                     lineno;
        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_rec *rec;                       /* INTO target, if record */
+       PLpgSQL_row *row;                       /* INTO target, if row */
 } PLpgSQL_stmt_execsql;
 
 
@@ -544,7 +594,12 @@ typedef struct
 {                                                              /* Dynamic SQL string to execute */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_expr *query;
+       PLpgSQL_expr *query;            /* string expression */
+       bool            into;                   /* INTO supplied? */
+       bool            strict;                 /* INTO STRICT flag */
+       PLpgSQL_rec *rec;                       /* INTO target, if record */
+       PLpgSQL_row *row;                       /* INTO target, if row */
+       List       *params;                     /* USING expressions */
 } PLpgSQL_stmt_dynexecute;
 
 
@@ -552,18 +607,21 @@ 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 relation it is used with, in case the rowtype is
-        * different.  Zero if not called as a trigger.
+        * 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
+        * relation it is used with, in case the rowtype is different.  Zero if
+        * not called as a trigger.
         */
        Oid                     trigrelOid;
 
        /*
-        * We include actual argument types in the hash key to support
-        * polymorphic PLpgSQL functions.  Be careful that extra positions are
-        * zeroed!
+        * 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;
@@ -574,9 +632,10 @@ typedef struct PLpgSQL_function
        char       *fn_name;
        Oid                     fn_oid;
        TransactionId fn_xmin;
-       CommandId       fn_cmin;
-       int                     fn_functype;
+       ItemPointerData fn_tid;
+       bool            fn_is_trigger;
        PLpgSQL_func_hashkey *fn_hashkey;       /* back-link to hashtable key */
+       MemoryContext fn_cxt;
 
        Oid                     fn_rettype;
        int                     fn_rettyplen;
@@ -589,6 +648,7 @@ typedef struct PLpgSQL_function
 
        int                     fn_nargs;
        int                     fn_argvarnos[FUNC_MAX_ARGS];
+       int                     out_param_varno;
        int                     found_varno;
        int                     new_varno;
        int                     old_varno;
@@ -598,16 +658,25 @@ typedef struct PLpgSQL_function
        int                     tg_op_varno;
        int                     tg_relid_varno;
        int                     tg_relname_varno;
+       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 */
@@ -619,15 +688,13 @@ typedef struct
        bool            readonly_func;
 
        TupleDesc       rettupdesc;
-       char       *exitlabel;
+       char       *exitlabel;          /* the "target" label of the current EXIT or
+                                                                * CONTINUE stmt, if any */
 
        Tuplestorestate *tuple_store;           /* SRFs accumulate results here */
        MemoryContext tuple_store_cxt;
        ReturnSetInfo *rsi;
 
-       int                     trig_nargs;
-       Datum      *trig_argv;
-
        int                     found_varno;
        int                     ndatums;
        PLpgSQL_datum **datums;
@@ -636,21 +703,70 @@ typedef struct
        SPITupleTable *eval_tuptable;
        uint32          eval_processed;
        Oid                     eval_lastoid;
-       ExprContext *eval_econtext;
+       ExprContext *eval_econtext; /* for executing simple expressions */
+       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;
 
 
+/*
+ * 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
+{
+       /* 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;
+
+
 /**********************************************************************
  * Global variable declarations
  **********************************************************************/
 
-extern int     plpgsql_DumpExecTree;
-extern int     plpgsql_SpaceScanned;
+extern bool plpgsql_DumpExecTree;
+extern bool plpgsql_SpaceScanned;
 extern int     plpgsql_nDatums;
 extern PLpgSQL_datum **plpgsql_Datums;
 
@@ -660,9 +776,13 @@ extern char *plpgsql_error_funcname;
 /* linkage to the real yytext variable */
 extern char *plpgsql_base_yytext;
 
-#define plpgsql_yytext plpgsql_base_yytext
+#define yytext plpgsql_base_yytext
 
 extern PLpgSQL_function *plpgsql_curr_compile;
+extern bool plpgsql_check_syntax;
+extern MemoryContext compile_tmp_cxt;
+
+extern PLpgSQL_plugin **plugin_ptr;
 
 /**********************************************************************
  * Function declarations
@@ -674,9 +794,10 @@ extern PLpgSQL_function *plpgsql_curr_compile;
  */
 extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo,
                                bool forValidator);
-extern int     plpgsql_parse_word(char *word);
-extern int     plpgsql_parse_dblword(char *word);
-extern int     plpgsql_parse_tripword(char *word);
+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);
 extern int     plpgsql_parse_wordtype(char *word);
 extern int     plpgsql_parse_dblwordtype(char *word);
 extern int     plpgsql_parse_tripwordtype(char *word);
@@ -684,20 +805,26 @@ extern int        plpgsql_parse_wordrowtype(char *word);
 extern int     plpgsql_parse_dblwordrowtype(char *word);
 extern PLpgSQL_type *plpgsql_parse_datatype(const char *string);
 extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod);
-extern PLpgSQL_variable *plpgsql_build_variable(char *refname, int lineno,
+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);
+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);
 extern void plpgsql_HashTableInit(void);
+extern void plpgsql_compile_error_callback(void *arg);
 
 /* ----------
  * Functions in pl_handler.c
  * ----------
  */
-extern void plpgsql_init(void);
+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);
 
 /* ----------
@@ -708,27 +835,22 @@ extern Datum plpgsql_exec_function(PLpgSQL_function *func,
                                          FunctionCallInfo fcinfo);
 extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func,
                                         TriggerData *trigdata);
-extern void plpgsql_xact_cb(XactEvent event, TransactionId parentXid, 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 char *plpgsql_dstring_get(PLpgSQL_dstring *ds);
+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 namestack handling in pl_funcs.c
+ * Functions for namestack handling in pl_funcs.c
  * ----------
  */
 extern void plpgsql_ns_init(void);
 extern bool plpgsql_ns_setlocal(bool flag);
-extern void plpgsql_ns_push(char *label);
+extern void plpgsql_ns_push(const char *label);
 extern void plpgsql_ns_pop(void);
-extern void plpgsql_ns_additem(int itemtype, int itemno, char *name);
-extern PLpgSQL_nsitem *plpgsql_ns_lookup(char *name, char *nsname);
+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);
+extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(const char *name);
 extern void plpgsql_ns_rename(char *oldname, char *newname);
 
 /* ----------
@@ -750,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 */