aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpgsql/src/pl_exec.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index cc5eb733534..09f7a99097d 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)
{