diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-16 15:36:02 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-16 15:36:02 -0500 |
commit | e1fd61c8cea76f1abca8d9a790f2188534724703 (patch) | |
tree | 2db6d0fd868010e9493c1ae4520ab88f9c2e62de /src/backend | |
parent | f04aa65daf597e2f9eb1e79c553c62adbbe3b897 (diff) | |
download | postgresql-e1fd61c8cea76f1abca8d9a790f2188534724703.tar.gz postgresql-e1fd61c8cea76f1abca8d9a790f2188534724703.zip |
Ensure casting to typmod -1 generates a RelabelType.
Fix the code changed by commit 5c056b0c2 so that we always generate
RelabelType, not something else, for a cast to unspecified typmod.
Otherwise planner optimizations might not happen.
It appears we missed this point because the previous experiments were
done on type numeric: the parser undesirably generates a call on the
numeric() length-coercion function, but then numeric_support()
optimizes that down to a RelabelType, so that everything seems fine.
It misbehaves for types that have a non-optimized length coercion
function, such as bpchar.
Per report from John Naylor. Back-patch to all supported branches,
as the previous patch eventually was. Unfortunately, that no longer
includes 9.6 ... we really shouldn't put this type of change into a
nearly-EOL branch.
Discussion: https://postgr.es/m/CAFBsxsEfbFHEkouc+FSj+3K1sHipLPbEC67L0SAe-9-da8QtYg@mail.gmail.com
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/parser/parse_coerce.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 7a38226c312..8801a455722 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -760,7 +760,15 @@ coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, if (hideInputCoercion) hide_coercion_node(node); - pathtype = find_typmod_coercion_function(targetTypeId, &funcId); + /* + * A negative typmod means that no actual coercion is needed, but we still + * want a RelabelType to ensure that the expression exposes the intended + * typmod. + */ + if (targetTypMod < 0) + pathtype = COERCION_PATH_NONE; + else + pathtype = find_typmod_coercion_function(targetTypeId, &funcId); if (pathtype != COERCION_PATH_NONE) { |