• Tom Lane's avatar
    Fix handling of expanded objects in CoerceToDomain and CASE execution. · cd1b2156
    Tom Lane authored
    When the input value to a CoerceToDomain expression node is a read-write
    expanded datum, we should pass a read-only pointer to any domain CHECK
    expressions and then return the original read-write pointer as the
    expression result.  Previously we were blindly passing the same pointer to
    all the consumers of the value, making it possible for a function in CHECK
    to modify or even delete the expanded value.  (Since a plpgsql function
    will absorb a passed-in read-write expanded array as a local variable
    value, it will in fact delete the value on exit.)
    
    A similar hazard of passing the same read-write pointer to multiple
    consumers exists in domain_check() and in ExecEvalCase, so fix those too.
    
    The fix requires adding MakeExpandedObjectReadOnly calls at the appropriate
    places, which is simple enough except that we need to get the data type's
    typlen from somewhere.  For the domain cases, solve this by redefining
    DomainConstraintRef.tcache as okay for callers to access; there wasn't any
    reason for the original convention against that, other than not wanting the
    API of typcache.c to be any wider than it had to be.  For CASE, there's
    no good solution except to add a syscache lookup during executor start.
    
    Per bug #14472 from Marcos Castedo.  Back-patch to 9.5 where expanded
    values were introduced.
    
    Discussion: https://postgr.es/m/15225.1482431619@sss.pgh.pa.us
    cd1b2156
domains.c 11.1 KB