Account for collation when coercing the output of a SQL function.
authorTom Lane
Tue, 14 Apr 2020 21:30:13 +0000 (17:30 -0400)
committerTom Lane
Tue, 14 Apr 2020 21:30:36 +0000 (17:30 -0400)
Commit 913bbd88d overlooked that the result of coerce_to_target_type
might need collation fixups.  Per report from Andreas Joseph Krogh.

Discussion: https://postgr.es/m/VisenaEmail.72.37d08ec2b8cb8fb5.17179940cd3@tc7-visena

src/backend/executor/functions.c
src/test/regress/expected/collate.out
src/test/regress/sql/collate.sql

index 1c387a952e32b5f23a248a208e672a74a4826e08..f940f48c6dae1605671869d0336824cd790f0bf4 100644 (file)
@@ -24,6 +24,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "parser/parse_coerce.h"
+#include "parser/parse_collate.h"
 #include "parser/parse_func.h"
 #include "storage/proc.h"
 #include "tcop/utility.h"
@@ -1989,6 +1990,7 @@ coerce_fn_result_column(TargetEntry *src_tle,
                                            -1);
        if (cast_result == NULL)
            return false;
+       assign_expr_collations(NULL, cast_result);
        src_tle->expr = (Expr *) cast_result;
        /* Make a Var referencing the possibly-modified TLE */
        new_tle_expr = (Expr *) makeVarFromTargetEntry(1, src_tle);
@@ -2007,6 +2009,7 @@ coerce_fn_result_column(TargetEntry *src_tle,
                                            -1);
        if (cast_result == NULL)
            return false;
+       assign_expr_collations(NULL, cast_result);
        /* Did the coercion actually do anything? */
        if (cast_result != (Node *) var)
            *upper_tlist_nontrivial = true;
index 0dee7d783a0c854216298d739a0e6d11f58e6692..c42ab8f7037e95e315c5db566edc461b791ddcbd 100644 (file)
@@ -536,6 +536,18 @@ SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
  3 | bbc
 (4 rows)
 
+-- result of a SQL function
+CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql
+    AS 'select $1::varchar';
+SELECT a, b FROM collate_test1 ORDER BY a, vc(b);
+ a |  b  
+---+-----
+ 1 | abc
+ 2 | Abc
+ 3 | bbc
+ 4 | ABD
+(4 rows)
+
 -- polymorphism
 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
  unnest 
@@ -682,7 +694,7 @@ SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1));
 -- must get rid of them.
 --
 DROP SCHEMA collate_tests CASCADE;
-NOTICE:  drop cascades to 17 other objects
+NOTICE:  drop cascades to 18 other objects
 DETAIL:  drop cascades to table collate_test1
 drop cascades to table collate_test_like
 drop cascades to table collate_test2
@@ -694,6 +706,7 @@ drop cascades to view collview1
 drop cascades to view collview2
 drop cascades to view collview3
 drop cascades to type testdomain
+drop cascades to function vc(text)
 drop cascades to function dup(anyelement)
 drop cascades to table collate_test20
 drop cascades to table collate_test21
index 89de26a227e92d1200234e96cb729c99fedfc67e..82f9c855b884a7a1c065fa06fa80dae834d27242 100644 (file)
@@ -177,6 +177,14 @@ SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2;
 SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
 
 
+-- result of a SQL function
+
+CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql
+    AS 'select $1::varchar';
+
+SELECT a, b FROM collate_test1 ORDER BY a, vc(b);
+
+
 -- polymorphism
 
 SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;