From 4c6a244de6c0ee0d6e07a1ad7a71c4d2f317a4d7 Mon Sep 17 00:00:00 2001 From: NirnayaSindhuSuthari Date: Tue, 6 Aug 2024 18:22:32 +0000 Subject: [PATCH 1/2] Default Value Struct changes (#883) * Default Values struct Changes * corrected test * corrected few nits * test correction * correction of test files --- schema/schema.go | 19 +++++++++---- sources/mysql/infoschema.go | 23 ++++++++++----- sources/mysql/infoschema_test.go | 48 +++++++++++++++++++------------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/schema/schema.go b/schema/schema.go index 48b125bba5..4f4dedb238 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -49,12 +49,13 @@ type Table struct { // Column represents a database column. // TODO: add support for foreign keys. type Column struct { - Name string - Type Type - NotNull bool - Ignored Ignored - Id string - AutoGen ddl.AutoGenCol + Name string + Type Type + NotNull bool + Ignored Ignored + Id string + AutoGen ddl.AutoGenCol + DefaultValue DefaultValue } // ForeignKey represents a foreign key. @@ -122,6 +123,12 @@ type Ignored struct { AutoIncrement bool } +// DefaultValue represents a Default value. +type DefaultValue struct { + IsPresent bool + Value string +} + // Print converts ty to a string suitable for printing. func (ty Type) Print() string { s := ty.Name diff --git a/sources/mysql/infoschema.go b/sources/mysql/infoschema.go index 7b4fcdd6d4..576a25a6e7 100644 --- a/sources/mysql/infoschema.go +++ b/sources/mysql/infoschema.go @@ -204,7 +204,7 @@ func (isi InfoSchemaImpl) GetColumns(conv *internal.Conv, table common.SchemaAnd // Nothing to do here -- these are all handled elsewhere. } } - ignored.Default = colDefault.Valid + ignored.Default = false colId := internal.GenerateColumnId() if colExtra.String == "auto_increment" { sequence := createSequence(conv) @@ -219,13 +219,22 @@ func (isi InfoSchemaImpl) GetColumns(conv *internal.Conv, table common.SchemaAnd } else { colAutoGen = ddl.AutoGenCol{} } + defaultVal := schema.DefaultValue{ + IsPresent: colDefault.Valid, + Value: "", + } + if colDefault.Valid { + defaultVal.Value = colDefault.String + } + c := schema.Column{ - Id: colId, - Name: colName, - Type: toType(dataType, columnType, charMaxLen, numericPrecision, numericScale), - NotNull: common.ToNotNull(conv, isNullable), - Ignored: ignored, - AutoGen: colAutoGen, + Id: colId, + Name: colName, + Type: toType(dataType, columnType, charMaxLen, numericPrecision, numericScale), + NotNull: common.ToNotNull(conv, isNullable), + Ignored: ignored, + AutoGen: colAutoGen, + DefaultValue: defaultVal, } colDefs[colId] = c colIds = append(colIds, colId) diff --git a/sources/mysql/infoschema_test.go b/sources/mysql/infoschema_test.go index a61c045807..b78090c837 100644 --- a/sources/mysql/infoschema_test.go +++ b/sources/mysql/infoschema_test.go @@ -71,7 +71,8 @@ func TestProcessSchemaMYSQL(t *testing.T) { rows: [][]driver.Value{ {"user_id", "text", "text", "NO", nil, nil, nil, nil, nil}, {"name", "text", "text", "NO", nil, nil, nil, nil, nil}, - {"ref", "bigint", "bigint", "NO", nil, nil, nil, nil, nil}}, + {"ref", "bigint", "bigint", "NO", nil, nil, nil, nil, nil}, + {"defval_1", "varchar", "varchar", "YES", "John", nil, nil, nil, nil}}, }, // db call to fetch index happens after fetching of column { @@ -101,7 +102,8 @@ func TestProcessSchemaMYSQL(t *testing.T) { rows: [][]driver.Value{ {"productid", "text", "text", "NO", nil, nil, nil, nil, nil}, {"userid", "text", "text", "NO", nil, nil, nil, nil, nil}, - {"quantity", "bigint", "bigint", "YES", nil, nil, 64, 0, nil}}, + {"quantity", "bigint", "bigint", "YES", nil, nil, 64, 0, nil}, + {"defval_2", "varchar", "varchar", "YES", "John", nil, nil, nil, nil}}, }, // db call to fetch index happens after fetching of column { @@ -131,7 +133,8 @@ func TestProcessSchemaMYSQL(t *testing.T) { cols: []string{"column_name", "data_type", "column_type", "is_nullable", "column_default", "character_maximum_length", "numeric_precision", "numeric_scale", "extra"}, rows: [][]driver.Value{ {"product_id", "text", "text", "NO", nil, nil, nil, nil, nil}, - {"product_name", "text", "text", "NO", nil, nil, nil, nil, nil}}, + {"product_name", "text", "text", "NO", nil, nil, nil, nil, nil}, + {"defval_3", "varchar", "varchar", "YES", "John", nil, nil, nil, nil}}, }, // db call to fetch index happens after fetching of column { @@ -174,7 +177,8 @@ func TestProcessSchemaMYSQL(t *testing.T) { {"ts", "datetime", "datetime", "YES", nil, nil, nil, nil, nil}, {"tz", "timestamp", "timestamp", "YES", nil, nil, nil, nil, nil}, {"vc", "varchar", "varchar", "YES", nil, nil, nil, nil, nil}, - {"vc6", "varchar", "varchar(6)", "YES", nil, 6, nil, nil, nil}}, + {"vc6", "varchar", "varchar(6)", "YES", nil, 6, nil, nil, nil}, + {"def", "varchar", "varchar", "YES", "John", nil, nil, nil, nil}}, }, // db call to fetch index happens after fetching of column { @@ -200,7 +204,8 @@ func TestProcessSchemaMYSQL(t *testing.T) { rows: [][]driver.Value{ {"ref_id", "bigint", "bigint", "NO", nil, nil, 64, 0, nil}, {"ref_txt", "text", "text", "NO", nil, nil, nil, nil, nil}, - {"abc", "text", "text", "NO", nil, nil, nil, nil, nil}}, + {"abc", "text", "text", "NO", nil, nil, nil, nil, nil}, + {"defval_4", "varchar", "varchar", "YES", "John", nil, nil, nil, nil}}, }, // db call to fetch index happens after fetching of column { @@ -216,24 +221,26 @@ func TestProcessSchemaMYSQL(t *testing.T) { _, err := commonInfoSchema.GenerateSrcSchema(conv, isi, 1) assert.Nil(t, err) expectedSchema := map[string]schema.Table{ - "cart": schema.Table{Name: "cart", Schema: "test", ColIds: []string{"productid", "userid", "quantity"}, ColDefs: map[string]schema.Column{ + "cart": schema.Table{Name: "cart", Schema: "test", ColIds: []string{"productid", "userid", "quantity", "defval_2"}, ColDefs: map[string]schema.Column{ "productid": schema.Column{Name: "productid", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "quantity": schema.Column{Name: "quantity", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "userid": schema.Column{Name: "userid", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}}, + "userid": schema.Column{Name: "userid", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "defval_2": schema.Column{Name: "defval_2", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "John"}}}, PrimaryKeys: []schema.Key{schema.Key{ColId: "productid", Desc: false, Order: 0}, schema.Key{ColId: "userid", Desc: false, Order: 0}}, ForeignKeys: []schema.ForeignKey{schema.ForeignKey{Name: "fk_test2", ColIds: []string{"productid"}, ReferTableId: "product", ReferColumnIds: []string{"product_id"}, OnDelete: constants.FK_NO_ACTION, OnUpdate: constants.FK_NO_ACTION, Id: ""}, schema.ForeignKey{Name: "fk_test3", ColIds: []string{"userid"}, ReferTableId: "user", ReferColumnIds: []string{"user_id"}, OnUpdate: constants.FK_SET_NULL, OnDelete: constants.FK_RESTRICT, Id: ""}}, Indexes: []schema.Index{schema.Index{Name: "index1", Unique: true, Keys: []schema.Key{schema.Key{ColId: "userid", Desc: false, Order: 0}}, Id: "", StoredColumnIds: []string(nil)}, schema.Index{Name: "index2", Unique: false, Keys: []schema.Key{schema.Key{ColId: "userid", Desc: false, Order: 0}, schema.Key{ColId: "productid", Desc: true, Order: 0}}, Id: "", StoredColumnIds: []string(nil)}, schema.Index{Name: "index3", Unique: true, Keys: []schema.Key{schema.Key{ColId: "productid", Desc: false, Order: 0}, schema.Key{ColId: "userid", Desc: true, Order: 0}}, Id: "", StoredColumnIds: []string(nil)}}, Id: ""}, - "product": schema.Table{Name: "product", Schema: "test", ColIds: []string{"product_id", "product_name"}, ColDefs: map[string]schema.Column{ + "product": schema.Table{Name: "product", Schema: "test", ColIds: []string{"product_id", "product_name", "defval_3"}, ColDefs: map[string]schema.Column{ "product_id": schema.Column{Name: "product_id", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "product_name": schema.Column{Name: "product_name", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}}, + "product_name": schema.Column{Name: "product_name", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "defval_3": schema.Column{Name: "defval_3", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "John"}}}, PrimaryKeys: []schema.Key{schema.Key{ColId: "product_id", Desc: false, Order: 0}}, ForeignKeys: []schema.ForeignKey(nil), Indexes: []schema.Index(nil), Id: ""}, - "test": schema.Table{Name: "test", Schema: "test", ColIds: []string{"id", "s", "txt", "b", "bs", "bl", "c", "c8", "d", "dec", "f8", "f4", "i8", "i4", "i2", "si", "ts", "tz", "vc", "vc6"}, ColDefs: map[string]schema.Column{ + "test": schema.Table{Name: "test", Schema: "test", ColIds: []string{"id", "s", "txt", "b", "bs", "bl", "c", "c8", "d", "dec", "f8", "f4", "i8", "i4", "i2", "si", "ts", "tz", "vc", "vc6", "def"}, ColDefs: map[string]schema.Column{ "b": schema.Column{Name: "b", Type: schema.Type{Name: "boolean", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "bl": schema.Column{Name: "bl", Type: schema.Type{Name: "blob", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "bs": schema.Column{Name: "bs", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: true, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "bs": schema.Column{Name: "bs", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "nextval('test11_bs_seq'::regclass)"}}, "c": schema.Column{Name: "c", Type: schema.Type{Name: "char", Mods: []int64{1}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "c8": schema.Column{Name: "c8", Type: schema.Type{Name: "char", Mods: []int64{8}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "d": schema.Column{Name: "d", Type: schema.Type{Name: "date", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, @@ -241,30 +248,33 @@ func TestProcessSchemaMYSQL(t *testing.T) { "f4": schema.Column{Name: "f4", Type: schema.Type{Name: "float", Mods: []int64{24}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "f8": schema.Column{Name: "f8", Type: schema.Type{Name: "double", Mods: []int64{53}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "i2": schema.Column{Name: "i2", Type: schema.Type{Name: "smallint", Mods: []int64{16}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "i4": schema.Column{Name: "i4", Type: schema.Type{Name: "integer", Mods: []int64{32}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", AutoGen: ddl.AutoGenCol{Name: "Sequence34", GenerationType: constants.AUTO_INCREMENT}}, + "i4": schema.Column{Name: "i4", Type: schema.Type{Name: "integer", Mods: []int64{32}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", AutoGen: ddl.AutoGenCol{Name: "Sequence37", GenerationType: constants.AUTO_INCREMENT}}, "i8": schema.Column{Name: "i8", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "id": schema.Column{Name: "id", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "s": schema.Column{Name: "s", Type: schema.Type{Name: "set", Mods: []int64(nil), ArrayBounds: []int64{-1}}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "si": schema.Column{Name: "si", Type: schema.Type{Name: "integer", Mods: []int64{32}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: true, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "si": schema.Column{Name: "si", Type: schema.Type{Name: "integer", Mods: []int64{32}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "nextval('test11_s_seq'::regclass)"}}, "ts": schema.Column{Name: "ts", Type: schema.Type{Name: "datetime", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "txt": schema.Column{Name: "txt", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "tz": schema.Column{Name: "tz", Type: schema.Type{Name: "timestamp", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "vc": schema.Column{Name: "vc", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "vc6": schema.Column{Name: "vc6", Type: schema.Type{Name: "varchar", Mods: []int64{6}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}}, + "vc6": schema.Column{Name: "vc6", Type: schema.Type{Name: "varchar", Mods: []int64{6}, ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "def": schema.Column{Name: "def", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "John"}}}, PrimaryKeys: []schema.Key{schema.Key{ColId: "id", Desc: false, Order: 0}}, ForeignKeys: []schema.ForeignKey{schema.ForeignKey{Name: "fk_test4", ColIds: []string{"id", "txt"}, ReferTableId: "test_ref", ReferColumnIds: []string{"ref_id", "ref_txt"}, OnUpdate: constants.FK_RESTRICT, OnDelete: constants.FK_CASCADE, Id: ""}}, Indexes: []schema.Index(nil), Id: ""}, - "test_ref": schema.Table{Name: "test_ref", Schema: "test", ColIds: []string{"ref_id", "ref_txt", "abc"}, ColDefs: map[string]schema.Column{ + "test_ref": schema.Table{Name: "test_ref", Schema: "test", ColIds: []string{"ref_id", "ref_txt", "abc", "defval_4"}, ColDefs: map[string]schema.Column{ "abc": schema.Column{Name: "abc", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "ref_id": schema.Column{Name: "ref_id", Type: schema.Type{Name: "bigint", Mods: []int64{64}, ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "ref_txt": schema.Column{Name: "ref_txt", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}}, + "ref_txt": schema.Column{Name: "ref_txt", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "defval_4": schema.Column{Name: "defval_4", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "John"}}}, PrimaryKeys: []schema.Key{schema.Key{ColId: "ref_id", Desc: false, Order: 0}, schema.Key{ColId: "ref_txt", Desc: false, Order: 0}}, ForeignKeys: []schema.ForeignKey(nil), Indexes: []schema.Index(nil), Id: ""}, - "user": schema.Table{Name: "user", Schema: "test", ColIds: []string{"user_id", "name", "ref"}, ColDefs: map[string]schema.Column{ + "user": schema.Table{Name: "user", Schema: "test", ColIds: []string{"user_id", "name", "ref", "defval_1"}, ColDefs: map[string]schema.Column{ "name": schema.Column{Name: "name", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, "ref": schema.Column{Name: "ref", Type: schema.Type{Name: "bigint", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, - "user_id": schema.Column{Name: "user_id", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}}, + "user_id": schema.Column{Name: "user_id", Type: schema.Type{Name: "text", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: true, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: ""}, + "defval_1": schema.Column{Name: "defval_1", Type: schema.Type{Name: "varchar", Mods: []int64(nil), ArrayBounds: []int64(nil)}, NotNull: false, Ignored: schema.Ignored{Check: false, Identity: false, Default: false, Exclusion: false, ForeignKey: false, AutoIncrement: false}, Id: "", DefaultValue: schema.DefaultValue{IsPresent: true, Value: "John"}}}, PrimaryKeys: []schema.Key{schema.Key{ColId: "user_id", Desc: false, Order: 0}}, ForeignKeys: []schema.ForeignKey{schema.ForeignKey{Name: "fk_test", ColIds: []string{"ref"}, ReferTableId: "test", ReferColumnIds: []string{"id"}, OnUpdate: constants.FK_CASCADE, OnDelete: constants.FK_SET_NULL, Id: ""}}, Indexes: []schema.Index(nil), Id: ""}} @@ -395,7 +405,7 @@ func TestProcessData_MultiCol(t *testing.T) { } internal.AssertSpSchema(conv, t, expectedSchema, stripSchemaComments(conv.SpSchema)) columnLevelIssues := map[string][]internal.SchemaIssue{ - "c49": []internal.SchemaIssue{ + "c54": []internal.SchemaIssue{ 2, }, } From 62dbb626058f363383a77f5a657dc1d735fbeb45 Mon Sep 17 00:00:00 2001 From: NirnayaSindhuSuthari Date: Thu, 8 Aug 2024 06:39:52 +0000 Subject: [PATCH 2/2] Sanitize Default Value (#885) * Default Value Sanitize Default Value function * corrected comments * corrected nits * Added comments * done * handled escape characters * added unit test of sanitizeDefaultValue * changes updated * removed comments * added line * added line --- sources/mysql/infoschema.go | 21 ++++++++++++++++++++- sources/mysql/infoschema_test.go | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/sources/mysql/infoschema.go b/sources/mysql/infoschema.go index 576a25a6e7..da317cb5a6 100644 --- a/sources/mysql/infoschema.go +++ b/sources/mysql/infoschema.go @@ -224,7 +224,7 @@ func (isi InfoSchemaImpl) GetColumns(conv *internal.Conv, table common.SchemaAnd Value: "", } if colDefault.Valid { - defaultVal.Value = colDefault.String + defaultVal.Value = sanitizeDefaultValue(colDefault.String) } c := schema.Column{ @@ -242,6 +242,25 @@ func (isi InfoSchemaImpl) GetColumns(conv *internal.Conv, table common.SchemaAnd return colDefs, colIds, nil } +// sanitizeDefaultValue removes extra characters added to Default Value in information schema in MySQL. +// Example_1: +// Default Value: "concat('John', 'swamp', 'span')" +// Default Value in MySQL infoschema with extra characters: "concat(_utf8mb4\\'John\\',_utf8mb4\\'swamp\\',_utf8mb4\\'span\\')" +// Default Value after removing "_utf8mb4": "concat( \\'John\\', \\'swamp\\', \\'span\\')" +// Default Value after removing all backslashes: "concat('John','swamp','span')" +// Example_2: +// Default Value: "This is a message \nwith a newline\rand a carriage return." +// Default Value in MySQL infoschema with extra characters: "_utf8mb4\\'This is a \\tmessage \\\\nwith a newline\\\\\\'s and \\\\ra carriage return.\\'" +// Default Value after removing "_utf8mb4": " \\'This is a \\tmessage \\\\nwith a newline\\\\\\'s and \\\\ra carriage return.\\'" +// Default Value after removing all "\\\\": " \\'This is a \\tmessage \\nwith a newline\\\\'s and \\ra carriage return.\\' +// Default Value after removing all "\\'": "'This is a message \\nwith a newline\\'s \\rand a carriage return.' +func sanitizeDefaultValue(defaultValue string) string { + defaultValue = strings.ReplaceAll(defaultValue, "_utf8mb4", " ") + defaultValue = strings.ReplaceAll(defaultValue, "\\\\", "\\") + defaultValue = strings.ReplaceAll(defaultValue, "\\'", "'") + return defaultValue +} + // GetConstraints returns a list of primary keys and by-column map of // other constraints. Note: we need to preserve ordinal order of // columns in primary key constraints. diff --git a/sources/mysql/infoschema_test.go b/sources/mysql/infoschema_test.go index b78090c837..cfc6c6c02e 100644 --- a/sources/mysql/infoschema_test.go +++ b/sources/mysql/infoschema_test.go @@ -524,6 +524,25 @@ func TestSetRowStats(t *testing.T) { assert.Equal(t, int64(0), conv.Unexpecteds()) } +func TestSanitizeDefaultValue(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {"_utf8mb4\\'hello world\\'", " 'hello world'"}, + {"week(_utf8mb4\\'2024-06-20\\',0)", "week( '2024-06-20',0)"}, + {"_utf8mb4\\'This is a message \\\\nwith a newline\\\\rand a carriage return.\\'", " 'This is a message \\nwith a newline\\rand a carriage return.'"}, + {"strcmp(_utf8mb4\\'abc\\',_utf8mb4\\'abcd\\')", "strcmp( 'abc', 'abcd')"}, + {"_utf8mb4\\'John\\\\\\'s Jack\\'", " 'John\\'s Jack'"}, + {"_utf8mb4\\'This product has\tmultiple features.\\'", " 'This product has\tmultiple features.'"}, + {"_utf8mb4\\'C:\\\\\\\\Users\\\\\\\\johndoe\\\\\\\\Documents\\\\\\\\myfile.txt\\'", " 'C:\\\\Users\\\\johndoe\\\\Documents\\\\myfile.txt'"}, + } + for _, test := range tests { + result := sanitizeDefaultValue(test.input) + assert.Equal(t, test.expected, result) + } +} + func mkMockDB(t *testing.T, ms []mockSpec) *sql.DB { db, mock, err := sqlmock.New() assert.Nil(t, err)