and SPI_return values. Patch from Philip Warner.
Jan
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.11 2000/08/31 13:26:15 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.12 2000/09/05 09:02:18 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
%type <stmt> stmt_assign, stmt_if, stmt_loop, stmt_while, stmt_exit
%type <stmt> stmt_return, stmt_raise, stmt_execsql, stmt_fori
%type <stmt> stmt_fors, stmt_select, stmt_perform
-%type <stmt> stmt_dynexecute, stmt_dynfors
+%type <stmt> stmt_dynexecute, stmt_dynfors, stmt_getdiag
%type <dtlist> raise_params
%type <ival> raise_level, raise_param
%type <str> raise_msg
+%type <dtlist> getdiag_items, getdiag_targets
+%type <ival> getdiag_item, getdiag_target
+
%type <ival> lno
/*
%token K_DEBUG
%token K_DECLARE
%token K_DEFAULT
+%token K_DIAGNOSTICS
%token K_DOTDOT
%token K_ELSE
%token K_END
%token K_EXIT
%token K_FOR
%token K_FROM
+%token K_GET
%token K_IF
%token K_IN
%token K_INTO
%token K_NOTICE
%token K_NULL
%token K_PERFORM
+%token K_PROCESSED
%token K_RAISE
%token K_RECORD
%token K_RENAME
+%token K_RESULT
%token K_RETURN
%token K_REVERSE
%token K_SELECT
decl_varname : T_WORD
{
- $$.name = strdup(yytext);
+ $$.name = plpgsql_tolower(strdup(yytext));
$$.lineno = yylineno;
}
;
{ $$ = $1; }
| stmt_perform
{ $$ = $1; }
+ | stmt_getdiag
+ { $$ = $1; }
;
stmt_perform : K_PERFORM lno expr_until_semi
}
;
+stmt_getdiag : K_GET K_DIAGNOSTICS lno K_SELECT getdiag_items K_INTO getdiag_targets ';'
+ {
+ PLpgSQL_stmt_getdiag *new;
+
+ new = malloc(sizeof(PLpgSQL_stmt_getdiag));
+ memset(new, 0, sizeof(PLpgSQL_stmt_getdiag));
+
+ new->cmd_type = PLPGSQL_STMT_GETDIAG;
+ new->lineno = $3;
+ new->nitems = $5.nused;
+ new->items = malloc(sizeof(int) * $5.nused);
+ new->ntargets = $7.nused;
+ new->targets = malloc(sizeof(int) * $7.nused);
+ memcpy(new->items, $5.dtnums, sizeof(int) * $5.nused);
+ memcpy(new->targets, $7.dtnums, sizeof(int) * $7.nused);
+
+ if (new->nitems != new->ntargets) {
+ plpgsql_error_lineno = new->lineno;
+ plpgsql_comperrinfo();
+ elog(ERROR, "number of diagnostic items does not match target list");
+ };
+
+ $$ = (PLpgSQL_stmt *)new;
+ }
+ ;
+
+getdiag_items : getdiag_items ',' getdiag_item
+ {
+ if ($1.nused == $1.nalloc) {
+ $1.nalloc *= 2;
+ $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
+ }
+ $1.dtnums[$1.nused++] = $3;
+
+ $$.nalloc = $1.nalloc;
+ $$.nused = $1.nused;
+ $$.dtnums = $1.dtnums;
+ }
+ | getdiag_item
+ {
+ $$.nalloc = 1;
+ $$.nused = 1;
+ $$.dtnums = palloc(sizeof(int) * $$.nalloc);
+ $$.dtnums[0] = $1;
+ }
+ ;
+
+getdiag_item : K_PROCESSED
+ {
+ $$ = PLPGSQL_GETDIAG_PROCESSED;
+ }
+ | K_RESULT
+ {
+ $$ = PLPGSQL_GETDIAG_RESULT;
+ }
+ ;
+
+getdiag_targets : getdiag_targets ',' getdiag_target
+ {
+ if ($1.nused == $1.nalloc) {
+ $1.nalloc *= 2;
+ $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
+ }
+ $1.dtnums[$1.nused++] = $3;
+
+ $$.nalloc = $1.nalloc;
+ $$.nused = $1.nused;
+ $$.dtnums = $1.dtnums;
+ }
+ | getdiag_target
+ {
+ $$.nalloc = 1;
+ $$.nused = 1;
+ $$.dtnums = palloc(sizeof(int) * $$.nalloc);
+ $$.dtnums[0] = $1;
+ }
+ ;
+
+
+getdiag_target : T_VARIABLE
+ {
+ if (yylval.var->isconst) {
+ plpgsql_comperrinfo();
+ elog(ERROR, "%s is declared CONSTANT; can not receive diagnostics", yylval.var->refname);
+ }
+ $$ = yylval.var->varno;
+ }
+ | T_RECFIELD
+ {
+ $$ = yylval.recfield->rfno;
+ }
+ ;
+
+
assign_var : T_VARIABLE
{
if (yylval.var->isconst) {
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.29 2000/08/31 13:26:16 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.30 2000/09/05 09:02:18 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
PLpgSQL_stmt * stmt);
static int exec_stmt_assign(PLpgSQL_execstate * estate,
PLpgSQL_stmt_assign * stmt);
+static int exec_stmt_getdiag(PLpgSQL_execstate * estate,
+ PLpgSQL_stmt_getdiag * stmt);
static int exec_stmt_if(PLpgSQL_execstate * estate,
PLpgSQL_stmt_if * stmt);
static int exec_stmt_loop(PLpgSQL_execstate * estate,
case PLPGSQL_STMT_ASSIGN:
stmttype = "assignment";
break;
+ case PLPGSQL_STMT_GETDIAG:
+ stmttype = "get diagnostics";
+ break;
case PLPGSQL_STMT_IF:
stmttype = "if";
break;
case PLPGSQL_STMT_ASSIGN:
stmttype = "assignment";
break;
+ case PLPGSQL_STMT_GETDIAG:
+ stmttype = "get diagnostics";
+ break;
case PLPGSQL_STMT_IF:
stmttype = "if";
break;
rc = exec_stmt_assign(estate, (PLpgSQL_stmt_assign *) stmt);
break;
+ case PLPGSQL_STMT_GETDIAG:
+ rc = exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag *) stmt);
+ break;
+
case PLPGSQL_STMT_IF:
rc = exec_stmt_if(estate, (PLpgSQL_stmt_if *) stmt);
break;
return PLPGSQL_RC_OK;
}
+/* ----------
+ * exec_stmt_getdiag Put internal PG information into
+ * specified variables.
+ * ----------
+ */
+static int
+exec_stmt_getdiag(PLpgSQL_execstate * estate, PLpgSQL_stmt_getdiag * stmt)
+{
+ int i;
+ PLpgSQL_datum *var;
+ HeapTuple typeTup;
+ bool isnull = false;
+
+ for ( i=0 ; i < stmt->nitems ; i++)
+ {
+ if ((stmt->targets[i] <= 0))
+ break;
+
+ var = (estate->datums[stmt->targets[i]]);
+
+ if (var == NULL)
+ break;
+
+ switch (stmt->items[i])
+ {
+ case PLPGSQL_GETDIAG_PROCESSED:
+
+ exec_assign_value(estate, var, (Datum)SPI_processed, INT4OID, &isnull);
+ break;
+
+ case PLPGSQL_GETDIAG_RESULT:
+
+ exec_assign_value(estate, var, (Datum)SPI_result, INT4OID, &isnull);
+ break;
+
+ default:
+
+ elog(ERROR, "unknown attribute request %d in get_diagnostic", stmt->items[i]);
+ };
+ };
+
+ return PLPGSQL_RC_OK;
+}
/* ----------
* exec_stmt_if Evaluate a bool expression and
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.7 2000/08/31 13:26:16 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.8 2000/09/05 09:02:18 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
static void dump_execsql(PLpgSQL_stmt_execsql * stmt);
static void dump_dynexecute(PLpgSQL_stmt_dynexecute * stmt);
static void dump_dynfors(PLpgSQL_stmt_dynfors * stmt);
+static void dump_getdiag(PLpgSQL_stmt_getdiag * stmt);
static void dump_expr(PLpgSQL_expr * expr);
case PLPGSQL_STMT_DYNFORS:
dump_dynfors((PLpgSQL_stmt_dynfors *) stmt);
break;
+ case PLPGSQL_STMT_GETDIAG:
+ dump_getdiag((PLpgSQL_stmt_getdiag *) stmt);
+ break;
default:
elog(ERROR, "plpgsql_dump: unknown cmd_type %d\n", stmt->cmd_type);
break;
{
dump_ind();
printf("RETURN ");
- if (stmt->retrecno >= 0)
+ if (stmt->retrecno > 0)
printf("record %d", stmt->retrecno);
else
{
printf(" ENDFORS\n");
}
+static void
+dump_getdiag(PLpgSQL_stmt_getdiag * stmt)
+{
+ int i;
+
+ dump_ind();
+ printf("GET DIAGNOSTICS SELECT ");
+ for (i = 0; i < stmt->nitems; i++)
+ {
+ if (i != 0)
+ printf(", ");
+
+ switch (stmt->items[i])
+ {
+ case PLPGSQL_GETDIAG_PROCESSED:
+ printf("PROCESSED");
+ break;
+
+ case PLPGSQL_GETDIAG_RESULT:
+ printf("RESULT");
+ break;
+
+ default:
+ printf("???");
+ break;
+ }
+ }
+ printf(" INTO ");
+ for (i = 0; i < stmt->ntargets; i++)
+ {
+ if (i != 0)
+ printf(", ");
+
+ printf("{var %d}", stmt->targets[i]);
+ }
+
+ printf("\n");
+}
+
static void
dump_expr(PLpgSQL_expr * expr)
{
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.10 2000/08/31 13:26:16 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.11 2000/09/05 09:02:18 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
PLPGSQL_STMT_RAISE,
PLPGSQL_STMT_EXECSQL,
PLPGSQL_STMT_DYNEXECUTE,
- PLPGSQL_STMT_DYNFORS
+ PLPGSQL_STMT_DYNFORS,
+ PLPGSQL_STMT_GETDIAG
};
PLPGSQL_RC_RETURN
};
+/* ----------
+ * GET DIAGNOSTICS system attrs
+ * ----------
+ */
+enum
+{
+ PLPGSQL_GETDIAG_PROCESSED,
+ PLPGSQL_GETDIAG_RESULT
+};
+
+
/**********************************************************************
* Node and structure definitions
**********************************************************************/
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
+typedef struct
+{ /* Get Disgnostics statement */
+ int cmd_type;
+ int lineno;
+ int nitems;
+ int *items;
+ int ntargets;
+ int *targets;
+} PLpgSQL_stmt_getdiag;
+
typedef struct
{ /* IF statement */
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.6 2000/08/31 13:26:16 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.7 2000/09/05 09:02:18 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
debug { return K_DEBUG; }
declare { return K_DECLARE; }
default { return K_DEFAULT; }
+diagnostics { return K_DIAGNOSTICS; }
else { return K_ELSE; }
end { return K_END; }
exception { return K_EXCEPTION; }
exit { return K_EXIT; }
for { return K_FOR; }
from { return K_FROM; }
+get { return K_GET; }
if { return K_IF; }
in { return K_IN; }
into { return K_INTO; }
notice { return K_NOTICE; }
null { return K_NULL; }
perform { return K_PERFORM; }
+processed { return K_PROCESSED; }
raise { return K_RAISE; }
record { return K_RECORD; }
rename { return K_RENAME; }
+result { return K_RESULT; }
return { return K_RETURN; }
reverse { return K_REVERSE; }
select { return K_SELECT; }