On 2018/11/09 14:04, Amit Langote wrote:
> On 2018/11/09 4:39, Alvaro Herrera wrote:
>> I included the test case for collations to the three branches, but no
>> code changes.  We can patch master for the handling of collations per
>> your patch,
> 
> Okay, but should we back-patch it by adding WARNING to back-branches as
> you suggest?

I was looking at the pending patches that I'd sent and noticed this one to
throw an error when a partition specifies a collation for a column that
doesn't match the parent's.  Do we want to apply the attached rebased
patch to HEAD and leave the back-branches (10 and 11) alone?

Thanks,
Amit
From b802e96a78f1d52571c1a83dcfd9053ad32f81b8 Mon Sep 17 00:00:00 2001
From: amit <amitlangot...@gmail.com>
Date: Wed, 7 Nov 2018 10:32:14 +0900
Subject: [PATCH] Disallow creating partitions with mismatching collations for
 columns

---
 src/backend/commands/tablecmds.c           | 21 +++++++++++++++++++++
 src/test/regress/expected/create_table.out |  4 ++++
 2 files changed, 25 insertions(+)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d6d0de1b01..ec583bb74c 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2413,6 +2413,10 @@ MergeAttributes(List *schema, List *supers, char 
relpersistence,
 
                                if (strcmp(coldef->colname, restdef->colname) 
== 0)
                                {
+                                       Oid                     defTypeId;
+                                       int32           deftypmod;
+                                       Oid                     newCollId;
+
                                        found = true;
                                        coldef->is_not_null |= 
restdef->is_not_null;
 
@@ -2432,6 +2436,23 @@ MergeAttributes(List *schema, List *supers, char 
relpersistence,
                                                coldef->raw_default = 
restdef->raw_default;
                                                coldef->cooked_default = NULL;
                                        }
+
+                                       /*
+                                        * Collation must be same, so error out 
if a different one
+                                        * specified for the partition.
+                                        */
+                                       typenameTypeIdAndMod(NULL, 
coldef->typeName,
+                                                                               
 &defTypeId, &deftypmod);
+                                       newCollId = GetColumnDefCollation(NULL, 
restdef,
+                                                                               
                          defTypeId);
+                                       if (newCollId != coldef->collOid)
+                                               ereport(ERROR,
+                                                               
(errcode(ERRCODE_COLLATION_MISMATCH),
+                                                                errmsg("column 
\"%s\" has a collation conflict",
+                                                                               
coldef->colname),
+                                                                
errdetail("\"%s\" versus \"%s\"",
+                                                                               
   get_collation_name(newCollId),
+                                                                               
   get_collation_name(coldef->collOid))));
                                }
                        }
 
diff --git a/src/test/regress/expected/create_table.out 
b/src/test/regress/expected/create_table.out
index 7e52c27e3f..f3dd9d964f 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -770,9 +770,13 @@ create table parted_collate_must_match (a text collate 
"C", b text collate "C")
 -- on the partition key
 create table parted_collate_must_match1 partition of parted_collate_must_match
   (a collate "POSIX") for values from ('a') to ('m');
+ERROR:  column "a" has a collation conflict
+DETAIL:  "POSIX" versus "C"
 -- on another column
 create table parted_collate_must_match2 partition of parted_collate_must_match
   (b collate "POSIX") for values from ('m') to ('z');
+ERROR:  column "b" has a collation conflict
+DETAIL:  "POSIX" versus "C"
 drop table parted_collate_must_match;
 -- Partition bound in describe output
 \d+ part_b
-- 
2.11.0

Reply via email to