From facaf5dc17a84774595e586076e2ea1055311388 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 29 Aug 2024 07:50:10 +0300 Subject: [PATCH 1/2] schemadiff: INSTANT algorithm not supported for CHANGE COLUMN and MODIFY COLUMN which specify FIRST or AFTER Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/capability.go | 6 ++++++ go/vt/schemadiff/capability_test.go | 26 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/go/vt/schemadiff/capability.go b/go/vt/schemadiff/capability.go index 1471599d390..2acc12a4309 100644 --- a/go/vt/schemadiff/capability.go +++ b/go/vt/schemadiff/capability.go @@ -185,6 +185,9 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab } return capableOf(capabilities.InstantAddDropColumnFlavorCapability) case *sqlparser.ChangeColumn: + if opt.First || opt.After != nil { + return false, nil + } // We do not support INSTANT for renaming a column (ALTER TABLE ...CHANGE) because: // 1. We discourage column rename // 2. We do not produce CHANGE statements in declarative diff @@ -198,6 +201,9 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab } return false, nil case *sqlparser.ModifyColumn: + if opt.First || opt.After != nil { + return false, nil + } if col := findColumn(opt.NewColDefinition.Name.String()); col != nil { return changeModifyColumnCapableOfInstantDDL(col, opt.NewColDefinition) } diff --git a/go/vt/schemadiff/capability_test.go b/go/vt/schemadiff/capability_test.go index b35afb7fe22..59f30c85b3d 100644 --- a/go/vt/schemadiff/capability_test.go +++ b/go/vt/schemadiff/capability_test.go @@ -225,11 +225,23 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { expectCapableOfInstantDDL: false, }, { - name: "set column dfault value to null", + name: "set column default value to null", create: "create table t(id int, i1 int, primary key(id))", alter: "alter table t modify column i1 int default null", expectCapableOfInstantDDL: true, }, + { + name: "rearrange column after", + create: "create table t(id int, i1 int, i2 int, primary key(id))", + alter: "alter table t modify column i1 int after i2", + expectCapableOfInstantDDL: false, + }, + { + name: "rearrange column first", + create: "create table t(id int, i1 int, i2 int, primary key(id))", + alter: "alter table t modify column i1 int first", + expectCapableOfInstantDDL: false, + }, // enum/set: { name: "change enum default value", @@ -291,6 +303,18 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { alter: "alter table t1 change column i1 i2 int visible", expectCapableOfInstantDDL: false, }, + { + name: "change column, first", + create: "create table t1 (id int, i1 int, i2 int)", + alter: "alter table t1 change column i1 i1 int first", + expectCapableOfInstantDDL: false, + }, + { + name: "change column, after", + create: "create table t1 (id int, i1 int, i2 int)", + alter: "alter table t1 change column i1 i1 int after i2", + expectCapableOfInstantDDL: false, + }, { name: "make a column invisible via SET", create: "create table t1 (id int, i1 int)", From cc7b2175df79dbf7cf2c63800b87532296bf0472 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 29 Aug 2024 08:23:24 +0300 Subject: [PATCH 2/2] handle no-default DATETIME Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/capability.go | 7 +++++++ go/vt/schemadiff/capability_test.go | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/go/vt/schemadiff/capability.go b/go/vt/schemadiff/capability.go index 2acc12a4309..9a4010854d7 100644 --- a/go/vt/schemadiff/capability.go +++ b/go/vt/schemadiff/capability.go @@ -151,6 +151,13 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab // Expression default values are not supported return false, nil } + if strings.EqualFold(column.Type.Type, "datetime") { + e := &ColumnDefinitionEntity{ColumnDefinition: column} + if !e.IsNullable() && !e.HasDefault() { + // DATETIME columns must have a default value + return false, nil + } + } } if opt.First || opt.After != nil { // not a "last" column. Only supported as of 8.0.29 diff --git a/go/vt/schemadiff/capability_test.go b/go/vt/schemadiff/capability_test.go index 59f30c85b3d..ad9e0507e5a 100644 --- a/go/vt/schemadiff/capability_test.go +++ b/go/vt/schemadiff/capability_test.go @@ -133,6 +133,24 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { alter: "alter table t add column i2 int generated always as (i1 + 1) virtual", expectCapableOfInstantDDL: true, }, + { + name: "add nullable datetime column", + create: "create table t(id int, i1 int not null, primary key(id))", + alter: "alter table t add column dt datetime(3)", + expectCapableOfInstantDDL: true, + }, + { + name: "add default null datetime column", + create: "create table t(id int, i1 int not null, primary key(id))", + alter: "alter table t add column dt datetime(3) default null", + expectCapableOfInstantDDL: true, + }, + { + name: "add datetime column without default", + create: "create table t(id int, i1 int not null, primary key(id))", + alter: "alter table t add column dt datetime(3) not null", + expectCapableOfInstantDDL: false, + }, { name: "add stored column", create: "create table t(id int, i1 int not null, primary key(id))",