]> 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 945569b6f6a416f9628a86cfa469442cc31e388e..3d0f155a884142d477b8a4fbe55ece44478ad84f 100644 (file)
@@ -1,56 +1,43 @@
-/**********************************************************************
+/*-------------------------------------------------------------------------
+ *
  * plpgsql.h           - Definitions for the PL/pgSQL
  *                       procedural language
  *
- * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.30 2002/12/13 19:46:01 tgl 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
@@ -58,8 +45,7 @@ enum
        PLPGSQL_NSTYPE_LABEL,
        PLPGSQL_NSTYPE_VAR,
        PLPGSQL_NSTYPE_ROW,
-       PLPGSQL_NSTYPE_REC,
-       PLPGSQL_NSTYPE_RECFIELD
+       PLPGSQL_NSTYPE_REC
 };
 
 /* ----------
@@ -72,27 +58,41 @@ enum
        PLPGSQL_DTYPE_ROW,
        PLPGSQL_DTYPE_REC,
        PLPGSQL_DTYPE_RECFIELD,
-       PLPGSQL_DTYPE_EXPR,
-       PLPGSQL_DTYPE_TRIGARG
+       PLPGSQL_DTYPE_ARRAYELEM,
+       PLPGSQL_DTYPE_EXPR
 };
 
 /* ----------
- * Execution tree node types
+ * Variants distinguished in PLpgSQL_type structs
  * ----------
  */
 enum
+{
+       PLPGSQL_TTYPE_SCALAR,           /* scalar types and domains */
+       PLPGSQL_TTYPE_ROW,                      /* composite types */
+       PLPGSQL_TTYPE_REC,                      /* RECORD pseudotype */
+       PLPGSQL_TTYPE_PSEUDO            /* other pseudotypes */
+};
+
+/* ----------
+ * Execution tree node types
+ * ----------
+ */
+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,
@@ -113,7 +113,9 @@ enum
 {
        PLPGSQL_RC_OK,
        PLPGSQL_RC_EXIT,
-       PLPGSQL_RC_RETURN
+       PLPGSQL_RC_RETURN,
+       PLPGSQL_RC_CONTINUE,
+       PLPGSQL_RC_RERAISE
 };
 
 /* ----------
@@ -126,6 +128,18 @@ 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
@@ -133,50 +147,71 @@ enum
 
 
 typedef struct
-{                                                              /* Dynamic string control structure */
-       int                     alloc;
-       int                     used;
-       char       *value;
-}      PLpgSQL_dstring;
-
-
-typedef struct
-{                                                              /* Postgres base data type              */
-       char       *typname;
-       Oid                     typoid;
-       FmgrInfo        typinput;
-       Oid                     typelem;
-       int16           typlen;
+{                                                              /* Postgres data type */
+       char       *typname;            /* (simple) name of the type */
+       Oid                     typoid;                 /* OID of the data type */
+       int                     ttype;                  /* PLPGSQL_TTYPE_ code */
+       int16           typlen;                 /* stuff copied from its pg_type entry */
        bool            typbyval;
-       int32           atttypmod;
-}      PLpgSQL_type;
+       Oid                     typrelid;
+       Oid                     typioparam;
+       FmgrInfo        typinput;               /* lookup info for typinput function */
+       int32           atttypmod;              /* typmod (taken from someplace else) */
+} PLpgSQL_type;
 
 
+/*
+ * PLpgSQL_datum is the common supertype for PLpgSQL_expr, PLpgSQL_var,
+ * PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, and PLpgSQL_arrayelem
+ */
 typedef struct
 {                                                              /* Generic datum array item             */
        int                     dtype;
        int                     dno;
-}      PLpgSQL_datum;
-
+} PLpgSQL_datum;
 
+/*
+ * The variants PLpgSQL_var, PLpgSQL_row, and PLpgSQL_rec share these
+ * fields
+ */
 typedef struct
+{                                                              /* Scalar or composite variable */
+       int                     dtype;
+       int                     dno;
+       char       *refname;
+       int                     lineno;
+} PLpgSQL_variable;
+
+typedef struct PLpgSQL_expr
 {                                                              /* SQL Query to plan and execute        */
        int                     dtype;
-       int                     exprno;
+       int                     dno;
        char       *query;
-       void       *plan;
-       ExprState  *plan_simple_expr;
-       Oid                     plan_simple_type;
-       Oid                *plan_argtypes;
-       int                     nparams;
-       int                     params[1];
-}      PLpgSQL_expr;
+       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 */
+       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;
+       LocalTransactionId expr_simple_lxid;
+} PLpgSQL_expr;
 
 
 typedef struct
-{                                                              /* Local variable                       */
+{                                                              /* Scalar variable */
        int                     dtype;
-       int                     varno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -186,31 +221,40 @@ typedef struct
        PLpgSQL_expr *default_val;
        PLpgSQL_expr *cursor_explicit_expr;
        int                     cursor_explicit_argrow;
+       int                     cursor_options;
 
        Datum           value;
        bool            isnull;
        bool            freeval;
-}      PLpgSQL_var;
+} PLpgSQL_var;
 
 
 typedef struct
-{                                                              /* Rowtype                              */
+{                                                              /* Row variable */
        int                     dtype;
-       int                     rowno;
+       int                     dno;
        char       *refname;
        int                     lineno;
-       Oid                     rowtypeclass;
 
+       TupleDesc       rowtupdesc;
+
+       /*
+        * Note: TupleDesc is only set up for named rowtypes, else it is NULL.
+        *
+        * Note: if the underlying rowtype contains a dropped column, the
+        * corresponding fieldnames[] entry will be NULL, and there is no
+        * corresponding var (varnos[] will be -1).
+        */
        int                     nfields;
        char      **fieldnames;
        int                *varnos;
-}      PLpgSQL_row;
+} PLpgSQL_row;
 
 
 typedef struct
-{                                                              /* Record of undefined structure        */
+{                                                              /* Record variable (non-fixed structure) */
        int                     dtype;
-       int                     recno;
+       int                     dno;
        char       *refname;
        int                     lineno;
 
@@ -218,24 +262,25 @@ typedef struct
        TupleDesc       tupdesc;
        bool            freetup;
        bool            freetupdesc;
-}      PLpgSQL_rec;
+} PLpgSQL_rec;
 
 
 typedef struct
-{                                                              /* Field in record                      */
+{                                                              /* Field in record */
        int                     dtype;
-       int                     rfno;
+       int                     dno;
        char       *fieldname;
-       int                     recno;
-}      PLpgSQL_recfield;
+       int                     recparentno;    /* dno of parent record */
+} PLpgSQL_recfield;
 
 
 typedef struct
-{                                                              /* Positional argument to trigger       */
+{                                                              /* Element of array variable */
        int                     dtype;
        int                     dno;
-       PLpgSQL_expr *argnum;
-}      PLpgSQL_trigarg;
+       PLpgSQL_expr *subscript;
+       int                     arrayparentno;  /* dno of parent array variable */
+} PLpgSQL_arrayelem;
 
 
 typedef struct
@@ -243,31 +288,46 @@ typedef struct
        int                     itemtype;
        int                     itemno;
        char            name[1];
-}      PLpgSQL_nsitem;
+} PLpgSQL_nsitem;
 
 
+/* XXX: consider adapting this to use List */
 typedef struct PLpgSQL_ns
 {                                                              /* Compiler namestack level             */
        int                     items_alloc;
        int                     items_used;
        PLpgSQL_nsitem **items;
        struct PLpgSQL_ns *upper;
-}      PLpgSQL_ns;
+} PLpgSQL_ns;
 
 
 typedef struct
-{                                                              /* List of execution nodes              */
-       int                     stmts_alloc;
-       int                     stmts_used;
-       struct PLpgSQL_stmt **stmts;
-}      PLpgSQL_stmts;
+{                                                              /* Generic execution node               */
+       int                     cmd_type;
+       int                     lineno;
+} PLpgSQL_stmt;
+
 
+typedef struct PLpgSQL_condition
+{                                                              /* One EXCEPTION condition name */
+       int                     sqlerrstate;    /* SQLSTATE code */
+       char       *condname;           /* condition name (for debugging) */
+       struct PLpgSQL_condition *next;
+} PLpgSQL_condition;
 
 typedef struct
-{                                                              /* Generic execution node               */
-       int                     cmd_type;
+{
+       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_stmt;
+       PLpgSQL_condition *conditions;
+       List       *action;                     /* List of statements */
+} PLpgSQL_exception;
 
 
 typedef struct
@@ -275,10 +335,11 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        char       *label;
-       PLpgSQL_stmts *body;
+       List       *body;                       /* List of statements */
        int                     n_initvars;
        int                *initvarnos;
-}      PLpgSQL_stmt_block;
+       PLpgSQL_exception_block *exceptions;
+} PLpgSQL_stmt_block;
 
 
 typedef struct
@@ -287,28 +348,27 @@ typedef struct
        int                     lineno;
        int                     varno;
        PLpgSQL_expr *expr;
-}      PLpgSQL_stmt_assign;
+} PLpgSQL_stmt_assign;
 
 typedef struct
 {                                                              /* PERFORM statement            */
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *expr;
-}   PLpgSQL_stmt_perform;
+} PLpgSQL_stmt_perform;
 
 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;
+} PLpgSQL_diag_item;
 
 typedef struct
 {                                                              /* Get Diagnostics statement            */
        int                     cmd_type;
        int                     lineno;
-       int                     ndtitems;
-       PLpgSQL_diag_item *dtitems;
-}      PLpgSQL_stmt_getdiag;
+       List       *diag_items;         /* List of PLpgSQL_diag_item */
+} PLpgSQL_stmt_getdiag;
 
 
 typedef struct
@@ -316,9 +376,28 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *cond;
-       PLpgSQL_stmts *true_body;
-       PLpgSQL_stmts *false_body;
-}      PLpgSQL_stmt_if;
+       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
@@ -326,8 +405,8 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        char       *label;
-       PLpgSQL_stmts *body;
-}      PLpgSQL_stmt_loop;
+       List       *body;                       /* List of statements */
+} PLpgSQL_stmt_loop;
 
 
 typedef struct
@@ -336,8 +415,8 @@ typedef struct
        int                     lineno;
        char       *label;
        PLpgSQL_expr *cond;
-       PLpgSQL_stmts *body;
-}      PLpgSQL_stmt_while;
+       List       *body;                       /* List of statements */
+} PLpgSQL_stmt_while;
 
 
 typedef struct
@@ -348,43 +427,64 @@ 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;
-}      PLpgSQL_stmt_fori;
+       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
-{                                                              /* FOR statement running over SELECT    */
+{
        int                     cmd_type;
        int                     lineno;
        char       *label;
        PLpgSQL_rec *rec;
        PLpgSQL_row *row;
-       PLpgSQL_expr *query;
-       PLpgSQL_stmts *body;
-}      PLpgSQL_stmt_fors;
-
+       List       *body;                       /* List of statements */
+} PLpgSQL_stmt_forq;
 
 typedef struct
-{                                                              /* FOR statement running over EXECUTE   */
+{                                                              /* FOR statement running over SELECT    */
        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_stmts *body;
-}      PLpgSQL_stmt_dynfors;
+} PLpgSQL_stmt_fors;
 
+typedef struct
+{                                                              /* FOR statement running over cursor    */
+       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 */
+       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
@@ -392,21 +492,27 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        int                     curvar;
+       int                     cursor_options;
        PLpgSQL_row *returntype;
        PLpgSQL_expr *argquery;
        PLpgSQL_expr *query;
        PLpgSQL_expr *dynquery;
-}      PLpgSQL_stmt_open;
+} PLpgSQL_stmt_open;
 
 
 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;
-}      PLpgSQL_stmt_fetch;
+       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;
 
 
 typedef struct
@@ -414,16 +520,17 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        int                     curvar;
-}      PLpgSQL_stmt_close;
+} PLpgSQL_stmt_close;
 
 
 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;
+} PLpgSQL_stmt_exit;
 
 
 typedef struct
@@ -431,27 +538,42 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *expr;
-       int                     retrecno;
-}      PLpgSQL_stmt_return;
+       int                     retvarno;
+} PLpgSQL_stmt_return;
 
 typedef struct
 {                                                              /* RETURN NEXT statement */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_rec *rec;
-       PLpgSQL_row *row;
        PLpgSQL_expr *expr;
-}      PLpgSQL_stmt_return_next;
+       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;
-}      PLpgSQL_stmt_raise;
+       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
@@ -459,15 +581,50 @@ typedef struct
        int                     cmd_type;
        int                     lineno;
        PLpgSQL_expr *sqlstmt;
-}      PLpgSQL_stmt_execsql;
+       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;
 
 
 typedef struct
 {                                                              /* Dynamic SQL string to execute */
        int                     cmd_type;
        int                     lineno;
-       PLpgSQL_expr *query;
-}      PLpgSQL_stmt_dynexecute;
+       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;
+
+
+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.
+        */
+       Oid                     trigrelOid;
+
+       /*
+        * 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;
 
 
 typedef struct PLpgSQL_function
@@ -475,19 +632,23 @@ 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;
        bool            fn_retbyval;
        FmgrInfo        fn_retinput;
-       Oid                     fn_rettypelem;
+       Oid                     fn_rettypioparam;
        bool            fn_retistuple;
        bool            fn_retset;
+       bool            fn_readonly;
 
        int                     fn_nargs;
        int                     fn_argvarnos[FUNC_MAX_ARGS];
+       int                     out_param_varno;
        int                     found_varno;
        int                     new_varno;
        int                     old_varno;
@@ -497,18 +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;
 
-       struct PLpgSQL_function *next;          /* for chaining list of functions */
-}      PLpgSQL_function;
+       /* 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 */
@@ -517,16 +685,16 @@ typedef struct
        bool            retistuple;
        bool            retisset;
 
+       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;
@@ -535,31 +703,86 @@ typedef struct
        SPITupleTable *eval_tuptable;
        uint32          eval_processed;
        Oid                     eval_lastoid;
-       ExprContext *eval_econtext;
-}      PLpgSQL_execstate;
+       ExprContext *eval_econtext; /* for executing simple expressions */
+       PLpgSQL_expr *cur_expr;         /* current query/expr being evaluated */
+
+       /* 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
+{
+       /* 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;
 
 extern int     plpgsql_error_lineno;
 extern char *plpgsql_error_funcname;
 
-/* linkage to the real yytext and yylineno variables */
+/* linkage to the real yytext variable */
 extern char *plpgsql_base_yytext;
 
-#define plpgsql_yytext plpgsql_base_yytext
-extern int     plpgsql_base_yylineno;
-
-#define plpgsql_yylineno plpgsql_base_yylineno
+#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
@@ -569,55 +792,65 @@ extern PLpgSQL_function *plpgsql_curr_compile;
  * Functions in pl_comp.c
  * ----------
  */
-extern PLpgSQL_function *plpgsql_compile(Oid fn_oid, int functype);
-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(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);
 extern int     plpgsql_parse_wordtype(char *word);
 extern int     plpgsql_parse_dblwordtype(char *word);
 extern int     plpgsql_parse_tripwordtype(char *word);
 extern int     plpgsql_parse_wordrowtype(char *word);
 extern int     plpgsql_parse_dblwordrowtype(char *word);
-extern PLpgSQL_type *plpgsql_parse_datatype(char *string);
-extern void plpgsql_adddatum(PLpgSQL_datum * new);
+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(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_yyerror(const char *s);
+extern void plpgsql_HashTableInit(void);
+extern void plpgsql_compile_error_callback(void *arg);
 
 /* ----------
  * Functions in pl_handler.c
  * ----------
  */
+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);
 
 /* ----------
  * Functions in pl_exec.c
  * ----------
  */
-extern Datum plpgsql_exec_function(PLpgSQL_function * func,
+extern Datum plpgsql_exec_function(PLpgSQL_function *func,
                                          FunctionCallInfo fcinfo);
-extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function * func,
+extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func,
                                         TriggerData *trigdata);
-
-
-/* ----------
- * 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, 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);
 
 /* ----------
@@ -625,8 +858,8 @@ extern void plpgsql_ns_rename(char *oldname, char *newname);
  * ----------
  */
 extern void plpgsql_convert_ident(const char *s, char **output, int numidents);
-extern const char *plpgsql_stmt_typename(PLpgSQL_stmt * stmt);
-extern void plpgsql_dumptree(PLpgSQL_function * func);
+extern const char *plpgsql_stmt_typename(PLpgSQL_stmt *stmt);
+extern void plpgsql_dumptree(PLpgSQL_function *func);
 
 /* ----------
  * Externs in gram.y and scan.l
@@ -637,6 +870,9 @@ extern int  plpgsql_yyparse(void);
 extern int     plpgsql_base_yylex(void);
 extern int     plpgsql_yylex(void);
 extern void plpgsql_push_back_token(int token);
-extern void plpgsql_setinput(char *s, int functype);
+extern void plpgsql_yyerror(const char *message);
+extern int     plpgsql_scanner_lineno(void);
+extern void plpgsql_scanner_init(const char *str);
+extern void plpgsql_scanner_finish(void);
 
 #endif   /* PLPGSQL_H */