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

Commitac7a5a3

Browse files
committed
Fix coerce_to_target_type for coerce_type's klugy handling of COLLATE.
Because coerce_type recurses into the argument of a CollateExpr,coerce_to_target_type's longstanding code for detecting whether coerce_typehad actually done anything (to wit, returned a different node than itpassed in) was broken in 9.1. This resulted in unexpected failures inhide_coercion_node; which was not the latter's fault, since it's criticalthat we never call it on anything that wasn't inserted by coerce_type.(Else we might decide to "hide" a user-written function call.)Fix by removing and replacing the CollateExpr in coerce_to_target_typeitself. This is all pretty ugly but I don't immediately see a way to makeit nicer.Per report from Jean-Yves F. Barbier.
1 parenta8ab8d0 commitac7a5a3

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

‎src/backend/parser/parse_coerce.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,24 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
7979
intlocation)
8080
{
8181
Node*result;
82+
Node*origexpr;
8283

8384
if (!can_coerce_type(1,&exprtype,&targettype,ccontext))
8485
returnNULL;
8586

87+
/*
88+
* If the input has a CollateExpr at the top, strip it off, perform the
89+
* coercion, and put a new one back on. This is annoying since it
90+
* duplicates logic in coerce_type, but if we don't do this then it's too
91+
* hard to tell whether coerce_type actually changed anything, and we
92+
* *must* know that to avoid possibly calling hide_coercion_node on
93+
* something that wasn't generated by coerce_type. Note that if there are
94+
* multiple stacked CollateExprs, we just discard all but the topmost.
95+
*/
96+
origexpr=expr;
97+
while (expr&&IsA(expr,CollateExpr))
98+
expr= (Node*) ((CollateExpr*)expr)->arg;
99+
86100
result=coerce_type(pstate,expr,exprtype,
87101
targettype,targettypmod,
88102
ccontext,cformat,location);
@@ -98,6 +112,18 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
98112
(cformat!=COERCE_IMPLICIT_CAST),
99113
(result!=expr&& !IsA(result,Const)));
100114

115+
if (expr!=origexpr)
116+
{
117+
/* Reinstall top CollateExpr */
118+
CollateExpr*coll= (CollateExpr*)origexpr;
119+
CollateExpr*newcoll=makeNode(CollateExpr);
120+
121+
newcoll->arg= (Expr*)result;
122+
newcoll->collOid=coll->collOid;
123+
newcoll->location=coll->location;
124+
result= (Node*)newcoll;
125+
}
126+
101127
returnresult;
102128
}
103129

@@ -318,7 +344,7 @@ coerce_type(ParseState *pstate, Node *node,
318344
* If we have a COLLATE clause, we have to push the coercion
319345
* underneath the COLLATE.This is really ugly, but there is little
320346
* choice because the above hacks on Consts and Params wouldn't happen
321-
* otherwise.
347+
* otherwise. This kluge has consequences in coerce_to_target_type.
322348
*/
323349
CollateExpr*coll= (CollateExpr*)node;
324350
CollateExpr*newcoll=makeNode(CollateExpr);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20;
574574
RESET enable_seqscan;
575575
RESET enable_hashjoin;
576576
RESET enable_nestloop;
577+
-- 9.1 bug with useless COLLATE in an expression subject to length coercion
578+
CREATE TEMP TABLE vctable (f1 varchar(25));
579+
INSERT INTO vctable VALUES ('foo' COLLATE "C");
577580
--
578581
-- Clean up. Many of these table names will be re-used if the user is
579582
-- trying to run any platform-specific collation tests later, so we

‎src/test/regress/sql/collate.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ RESET enable_seqscan;
214214
RESET enable_hashjoin;
215215
RESET enable_nestloop;
216216

217+
-- 9.1 bug with useless COLLATE in an expression subject to length coercion
218+
219+
CREATE TEMP TABLE vctable (f1varchar(25));
220+
INSERT INTO vctableVALUES ('foo' COLLATE"C");
221+
217222
--
218223
-- Clean up. Many of these table names will be re-used if the user is
219224
-- trying to run any platform-specific collation tests later, so we

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp