Skip to content

Commit

Permalink
schemadiff: normalize missing column collation
Browse files Browse the repository at this point in the history
Signed-off-by: Shlomi Noach <[email protected]>
  • Loading branch information
shlomi-noach committed May 22, 2024
1 parent 3cb9b37 commit 38bc519
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
15 changes: 14 additions & 1 deletion go/vt/schemadiff/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ func (c *ColumnDefinitionEntity) ColumnDiff(
) (*ModifyColumnDiff, error) {
if c.IsTextual() || other.IsTextual() {
// We will now denormalize the columns charset & collate as needed (if empty, populate from table.)

if c.columnDefinition.Type.Charset.Name != "" && c.columnDefinition.Type.Options.Collate == "" {
collation := env.CollationEnv().DefaultCollationForCharset(c.columnDefinition.Type.Charset.Name)
if collation == collations.Unknown {
return nil, &UnknownColumnCharsetCollationError{Column: c.columnDefinition.Name.String(), Charset: t1cc.charset}
}
c.columnDefinition.Type.Options.Collate = env.CollationEnv().LookupName(collation)
}
if c.columnDefinition.Type.Charset.Name == "" && c.columnDefinition.Type.Options.Collate != "" {
// Column has explicit collation but no charset. We can infer the charset from the collation.
collationID := env.CollationEnv().LookupByName(c.columnDefinition.Type.Options.Collate)
Expand Down Expand Up @@ -137,6 +143,13 @@ func (c *ColumnDefinitionEntity) ColumnDiff(
c.columnDefinition.Type.Options.Collate = env.CollationEnv().LookupName(collation)
}
}
if other.columnDefinition.Type.Charset.Name != "" && other.columnDefinition.Type.Options.Collate == "" {
collation := env.CollationEnv().DefaultCollationForCharset(other.columnDefinition.Type.Charset.Name)
if collation == collations.Unknown {
return nil, &UnknownColumnCharsetCollationError{Column: other.columnDefinition.Name.String(), Charset: t1cc.charset}
}
other.columnDefinition.Type.Options.Collate = env.CollationEnv().LookupName(collation)
}
if other.columnDefinition.Type.Charset.Name == "" && other.columnDefinition.Type.Options.Collate != "" {
// Column has explicit collation but no charset. We can infer the charset from the collation.
collationID := env.CollationEnv().LookupByName(other.columnDefinition.Type.Options.Collate)
Expand Down
25 changes: 25 additions & 0 deletions go/vt/schemadiff/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,26 @@ func TestCreateTableDiff(t *testing.T) {
from: "create table t (id int primary key, v varchar(64) character set utf8mb3 collate utf8mb3_bin)",
to: "create table t (id int primary key, v varchar(64) collate utf8mb3_bin)",
},
{
name: "ignore identical implicit ascii charset",
from: "create table t (id int primary key, v varchar(64) character set ascii collate ascii_general_ci)",
to: "create table t (id int primary key, v varchar(64) collate ascii_general_ci)",
},
{
name: "ignore identical implicit collation",
from: "create table t (id int primary key, v varchar(64) character set utf8mb3 collate utf8mb3_general_ci)",
to: "create table t (id int primary key, v varchar(64) character set utf8mb3)",
},
{
name: "ignore identical implicit collation, reverse",
from: "create table t (id int primary key, v varchar(64) character set utf8mb3)",
to: "create table t (id int primary key, v varchar(64) character set utf8mb3 collate utf8mb3_general_ci)",
},
{
name: "ignore identical implicit ascii collation",
from: "create table t (id int primary key, v varchar(64) character set ascii collate ascii_general_ci)",
to: "create table t (id int primary key, v varchar(64) character set ascii)",
},
{
name: "normalized unsigned attribute",
from: "create table t1 (id int primary key)",
Expand Down Expand Up @@ -2925,6 +2945,11 @@ func TestNormalize(t *testing.T) {
from: "create table t (id int primary key, v varchar(255) charset utf8mb4 collate utf8mb4_german2_ci)",
to: "CREATE TABLE `t` (\n\t`id` int,\n\t`v` varchar(255) COLLATE utf8mb4_german2_ci,\n\tPRIMARY KEY (`id`)\n)",
},
{
name: "ascii charset and collation",
from: "create table t (id int primary key, v varchar(255) charset ascii collate ascii_general_ci) charset utf8mb3 collate utf8_general_ci",
to: "CREATE TABLE `t` (\n\t`id` int,\n\t`v` varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci,\n\tPRIMARY KEY (`id`)\n) CHARSET utf8mb3,\n COLLATE utf8mb3_general_ci",
},
{
name: "correct case table options for engine",
from: "create table t (id int signed primary key) engine innodb",
Expand Down

0 comments on commit 38bc519

Please sign in to comment.