Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schemadiff: temporal range partition rotation analysis and operation #17426

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions go/mysql/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ package config
const DefaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
const DefaultMySQLVersion = "8.0.30"
const LegacyMySQLVersion = "5.7.31"
const Lts84MySQLVersion = "8.4.3"
11 changes: 11 additions & 0 deletions go/mysql/datetime/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,3 +778,14 @@ func NewDateTimeFromStd(t time.Time) DateTime {
Time: NewTimeFromStd(t),
}
}

func NewDateTimeFromSeconds(seconds decimal.Decimal) DateTime {
secondsInt64, _ := seconds.Int64()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make sure to also include sub-second precision here. I would expect a general conversion function to honor that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already reverted :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to never reverse-engineer a function value; always compute forward.

timeSeconds := secondsInt64 % (24 * 3600)
tt := NewTimeFromSeconds(decimal.NewFromInt(timeSeconds))
d := DateFromDayNumber(int(secondsInt64 / (24 * 3600)))
return DateTime{
Date: d,
Time: tt,
}
}
26 changes: 26 additions & 0 deletions go/mysql/datetime/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,32 @@ func TestToSeconds(t *testing.T) {
assert.Equal(t, 63877375780, int(res))
}

func TestFromSeconds(t *testing.T) {
{
tt := NewTimeFromSeconds(decimal.NewFromInt(45020))

assert.EqualValues(t, 12, tt.Hour())
assert.EqualValues(t, 30, tt.Minute())
assert.EqualValues(t, 20, tt.Second())

res := tt.ToSeconds()
assert.Equal(t, 45020, int(res))
}
{
dt := NewDateTimeFromSeconds(decimal.NewFromInt(63877465820))

assert.EqualValues(t, 2024, dt.Date.Year())
assert.EqualValues(t, 3, dt.Date.Month())
assert.EqualValues(t, 12, dt.Date.Day())
assert.EqualValues(t, 12, dt.Time.Hour())
assert.EqualValues(t, 30, dt.Time.Minute())
assert.EqualValues(t, 20, dt.Time.Second())

res := dt.ToSeconds()
assert.Equal(t, 63877465820, int(res))
}
}

func TestToStdTime(t *testing.T) {
testCases := []struct {
year int
Expand Down
68 changes: 0 additions & 68 deletions go/vt/schemadiff/analysis.go

This file was deleted.

83 changes: 0 additions & 83 deletions go/vt/schemadiff/analysis_test.go

This file was deleted.

34 changes: 33 additions & 1 deletion go/vt/schemadiff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,9 +587,11 @@ func TestDiffSchemas(t *testing.T) {
diffs []string
cdiffs []string
expectError string
tableRename int
annotated []string
// hints:
tableRename int
fkStrategy int
rotation int
}{
{
name: "identical tables",
Expand Down Expand Up @@ -922,6 +924,35 @@ func TestDiffSchemas(t *testing.T) {
"ALTER TABLE `t` RENAME INDEX `i_idx` TO `i_alternative`",
},
},
// Partitions
{
name: "change partitioning range: statements, add",
from: "create table t1 (id int primary key) partition by range (id) (partition p1 values less than (10), partition p2 values less than (20))",
to: "create table t1 (id int primary key) partition by range (id) (partition p1 values less than (10), partition p2 values less than (20), partition p3 values less than (30))",
rotation: RangeRotationDistinctStatements,
diffs: []string{
"alter table t1 add partition (partition p3 values less than (30))",
},
cdiffs: []string{
"ALTER TABLE `t1` ADD PARTITION (PARTITION `p3` VALUES LESS THAN (30))",
},
},
{
name: "change partitioning range: statements, multiple drops, distinct",
from: "create table t1 (id int primary key) partition by range (id) (partition p1 values less than (10), partition p2 values less than (20), partition p3 values less than (30))",
to: "create table t1 (id int primary key) partition by range (id) (partition p3 values less than (30))",
rotation: RangeRotationDistinctStatements,
diffs: []string{"alter table t1 drop partition p1, p2"},
cdiffs: []string{"ALTER TABLE `t1` DROP PARTITION `p1`, `p2`"},
},
{
name: "change partitioning range: statements, multiple, assorted",
from: "create table t1 (id int primary key) partition by range (id) (partition p1 values less than (10), partition p2 values less than (20), partition p3 values less than (30))",
to: "create table t1 (id int primary key) partition by range (id) (partition p2 values less than (20), partition p3 values less than (30), partition p4 values less than (40))",
rotation: RangeRotationDistinctStatements,
diffs: []string{"alter table t1 drop partition p1", "alter table t1 add partition (partition p4 values less than (40))"},
cdiffs: []string{"ALTER TABLE `t1` DROP PARTITION `p1`", "ALTER TABLE `t1` ADD PARTITION (PARTITION `p4` VALUES LESS THAN (40))"},
},
// Views
{
name: "identical views",
Expand Down Expand Up @@ -1043,6 +1074,7 @@ func TestDiffSchemas(t *testing.T) {
hints := &DiffHints{
TableRenameStrategy: ts.tableRename,
ForeignKeyCheckStrategy: ts.fkStrategy,
RangeRotationStrategy: ts.rotation,
}
diff, err := DiffSchemasSQL(env, ts.from, ts.to, hints)
if ts.expectError != "" {
Expand Down
7 changes: 7 additions & 0 deletions go/vt/schemadiff/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ func NewTestEnv() *Environment {
}
}

func New84TestEnv() *Environment {
return &Environment{
Environment: vtenv.New84TestEnv(),
DefaultColl: collations.MySQL8().DefaultConnectionCharset(),
}
}

func NewEnv(env *vtenv.Environment, defaultColl collations.ID) *Environment {
return &Environment{
Environment: env,
Expand Down
10 changes: 10 additions & 0 deletions go/vt/schemadiff/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,16 @@ func (e *InvalidColumnInPartitionError) Error() string {
sqlescape.EscapeID(e.Column), sqlescape.EscapeID(e.Table))
}

type UnsupportedRangeColumnsTypeError struct {
Table string
Column string
Type string
}

func (e *UnsupportedRangeColumnsTypeError) Error() string {
return fmt.Sprintf("unsupported column type %s for column %s indicated by RANGE COLUMNS in table %s", e.Type, e.Column, e.Table)
}

type MissingPartitionColumnInUniqueKeyError struct {
Table string
Column string
Expand Down
21 changes: 15 additions & 6 deletions go/vt/schemadiff/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ limitations under the License.

package schemadiff

import "strings"

const (
DateFormat = "2006-01-02"
TimestampFormat = "2006-01-02 15:04:05"
TimestampFormatPrecision3 = "2006-01-02 15:04:05.000"
TimestampFormatPrecision6 = "2006-01-02 15:04:05.000000"
)

var engineCasing = map[string]string{
"INNODB": "InnoDB",
"MYISAM": "MyISAM",
Expand Down Expand Up @@ -66,29 +75,29 @@ var blobStorageExponent = map[string]int{
}

func IsFloatingPointType(columnType string) bool {
_, ok := floatTypes[columnType]
_, ok := floatTypes[strings.ToLower(columnType)]
return ok
}

func FloatingPointTypeStorage(columnType string) int {
return floatTypes[columnType]
return floatTypes[strings.ToLower(columnType)]
}

func IsIntegralType(columnType string) bool {
_, ok := integralTypes[columnType]
_, ok := integralTypes[strings.ToLower(columnType)]
return ok
}

func IntegralTypeStorage(columnType string) int {
return integralTypes[columnType]
return integralTypes[strings.ToLower(columnType)]
}

func IsDecimalType(columnType string) bool {
return decimalTypes[columnType]
return decimalTypes[strings.ToLower(columnType)]
}

func BlobTypeStorage(columnType string) int {
return blobStorageExponent[columnType]
return blobStorageExponent[strings.ToLower(columnType)]
}

// expandedDataTypes maps some known and difficult-to-compute by INFORMATION_SCHEMA data types which expand other data types.
Expand Down
Loading
Loading