aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-06-18 12:09:22 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-06-18 12:09:22 -0400
commit102f31a208b85aec542fc93f73a222d98d551694 (patch)
tree3ee848363186c948152885f285d8a56e33a2a251
parent5b6b5e5ee598ced2dc8e1d08a34d499860a4d15b (diff)
downloadpostgresql-102f31a208b85aec542fc93f73a222d98d551694.tar.gz
postgresql-102f31a208b85aec542fc93f73a222d98d551694.zip
Avoid scribbling on input node tree in CREATE/ALTER DOMAIN.
This works fine in the "simple Query" code path; but if the statement is in the plan cache then it's corrupted for future re-execution. Apply copyObject() to protect the original tree from modification, as we've done elsewhere. This narrow fix is applied only to the back branches. In HEAD, the problem was fixed more generally by commit 7c337b6b5; but that changed ProcessUtility's API, so it's infeasible to back-patch. Per bug #17053 from Charles Samborski. Discussion: https://postgr.es/m/931771.1623893989@sss.pgh.pa.us Discussion: https://postgr.es/m/17053-3ca3f501bbc212b4@postgresql.org
-rw-r--r--src/backend/commands/typecmds.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 483bb65ddc8..05158246fba 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -846,10 +846,12 @@ DefineDomain(CreateDomainStmt *stmt)
pstate = make_parsestate(NULL);
/*
- * Cook the constr->raw_expr into an expression. Note:
- * name is strictly for error message
+ * Cook the constr->raw_expr into an expression; copy it
+ * in case the input is in plan cache. Note: name is used
+ * only for error messages.
*/
- defaultExpr = cookDefault(pstate, constr->raw_expr,
+ defaultExpr = cookDefault(pstate,
+ copyObject(constr->raw_expr),
basetypeoid,
basetypeMod,
domainName,
@@ -2184,10 +2186,10 @@ AlterDomainDefault(List *names, Node *defaultRaw)
pstate = make_parsestate(NULL);
/*
- * Cook the colDef->raw_expr into an expression. Note: Name is
- * strictly for error message
+ * Cook the raw default into an expression; copy it in case the input
+ * is in plan cache. Note: name is used only for error messages.
*/
- defaultExpr = cookDefault(pstate, defaultRaw,
+ defaultExpr = cookDefault(pstate, copyObject(defaultRaw),
typTup->typbasetype,
typTup->typtypmod,
NameStr(typTup->typname),
@@ -3069,7 +3071,12 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
pstate->p_pre_columnref_hook = replace_domain_constraint_value;
pstate->p_ref_hook_state = (void *) domVal;
- expr = transformExpr(pstate, constr->raw_expr, EXPR_KIND_DOMAIN_CHECK);
+ /*
+ * Transform the expression; first we must copy the input, in case it's in
+ * plan cache.
+ */
+ expr = transformExpr(pstate, copyObject(constr->raw_expr),
+ EXPR_KIND_DOMAIN_CHECK);
/*
* Make sure it yields a boolean result.