Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a19002d

Browse files
committed
Adjust collation determination rules as per discussion.
Remove crude hack that tried to propagate collation through a function-returning-record, ie, from the function's arguments to individual fields selected from its result record. That is just plain inconsistent, because the function result is composite and cannot have a collation; and there's no hope of making this kind of action-at-a-distance work consistently. Adjust regression test cases that expected this to happen. Meanwhile, the behavior of casting to a domain with a declared collation stays the same as it was, since that seemed to be the consensus.
1 parent 7c76906 commit a19002d

File tree

7 files changed

+59
-76
lines changed

7 files changed

+59
-76
lines changed

src/backend/parser/parse_collate.c

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,11 @@ assign_collations_walker(Node *node, assign_collations_context *context)
289289
case T_FieldSelect:
290290
{
291291
/*
292-
* FieldSelect is a special case because the field may have
293-
* a non-default collation, in which case we should use that.
294-
* The field's collation was already looked up and saved
295-
* in the node.
292+
* For FieldSelect, the result has the field's declared
293+
* collation, independently of what happened in the arguments.
294+
* (The immediate argument must be composite and thus not
295+
* collatable, anyhow.) The field's collation was already
296+
* looked up and saved in the node.
296297
*/
297298
FieldSelect *expr = (FieldSelect *) node;
298299

@@ -304,24 +305,6 @@ assign_collations_walker(Node *node, assign_collations_context *context)
304305
if (OidIsValid(expr->resultcollid))
305306
{
306307
/* Node's result type is collatable. */
307-
if (expr->resultcollid == DEFAULT_COLLATION_OID)
308-
{
309-
/*
310-
* The immediate input node necessarily yields a
311-
* composite type, so it will have no exposed
312-
* collation. However, if we are selecting a field
313-
* from a function returning composite, see if we
314-
* can bubble up a collation from the function's
315-
* input. XXX this is a bit of a hack, rethink ...
316-
*/
317-
if (IsA(expr->arg, FuncExpr))
318-
{
319-
FuncExpr *fexpr = (FuncExpr *) expr->arg;
320-
321-
if (OidIsValid(fexpr->inputcollid))
322-
expr->resultcollid = fexpr->inputcollid;
323-
}
324-
}
325308
/* Pass up field's collation as an implicit choice. */
326309
collation = expr->resultcollid;
327310
strength = COLLATE_IMPLICIT;

src/backend/parser/parse_func.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,7 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg,
13841384
fselect->fieldnum = i + 1;
13851385
fselect->resulttype = att->atttypid;
13861386
fselect->resulttypmod = att->atttypmod;
1387-
/* resultcollid may get overridden by parse_collate.c */
1387+
/* save attribute's collation for parse_collate.c */
13881388
fselect->resultcollid = att->attcollation;
13891389
return (Node *) fselect;
13901390
}

src/backend/parser/parse_target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ ExpandRowReference(ParseState *pstate, Node *expr,
12901290
fselect->fieldnum = i + 1;
12911291
fselect->resulttype = att->atttypid;
12921292
fselect->resulttypmod = att->atttypmod;
1293-
/* resultcollid may get overridden by parse_collate.c */
1293+
/* save attribute's collation for parse_collate.c */
12941294
fselect->resultcollid = att->attcollation;
12951295

12961296
if (targetlist)

src/test/regress/expected/collate.linux.utf8.out

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -771,33 +771,33 @@ SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER
771771
äbc
772772
(4 rows)
773773

774-
CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
775-
AS 'select $1, array[$1,$1]' LANGUAGE sql;
776-
SELECT a, (dup(b)).* FROM collate_test1 ORDER BY 2;
777-
a | f2 | f3
778-
---+-----+-----------
779-
1 | abc | {abc,abc}
780-
4 | ABC | {ABC,ABC}
781-
2 | äbc | {äbc,äbc}
782-
3 | bbc | {bbc,bbc}
783-
(4 rows)
784-
785-
SELECT a, (dup(b)).* FROM collate_test2 ORDER BY 2;
786-
a | f2 | f3
787-
---+-----+-----------
788-
1 | abc | {abc,abc}
789-
4 | ABC | {ABC,ABC}
790-
3 | bbc | {bbc,bbc}
791-
2 | äbc | {äbc,äbc}
792-
(4 rows)
793-
794-
SELECT a, (dup(b)).* FROM collate_test3 ORDER BY 2;
795-
a | f2 | f3
796-
---+-----+-----------
797-
4 | ABC | {ABC,ABC}
798-
1 | abc | {abc,abc}
799-
3 | bbc | {bbc,bbc}
800-
2 | äbc | {äbc,äbc}
774+
CREATE FUNCTION dup (anyelement) RETURNS anyelement
775+
AS 'select $1' LANGUAGE sql;
776+
SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
777+
a | dup
778+
---+-----
779+
1 | abc
780+
4 | ABC
781+
2 | äbc
782+
3 | bbc
783+
(4 rows)
784+
785+
SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
786+
a | dup
787+
---+-----
788+
1 | abc
789+
4 | ABC
790+
3 | bbc
791+
2 | äbc
792+
(4 rows)
793+
794+
SELECT a, dup(b) FROM collate_test3 ORDER BY 2;
795+
a | dup
796+
---+-----
797+
4 | ABC
798+
1 | abc
799+
3 | bbc
800+
2 | äbc
801801
(4 rows)
802802

803803
-- indexes

src/test/regress/expected/collate.out

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -502,24 +502,24 @@ SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER
502502
bbc
503503
(4 rows)
504504

505-
CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
506-
AS 'select $1, array[$1,$1]' LANGUAGE sql;
507-
SELECT a, (dup(b)).* FROM collate_test1 ORDER BY 2;
508-
a | f2 | f3
509-
---+-----+-----------
510-
4 | ABD | {ABD,ABD}
511-
2 | Abc | {Abc,Abc}
512-
1 | abc | {abc,abc}
513-
3 | bbc | {bbc,bbc}
505+
CREATE FUNCTION dup (anyelement) RETURNS anyelement
506+
AS 'select $1' LANGUAGE sql;
507+
SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
508+
a | dup
509+
---+-----
510+
4 | ABD
511+
2 | Abc
512+
1 | abc
513+
3 | bbc
514514
(4 rows)
515515

516-
SELECT a, (dup(b)).* FROM collate_test2 ORDER BY 2;
517-
a | f2 | f3
518-
---+-----+-----------
519-
4 | ABD | {ABD,ABD}
520-
2 | Abc | {Abc,Abc}
521-
1 | abc | {abc,abc}
522-
3 | bbc | {bbc,bbc}
516+
SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
517+
a | dup
518+
---+-----
519+
4 | ABD
520+
2 | Abc
521+
1 | abc
522+
3 | bbc
523523
(4 rows)
524524

525525
-- indexes

src/test/regress/sql/collate.linux.utf8.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,12 @@ SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER
242242
SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
243243
SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1;
244244

245-
CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
246-
AS 'select $1, array[$1,$1]' LANGUAGE sql;
245+
CREATE FUNCTION dup (anyelement) RETURNS anyelement
246+
AS 'select $1' LANGUAGE sql;
247247

248-
SELECT a, (dup(b)).* FROM collate_test1 ORDER BY 2;
249-
SELECT a, (dup(b)).* FROM collate_test2 ORDER BY 2;
250-
SELECT a, (dup(b)).* FROM collate_test3 ORDER BY 2;
248+
SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
249+
SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
250+
SELECT a, dup(b) FROM collate_test3 ORDER BY 2;
251251

252252

253253
-- indexes

src/test/regress/sql/collate.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
168168
SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
169169
SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
170170

171-
CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
172-
AS 'select $1, array[$1,$1]' LANGUAGE sql;
171+
CREATE FUNCTION dup (anyelement) RETURNS anyelement
172+
AS 'select $1' LANGUAGE sql;
173173

174-
SELECT a, (dup(b)).* FROM collate_test1 ORDER BY 2;
175-
SELECT a, (dup(b)).* FROM collate_test2 ORDER BY 2;
174+
SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
175+
SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
176176

177177

178178
-- indexes

0 commit comments

Comments
 (0)