Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9c356f4

Browse files
committed
Ensure casting to typmod -1 generates a RelabelType.
Fix the code changed by commit 5c056b0 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
1 parent cf0cab8 commit 9c356f4

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

src/backend/parser/parse_coerce.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,15 @@ coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
766766
if (hideInputCoercion)
767767
hide_coercion_node(node);
768768

769-
pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
769+
/*
770+
* A negative typmod means that no actual coercion is needed, but we still
771+
* want a RelabelType to ensure that the expression exposes the intended
772+
* typmod.
773+
*/
774+
if (targetTypMod < 0)
775+
pathtype = COERCION_PATH_NONE;
776+
else
777+
pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
770778

771779
if (pathtype != COERCION_PATH_NONE)
772780
{

src/test/regress/expected/expressions.out

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,42 @@ explain (verbose, costs off) select * from numeric_view;
194194
Output: numeric_tbl.f1, (numeric_tbl.f1)::numeric(16,4), (numeric_tbl.f1)::numeric, numeric_tbl.f2, (numeric_tbl.f2)::numeric(16,4), numeric_tbl.f2
195195
(2 rows)
196196

197+
-- bpchar, lacking planner support for its length coercion function,
198+
-- could behave differently
199+
create table bpchar_tbl (f1 character(16) unique, f2 bpchar);
200+
create view bpchar_view as
201+
select
202+
f1, f1::character(14) as f114, f1::bpchar as f1n,
203+
f2, f2::character(14) as f214, f2::bpchar as f2n
204+
from bpchar_tbl;
205+
\d+ bpchar_view
206+
View "public.bpchar_view"
207+
Column | Type | Collation | Nullable | Default | Storage | Description
208+
--------+---------------+-----------+----------+---------+----------+-------------
209+
f1 | character(16) | | | | extended |
210+
f114 | character(14) | | | | extended |
211+
f1n | bpchar | | | | extended |
212+
f2 | bpchar | | | | extended |
213+
f214 | character(14) | | | | extended |
214+
f2n | bpchar | | | | extended |
215+
View definition:
216+
SELECT bpchar_tbl.f1,
217+
bpchar_tbl.f1::character(14) AS f114,
218+
bpchar_tbl.f1::bpchar AS f1n,
219+
bpchar_tbl.f2,
220+
bpchar_tbl.f2::character(14) AS f214,
221+
bpchar_tbl.f2 AS f2n
222+
FROM bpchar_tbl;
223+
224+
explain (verbose, costs off) select * from bpchar_view
225+
where f1::bpchar = 'foo';
226+
QUERY PLAN
227+
------------------------------------------------------------------------------------------------------------------------------------------------
228+
Index Scan using bpchar_tbl_f1_key on public.bpchar_tbl
229+
Output: bpchar_tbl.f1, (bpchar_tbl.f1)::character(14), (bpchar_tbl.f1)::bpchar, bpchar_tbl.f2, (bpchar_tbl.f2)::character(14), bpchar_tbl.f2
230+
Index Cond: ((bpchar_tbl.f1)::bpchar = 'foo'::bpchar)
231+
(3 rows)
232+
197233
rollback;
198234
--
199235
-- Tests for ScalarArrayOpExpr with a hashfn

src/test/regress/sql/expressions.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ create view numeric_view as
8484

8585
explain (verbose, costs off) select * from numeric_view;
8686

87+
-- bpchar, lacking planner support for its length coercion function,
88+
-- could behave differently
89+
90+
create table bpchar_tbl (f1 character(16) unique, f2 bpchar);
91+
92+
create view bpchar_view as
93+
select
94+
f1, f1::character(14) as f114, f1::bpchar as f1n,
95+
f2, f2::character(14) as f214, f2::bpchar as f2n
96+
from bpchar_tbl;
97+
98+
\d+ bpchar_view
99+
100+
explain (verbose, costs off) select * from bpchar_view
101+
where f1::bpchar = 'foo';
102+
87103
rollback;
88104

89105

0 commit comments

Comments
 (0)