diff -c -r src.old/gram.y src/gram.y *** src.old/gram.y 2005-02-22 08:18:24.000000000 +0100 --- src/gram.y 2005-03-08 09:22:20.886036232 +0100 *************** *** 80,85 **** --- 80,90 ---- int n_initvars; int *initvarnos; } declhdr; + struct + { + int sqlstate_varno; + int sqlerrm_varno; + } fict_vars; List *list; PLpgSQL_type *dtype; PLpgSQL_datum *scalar; /* a VAR, RECFIELD, or TRIGARG */ *************** *** 95,101 **** PLpgSQL_nsitem *nsitem; PLpgSQL_diag_item *diagitem; } ! %type decl_sect %type decl_varname %type decl_renname --- 100,106 ---- PLpgSQL_nsitem *nsitem; PLpgSQL_diag_item *diagitem; } ! %type fict_vars_sect %type decl_sect %type decl_varname %type decl_renname *************** *** 244,268 **** | ';' ; ! pl_block : decl_sect K_BEGIN lno proc_sect exception_sect K_END { PLpgSQL_stmt_block *new; new = palloc0(sizeof(PLpgSQL_stmt_block)); new->cmd_type = PLPGSQL_STMT_BLOCK; ! new->lineno = $3; new->label = $1.label; new->n_initvars = $1.n_initvars; new->initvarnos = $1.initvarnos; ! new->body = $4; ! new->exceptions = $5; plpgsql_ns_pop(); $$ = (PLpgSQL_stmt *)new; } ; decl_sect : opt_label --- 249,288 ---- | ';' ; ! pl_block : decl_sect fict_vars_sect K_BEGIN lno proc_sect exception_sect K_END { PLpgSQL_stmt_block *new; new = palloc0(sizeof(PLpgSQL_stmt_block)); new->cmd_type = PLPGSQL_STMT_BLOCK; ! new->lineno = $4; new->label = $1.label; new->n_initvars = $1.n_initvars; new->initvarnos = $1.initvarnos; ! new->body = $5; ! new->exceptions = $6; ! ! new->sqlstate_varno = $2.sqlstate_varno; ! new->sqlerrm_varno = $2.sqlerrm_varno; plpgsql_ns_pop(); $$ = (PLpgSQL_stmt *)new; } ; + fict_vars_sect : + { + plpgsql_ns_setlocal(false); + PLpgSQL_variable *var; + var = plpgsql_build_variable("sqlstate", 0, + plpgsql_build_datatype(TEXTOID, -1), true); + $$.sqlstate_varno = var->dno; + var = plpgsql_build_variable("sqlerrm", 0, + plpgsql_build_datatype(TEXTOID, -1), true); + $$.sqlerrm_varno = var->dno; + plpgsql_add_initdatums(NULL); + }; decl_sect : opt_label diff -c -r src.old/pl_exec.c src/pl_exec.c *** src.old/pl_exec.c 2005-02-24 02:11:40.000000000 +0100 --- src/pl_exec.c 2005-03-08 09:40:16.537512352 +0100 *************** *** 181,186 **** --- 181,187 ---- static void exec_init_tuple_store(PLpgSQL_execstate *estate); static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2); static void exec_set_found(PLpgSQL_execstate *estate, bool state); + static char *unpack_sql_state(int ssval); /* ---------- *************** *** 809,814 **** --- 810,829 ---- int i; int n; + /* setup SQLSTATE and SQLERRM */ + PLpgSQL_var *var; + + var = (PLpgSQL_var *) (estate->datums[block->sqlstate_varno]); + var->isnull = false; + var->freeval = true; + var->value = DirectFunctionCall1(textin, CStringGetDatum("00000")); + + var = (PLpgSQL_var *) (estate->datums[block->sqlerrm_varno]); + var->isnull = false; + var->freeval = true; + var->value = DirectFunctionCall1(textin, CStringGetDatum("Sucessful completion")); + + /* * First initialize all variables declared in this block */ *************** *** 918,923 **** --- 933,949 ---- MemoryContextSwitchTo(oldcontext); CurrentResourceOwner = oldowner; + + /* set SQLSTATE and SQLERRM variables */ + + var = (PLpgSQL_var *) (estate->datums[block->sqlstate_varno]); + pfree((void *) (var->value)); + var->value = DirectFunctionCall1(textin, CStringGetDatum(unpack_sql_state(edata->sqlerrcode))); + + var = (PLpgSQL_var *) (estate->datums[block->sqlerrm_varno]); + pfree((void *) (var->value)); + var->value = DirectFunctionCall1(textin, CStringGetDatum(edata->message)); + /* * If AtEOSubXact_SPI() popped any SPI context of the subxact, * it will have left us in a disconnected state. We need this *************** *** 4319,4321 **** --- 4345,4368 ---- FreeExecutorState(simple_eval_estate); simple_eval_estate = NULL; } + + /* + * unpack MAKE_SQLSTATE code + * This code is redundand backend/utils/error/elog.c. I din't + * wont modify different part than plpgsql + */ + + static char * + unpack_sql_state(int ssval) + { + static char tbuf[12]; + int i; + + for (i = 0; i < 5; i++) + { + tbuf[i] = PGUNSIXBIT(ssval); + ssval >>= 6; + } + tbuf[i] = '\0'; + return tbuf; + } diff -c -r src.old/plpgsql.h src/plpgsql.h *** src.old/plpgsql.h 2005-02-22 08:18:24.000000000 +0100 --- src/plpgsql.h 2005-03-08 08:59:46.877876760 +0100 *************** *** 339,344 **** --- 339,346 ---- List *exceptions; /* List of WHEN clauses */ int n_initvars; int *initvarnos; + int sqlstate_varno; + int sqlerrm_varno; } PLpgSQL_stmt_block;