diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index cc5eb733534ce53dc083cf7ade185081c976933f..09f7a99097dda5c9ac2b06accb18b4dc8a016646 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.187 2007/02/01 19:22:07 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.188 2007/02/08 18:37:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -885,43 +885,43 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) { PLpgSQL_var *var = (PLpgSQL_var *) (estate->datums[n]); + /* free any old value, in case re-entering block */ free_var(var); - if (!var->isconst || var->isnull) + + /* Initially it contains a NULL */ + var->value = (Datum) 0; + var->isnull = true; + + if (var->default_val == NULL) { - if (var->default_val == NULL) + /* + * If needed, give the datatype a chance to reject + * NULLs, by assigning a NULL to the variable. + * We claim the value is of type UNKNOWN, not the + * var's datatype, else coercion will be skipped. + * (Do this before the notnull check to be + * consistent with exec_assign_value.) + */ + if (!var->datatype->typinput.fn_strict) { - /* Initially it contains a NULL */ - var->value = (Datum) 0; - var->isnull = true; - /* - * If needed, give the datatype a chance to reject - * NULLs, by assigning a NULL to the variable. - * We claim the value is of type UNKNOWN, not the - * var's datatype, else coercion will be skipped. - * (Do this before the notnull check to be - * consistent with exec_assign_value.) - */ - if (!var->datatype->typinput.fn_strict) - { - bool valIsNull = true; - - exec_assign_value(estate, - (PLpgSQL_datum *) var, - (Datum) 0, - UNKNOWNOID, - &valIsNull); - } - if (var->notnull) - ereport(ERROR, + bool valIsNull = true; + + exec_assign_value(estate, + (PLpgSQL_datum *) var, + (Datum) 0, + UNKNOWNOID, + &valIsNull); + } + if (var->notnull) + ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("variable \"%s\" declared NOT NULL cannot default to NULL", var->refname))); - } - else - { - exec_assign_expr(estate, (PLpgSQL_datum *) var, - var->default_val); - } + } + else + { + exec_assign_expr(estate, (PLpgSQL_datum *) var, + var->default_val); } } break; @@ -1065,7 +1065,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) rc = exec_stmts(estate, exception->action); free_var(state_var); + state_var->value = (Datum) 0; free_var(errm_var); + errm_var->value = (Datum) 0; break; } } @@ -4867,6 +4869,12 @@ plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid, } } +/* + * free_var --- pfree any pass-by-reference value of the variable. + * + * This should always be followed by some assignment to var->value, + * as it leaves a dangling pointer. + */ static void free_var(PLpgSQL_var *var) {