postgres.git / summary / log / commit / refs

commit    1a3d30255a4e821445927ca0949f00364de660fd
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Fri Jun 18 16:09:22 2021 +0000
First released in: 9.6.23, 10.18, 11.13, 12.8, 13.4

    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


src/backend/commands/typecmds.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 3f3d08b4df3..fb2c6f833c3 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -902,10 +902,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); @@ -2200,10 +2202,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)); @@ -3073,7 +3075,12 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, pstate->p_value_substitute = (Node *) 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. [parent: ec52b886d1dd]