1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-05 09:19:17 +03:00

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
This commit is contained in:
Tom Lane 2021-06-18 12:09:22 -04:00
parent 5b6b5e5ee5
commit 102f31a208

View File

@ -846,10 +846,12 @@ DefineDomain(CreateDomainStmt *stmt)
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
/* /*
* Cook the constr->raw_expr into an expression. Note: * Cook the constr->raw_expr into an expression; copy it
* name is strictly for error message * 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, basetypeoid,
basetypeMod, basetypeMod,
domainName, domainName,
@ -2184,10 +2186,10 @@ AlterDomainDefault(List *names, Node *defaultRaw)
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
/* /*
* Cook the colDef->raw_expr into an expression. Note: Name is * Cook the raw default into an expression; copy it in case the input
* strictly for error message * is in plan cache. Note: name is used only for error messages.
*/ */
defaultExpr = cookDefault(pstate, defaultRaw, defaultExpr = cookDefault(pstate, copyObject(defaultRaw),
typTup->typbasetype, typTup->typbasetype,
typTup->typtypmod, typTup->typtypmod,
NameStr(typTup->typname), 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_pre_columnref_hook = replace_domain_constraint_value;
pstate->p_ref_hook_state = (void *) domVal; 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. * Make sure it yields a boolean result.