From d2d2489e4978366b4fb489c60d85540264ba1064 Mon Sep 17 00:00:00 2001 From: amit Date: Wed, 7 Nov 2018 10:32:14 +0900 Subject: [PATCH 2/2] Disallow creating partitions with mismatching collations for columns --- src/backend/commands/tablecmds.c | 21 +++++++++++++++++++++ src/test/regress/expected/create_table.out | 6 ++++++ src/test/regress/sql/create_table.sql | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index a0279ae383..fbf902143b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2446,6 +2446,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; @@ -2465,6 +2469,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 bfc0dc7f6d..c921c8dc36 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -744,6 +744,12 @@ DETAIL: Failing row contains (1, null). Partition of: parted_notnull_inh_test FOR VALUES IN (1) drop table parted_notnull_inh_test; +-- check that conflicting COLLATE clause for partition disallowed +create table parted_collate_must_match (a text collate "C") partition by range (a); +create table parted_collate_must_match1 partition of parted_collate_must_match (a collate "POSIX") for values from ('a') to ('z'); +ERROR: column "a" has a collation conflict +DETAIL: "POSIX" versus "C" +drop table parted_collate_must_match; -- Partition bound in describe output \d+ part_b Table "public.part_b" diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index ee49e82a62..3875b38fbd 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -662,6 +662,11 @@ insert into parted_notnull_inh_test (b) values (null); \d parted_notnull_inh_test1 drop table parted_notnull_inh_test; +-- check that conflicting COLLATE clause for partition disallowed +create table parted_collate_must_match (a text collate "C") partition by range (a); +create table parted_collate_must_match1 partition of parted_collate_must_match (a collate "POSIX") for values from ('a') to ('z'); +drop table parted_collate_must_match; + -- Partition bound in describe output \d+ part_b -- 2.11.0