Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdede143

Browse files
committed
Don't elide casting to typmod -1.
Casting a value that's already of a type with a specific typmodto an unspecified typmod doesn't do anything so far as run-timebehavior is concerned. However, it really ought to change theexposed type of the expression to match. Up to now,coerce_type_typmod hasn't bothered with that, which creates gotchasin contexts such as recursive unions. If for example one side ofthe union is numeric(18,3), but it needs to be plain numeric tomatch the other side, there's no direct way to express that.This is easy enough to fix, by inserting a RelabelType to update theexposed type of the expression. However, it's a bit nervous-makingto change this behavior, because it's stood for a really long time.But no complaints have emerged about 14beta3, so go ahead andback-patch.Back-patch of5c056b0 into previous supported branches.Discussion:https://postgr.es/m/CABNQVagu3bZGqiTjb31a8D5Od3fUMs7Oh3gmZMQZVHZ=uWWWfQ@mail.gmail.comDiscussion:https://postgr.es/m/1488389.1631984807@sss.pgh.pa.us
1 parent89b5676 commitdede143

File tree

3 files changed

+74
-9
lines changed

3 files changed

+74
-9
lines changed

‎src/backend/parser/parse_coerce.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,25 +755,33 @@ coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
755755
CoercionPathTypepathtype;
756756
OidfuncId;
757757

758-
/*
759-
* A negative typmod is assumed to mean that no coercion is wanted. Also,
760-
* skip coercion if already done.
761-
*/
762-
if (targetTypMod<0||targetTypMod==exprTypmod(node))
758+
/* Skip coercion if already done */
759+
if (targetTypMod==exprTypmod(node))
763760
returnnode;
764761

762+
/* Suppress display of nested coercion steps */
763+
if (hideInputCoercion)
764+
hide_coercion_node(node);
765+
765766
pathtype=find_typmod_coercion_function(targetTypeId,&funcId);
766767

767768
if (pathtype!=COERCION_PATH_NONE)
768769
{
769-
/* Suppress display of nested coercion steps */
770-
if (hideInputCoercion)
771-
hide_coercion_node(node);
772-
773770
node=build_coercion_expression(node,pathtype,funcId,
774771
targetTypeId,targetTypMod,
775772
ccontext,cformat,location);
776773
}
774+
else
775+
{
776+
/*
777+
* We don't need to perform any actual coercion step, but we should
778+
* apply a RelabelType to ensure that the expression exposes the
779+
* intended typmod.
780+
*/
781+
node=applyRelabelType(node,targetTypeId,targetTypMod,
782+
exprCollation(node),
783+
cformat,location, false);
784+
}
777785

778786
returnnode;
779787
}

‎src/test/regress/expected/expressions.out

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,40 @@ select count(*) from date_tbl
158158
12
159159
(1 row)
160160

161+
--
162+
-- Test parsing of a no-op cast to a type with unspecified typmod
163+
--
164+
begin;
165+
create table numeric_tbl (f1 numeric(18,3), f2 numeric);
166+
create view numeric_view as
167+
select
168+
f1, f1::numeric(16,4) as f1164, f1::numeric as f1n,
169+
f2, f2::numeric(16,4) as f2164, f2::numeric as f2n
170+
from numeric_tbl;
171+
\d+ numeric_view
172+
View "public.numeric_view"
173+
Column | Type | Collation | Nullable | Default | Storage | Description
174+
--------+---------------+-----------+----------+---------+---------+-------------
175+
f1 | numeric(18,3) | | | | main |
176+
f1164 | numeric(16,4) | | | | main |
177+
f1n | numeric | | | | main |
178+
f2 | numeric | | | | main |
179+
f2164 | numeric(16,4) | | | | main |
180+
f2n | numeric | | | | main |
181+
View definition:
182+
SELECT numeric_tbl.f1,
183+
numeric_tbl.f1::numeric(16,4) AS f1164,
184+
numeric_tbl.f1::numeric AS f1n,
185+
numeric_tbl.f2,
186+
numeric_tbl.f2::numeric(16,4) AS f2164,
187+
numeric_tbl.f2 AS f2n
188+
FROM numeric_tbl;
189+
190+
explain (verbose, costs off) select * from numeric_view;
191+
QUERY PLAN
192+
-------------------------------------------------------------------------------------------------------------------------------------------------------
193+
Seq Scan on public.numeric_tbl
194+
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
195+
(2 rows)
196+
197+
rollback;

‎src/test/regress/sql/expressions.sql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,23 @@ select count(*) from date_tbl
6565
where f1 not between symmetric'1997-01-01'and'1998-01-01';
6666
selectcount(*)from date_tbl
6767
where f1 not between symmetric'1997-01-01'and'1998-01-01';
68+
69+
70+
--
71+
-- Test parsing of a no-op cast to a type with unspecified typmod
72+
--
73+
begin;
74+
75+
createtablenumeric_tbl (f1numeric(18,3), f2numeric);
76+
77+
createviewnumeric_viewas
78+
select
79+
f1, f1::numeric(16,4)as f1164, f1::numericas f1n,
80+
f2, f2::numeric(16,4)as f2164, f2::numericas f2n
81+
from numeric_tbl;
82+
83+
\d+ numeric_view
84+
85+
explain (verbose, costs off)select*from numeric_view;
86+
87+
rollback;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp