* 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
* ----------
PLPGSQL_DTYPE_REC,
PLPGSQL_DTYPE_RECFIELD,
PLPGSQL_DTYPE_ARRAYELEM,
- PLPGSQL_DTYPE_EXPR,
- PLPGSQL_DTYPE_TRIGARG
+ PLPGSQL_DTYPE_EXPR
};
/* ----------
* 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_RC_OK,
PLPGSQL_RC_EXIT,
PLPGSQL_RC_RETURN,
- PLPGSQL_RC_CONTINUE
+ PLPGSQL_RC_CONTINUE,
+ PLPGSQL_RC_RERAISE
};
/* ----------
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 */
/*
* 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 */
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;
typedef struct
{ /* Row variable */
int dtype;
- int rowno;
+ int dno;
char *refname;
int lineno;
typedef struct
{ /* Record variable (non-fixed structure) */
int dtype;
- int recno;
+ int dno;
char *refname;
int lineno;
typedef struct
{ /* Field in record */
int dtype;
- int rfno;
+ int dno;
char *fieldname;
int recparentno; /* dno of parent record */
} PLpgSQL_recfield;
} 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;
} 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;
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;
{ /* 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
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 */
{ /* 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
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;
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 */
MemoryContext tuple_store_cxt;
ReturnSetInfo *rsi;
- int trig_nargs;
- Datum *trig_argv;
-
int found_varno;
int ndatums;
PLpgSQL_datum **datums;
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;
*/
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);
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);
*/
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);
/* ----------
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
* ----------
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);
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 */