• Tom Lane's avatar
    Centralize the logic for protective copying of utility statements. · 7c337b6b
    Tom Lane authored
    In the "simple Query" code path, it's fine for parse analysis or
    execution of a utility statement to scribble on the statement's node
    tree, since that'll just be thrown away afterwards.  However it's
    not fine if the node tree is in the plan cache, as then it'd be
    corrupted for subsequent executions.  Up to now we've dealt with
    that by having individual utility-statement functions apply
    copyObject() if they were going to modify the tree.  But that's
    prone to errors of omission.  Bug #17053 from Charles Samborski
    shows that CREATE/ALTER DOMAIN didn't get this memo, and can
    crash if executed repeatedly from plan cache.
    
    In the back branches, we'll just apply a narrow band-aid for that,
    but in HEAD it seems prudent to have a more principled fix that
    will close off the possibility of other similar bugs in future.
    Hence, let's hoist the responsibility for doing copyObject up into
    ProcessUtility from its children, thus ensuring that it happens for
    all utility statement types.
    
    Also, modify ProcessUtility's API so that its callers can tell it
    whether a copy step is necessary.  It turns out that in all cases,
    the immediate caller knows whether the node tree is transient, so
    this doesn't involve a huge amount of code thrashing.  In this way,
    while we lose a little bit in the execute-from-cache code path due
    to sometimes copying node trees that wouldn't be mutated anyway,
    we gain something in the simple-Query code path by not copying
    throwaway node trees.  Statements that are complex enough to be
    expensive to copy are almost certainly ones that would have to be
    copied anyway, so the loss in the cache code path shouldn't be much.
    
    (Note that this whole problem applies only to utility statements.
    Optimizable statements don't have the issue because we long ago made
    the executor treat Plan trees as read-only.  Perhaps someday we will
    make utility statement execution act likewise, but I'm not holding
    my breath.)
    
    Discussion: https://postgr.es/m/931771.1623893989@sss.pgh.pa.us
    Discussion: https://postgr.es/m/17053-3ca3f501bbc212b4@postgresql.org
    7c337b6b
view.c 16.9 KB