Skip to content

Commit e5760f7

Browse files
authored
Merge branch 'master' into grodowski/remove-unused-code
2 parents 5c0359a + c6f95cc commit e5760f7

18 files changed

Lines changed: 244 additions & 58 deletions

File tree

go/base/context.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -970,9 +970,8 @@ func (this *MigrationContext) GetGhostTriggerName(triggerName string) string {
970970
return triggerName + this.TriggerSuffix
971971
}
972972

973-
// validateGhostTriggerLength check if the ghost trigger name length is not more than 64 characters
973+
// ValidateGhostTriggerLengthBelowMaxLength checks if the given trigger name (already transformed
974+
// by GetGhostTriggerName) does not exceed the maximum allowed length.
974975
func (this *MigrationContext) ValidateGhostTriggerLengthBelowMaxLength(triggerName string) bool {
975-
ghostTriggerName := this.GetGhostTriggerName(triggerName)
976-
977-
return utf8.RuneCountInString(ghostTriggerName) <= mysql.MaxTableNameLength
976+
return utf8.RuneCountInString(triggerName) <= mysql.MaxTableNameLength
978977
}

go/base/context_test.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,38 +86,69 @@ func TestGetTriggerNames(t *testing.T) {
8686
}
8787

8888
func TestValidateGhostTriggerLengthBelowMaxLength(t *testing.T) {
89+
// Tests simulate the real call pattern: GetGhostTriggerName first, then validate the result.
8990
{
91+
// Short trigger name with suffix appended: well under 64 chars
9092
context := NewMigrationContext()
9193
context.TriggerSuffix = "_gho"
92-
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength("my_trigger"))
94+
ghostName := context.GetGhostTriggerName("my_trigger") // "my_trigger_gho" = 14 chars
95+
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
9396
}
9497
{
98+
// 64-char original + "_ghost" suffix = 70 chars → exceeds limit
9599
context := NewMigrationContext()
96100
context.TriggerSuffix = "_ghost"
97-
require.False(t, context.ValidateGhostTriggerLengthBelowMaxLength(strings.Repeat("my_trigger_ghost", 4))) // 64 characters + "_ghost"
101+
ghostName := context.GetGhostTriggerName(strings.Repeat("my_trigger_ghost", 4)) // 64 + 6 = 70
102+
require.False(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
98103
}
99104
{
105+
// 48-char original + "_ghost" suffix = 54 chars → valid
100106
context := NewMigrationContext()
101107
context.TriggerSuffix = "_ghost"
102-
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(strings.Repeat("my_trigger_ghost", 3))) // 48 characters + "_ghost"
108+
ghostName := context.GetGhostTriggerName(strings.Repeat("my_trigger_ghost", 3)) // 48 + 6 = 54
109+
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
103110
}
104111
{
112+
// RemoveTriggerSuffix: 64-char name ending in "_ghost" → suffix removed → 58 chars → valid
105113
context := NewMigrationContext()
106114
context.TriggerSuffix = "_ghost"
107115
context.RemoveTriggerSuffix = true
108-
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(strings.Repeat("my_trigger_ghost", 4))) // 64 characters + "_ghost" removed
116+
ghostName := context.GetGhostTriggerName(strings.Repeat("my_trigger_ghost", 4)) // suffix removed → 58
117+
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
109118
}
110119
{
120+
// RemoveTriggerSuffix: name doesn't end in suffix → suffix appended → 65 + 6 = 71 chars → exceeds
111121
context := NewMigrationContext()
112122
context.TriggerSuffix = "_ghost"
113123
context.RemoveTriggerSuffix = true
114-
require.False(t, context.ValidateGhostTriggerLengthBelowMaxLength(strings.Repeat("my_trigger_ghost", 4)+"X")) // 65 characters + "_ghost" not removed
124+
ghostName := context.GetGhostTriggerName(strings.Repeat("my_trigger_ghost", 4) + "X") // no match, appended → 71
125+
require.False(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
115126
}
116127
{
128+
// RemoveTriggerSuffix: 70-char name ending in "_ghost" → suffix removed → 64 chars → exactly at limit → valid
117129
context := NewMigrationContext()
118130
context.TriggerSuffix = "_ghost"
119131
context.RemoveTriggerSuffix = true
120-
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(strings.Repeat("my_trigger_ghost", 4)+"_ghost")) // 70 characters + last "_ghost" removed
132+
ghostName := context.GetGhostTriggerName(strings.Repeat("my_trigger_ghost", 4) + "_ghost") // suffix removed → 64
133+
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
134+
}
135+
{
136+
// Edge case: exactly 64 chars after transformation → valid (boundary test)
137+
context := NewMigrationContext()
138+
context.TriggerSuffix = "_ght"
139+
originalName := strings.Repeat("x", 60) // 60 chars
140+
ghostName := context.GetGhostTriggerName(originalName) // 60 + 4 = 64
141+
require.Equal(t, 64, len(ghostName))
142+
require.True(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
143+
}
144+
{
145+
// Edge case: 65 chars after transformation → exceeds (boundary test)
146+
context := NewMigrationContext()
147+
context.TriggerSuffix = "_ght"
148+
originalName := strings.Repeat("x", 61) // 61 chars
149+
ghostName := context.GetGhostTriggerName(originalName) // 61 + 4 = 65
150+
require.Equal(t, 65, len(ghostName))
151+
require.False(t, context.ValidateGhostTriggerLengthBelowMaxLength(ghostName))
121152
}
122153
}
123154

go/logic/applier.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,10 +1470,9 @@ func (this *Applier) buildDMLEventQuery(dmlEvent *binlog.BinlogDMLEvent) []*dmlB
14701470
results = append(results, this.buildDMLEventQuery(dmlEvent)...)
14711471
return results
14721472
}
1473-
query, sharedArgs, uniqueKeyArgs, err := this.dmlUpdateQueryBuilder.BuildQuery(dmlEvent.NewColumnValues.AbstractValues(), dmlEvent.WhereColumnValues.AbstractValues())
1473+
query, updateArgs, err := this.dmlUpdateQueryBuilder.BuildQuery(dmlEvent.NewColumnValues.AbstractValues(), dmlEvent.WhereColumnValues.AbstractValues())
14741474
args := sqlutils.Args()
1475-
args = append(args, sharedArgs...)
1476-
args = append(args, uniqueKeyArgs...)
1475+
args = append(args, updateArgs...)
14771476
return []*dmlBuildResult{newDmlBuildResult(query, args, 0, err)}
14781477
}
14791478
}

go/logic/inspect.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ func (this *Inspector) validateGhostTriggersDontExist() error {
596596
var foundTriggers []string
597597
for _, trigger := range this.migrationContext.Triggers {
598598
triggerName := this.migrationContext.GetGhostTriggerName(trigger.Name)
599-
query := "select 1 from information_schema.triggers where trigger_name = ? and trigger_schema = ? and event_object_table = ?"
599+
query := "select 1 from information_schema.triggers where trigger_name = ? and trigger_schema = ?"
600600
err := sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error {
601601
triggerExists := rowMap.GetInt("1")
602602
if triggerExists == 1 {
@@ -606,7 +606,6 @@ func (this *Inspector) validateGhostTriggersDontExist() error {
606606
},
607607
triggerName,
608608
this.migrationContext.DatabaseName,
609-
this.migrationContext.OriginalTableName,
610609
)
611610
if err != nil {
612611
return err

go/logic/migrator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ func (this *Migrator) atomicCutOver() (err error) {
842842
// If we need to create triggers we need to do it here (only create part)
843843
if this.migrationContext.IncludeTriggers && len(this.migrationContext.Triggers) > 0 {
844844
if err := this.applier.CreateTriggersOnGhost(); err != nil {
845-
this.migrationContext.Log.Errore(err)
845+
return this.migrationContext.Log.Errore(err)
846846
}
847847
}
848848

go/mysql/utils.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ func Kill(db *gosql.DB, connectionID string) error {
248248

249249
// GetTriggers reads trigger list from given table
250250
func GetTriggers(db *gosql.DB, databaseName, tableName string) (triggers []Trigger, err error) {
251-
query := fmt.Sprintf(`select trigger_name as name, event_manipulation as event, action_statement as statement, action_timing as timing
252-
from information_schema.triggers
253-
where trigger_schema = '%s' and event_object_table = '%s'`, databaseName, tableName)
251+
query := `select trigger_name as name, event_manipulation as event, action_statement as statement, action_timing as timing
252+
from information_schema.triggers
253+
where trigger_schema = ? and event_object_table = ?`
254254

255255
err = sqlutils.QueryRowsMap(db, query, func(rowMap sqlutils.RowMap) error {
256256
triggers = append(triggers, Trigger{
@@ -260,7 +260,7 @@ func GetTriggers(db *gosql.DB, databaseName, tableName string) (triggers []Trigg
260260
Timing: rowMap.GetString("timing"),
261261
})
262262
return nil
263-
})
263+
}, databaseName, tableName)
264264
if err != nil {
265265
return nil, err
266266
}

go/sql/builder.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ func (b *CheckpointInsertQueryBuilder) BuildQuery(uniqueKeyArgs []interface{}) (
169169
}
170170
convertedArgs := make([]interface{}, 0, 2*b.uniqueKeyColumns.Len())
171171
for i, column := range b.uniqueKeyColumns.Columns() {
172-
minArg := column.convertArg(uniqueKeyArgs[i], true)
172+
minArg := column.convertArg(uniqueKeyArgs[i])
173173
convertedArgs = append(convertedArgs, minArg)
174174
}
175175
for i, column := range b.uniqueKeyColumns.Columns() {
176-
minArg := column.convertArg(uniqueKeyArgs[i+b.uniqueKeyColumns.Len()], true)
176+
minArg := column.convertArg(uniqueKeyArgs[i+b.uniqueKeyColumns.Len()])
177177
convertedArgs = append(convertedArgs, minArg)
178178
}
179179
return b.preparedStatement, convertedArgs, nil
@@ -533,7 +533,7 @@ func (b *DMLDeleteQueryBuilder) BuildQuery(args []interface{}) (string, []interf
533533
uniqueKeyArgs := make([]interface{}, 0, b.uniqueKeyColumns.Len())
534534
for _, column := range b.uniqueKeyColumns.Columns() {
535535
tableOrdinal := b.tableColumns.Ordinals[column.Name]
536-
arg := column.convertArg(args[tableOrdinal], true)
536+
arg := column.convertArg(args[tableOrdinal])
537537
uniqueKeyArgs = append(uniqueKeyArgs, arg)
538538
}
539539
return b.preparedStatement, uniqueKeyArgs, nil
@@ -595,7 +595,7 @@ func (b *DMLInsertQueryBuilder) BuildQuery(args []interface{}) (string, []interf
595595
sharedArgs := make([]interface{}, 0, b.sharedColumns.Len())
596596
for _, column := range b.sharedColumns.Columns() {
597597
tableOrdinal := b.tableColumns.Ordinals[column.Name]
598-
arg := column.convertArg(args[tableOrdinal], false)
598+
arg := column.convertArg(args[tableOrdinal])
599599
sharedArgs = append(sharedArgs, arg)
600600
}
601601
return b.preparedStatement, sharedArgs, nil
@@ -661,20 +661,18 @@ func NewDMLUpdateQueryBuilder(databaseName, tableName string, tableColumns, shar
661661

662662
// BuildQuery builds the arguments array for a DML event UPDATE query.
663663
// It returns the query string, the shared arguments array, and the unique key arguments array.
664-
func (b *DMLUpdateQueryBuilder) BuildQuery(valueArgs, whereArgs []interface{}) (string, []interface{}, []interface{}, error) {
665-
sharedArgs := make([]interface{}, 0, b.sharedColumns.Len())
664+
func (b *DMLUpdateQueryBuilder) BuildQuery(valueArgs, whereArgs []interface{}) (string, []interface{}, error) {
665+
args := make([]interface{}, 0, b.sharedColumns.Len()+b.uniqueKeyColumns.Len())
666666
for _, column := range b.sharedColumns.Columns() {
667667
tableOrdinal := b.tableColumns.Ordinals[column.Name]
668-
arg := column.convertArg(valueArgs[tableOrdinal], false)
669-
sharedArgs = append(sharedArgs, arg)
668+
arg := column.convertArg(valueArgs[tableOrdinal])
669+
args = append(args, arg)
670670
}
671-
672-
uniqueKeyArgs := make([]interface{}, 0, b.uniqueKeyColumns.Len())
673671
for _, column := range b.uniqueKeyColumns.Columns() {
674672
tableOrdinal := b.tableColumns.Ordinals[column.Name]
675-
arg := column.convertArg(whereArgs[tableOrdinal], true)
676-
uniqueKeyArgs = append(uniqueKeyArgs, arg)
673+
arg := column.convertArg(whereArgs[tableOrdinal])
674+
args = append(args, arg)
677675
}
678676

679-
return b.preparedStatement, sharedArgs, uniqueKeyArgs, nil
677+
return b.preparedStatement, args, nil
680678
}

go/sql/builder_test.go

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
647647
uniqueKeyColumns := NewColumnList([]string{"position"})
648648
builder, err := NewDMLUpdateQueryBuilder(databaseName, tableName, tableColumns, sharedColumns, sharedColumns, uniqueKeyColumns)
649649
require.NoError(t, err)
650-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
650+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
651651
require.NoError(t, err)
652652
expected := `
653653
update /* gh-ost mydb.tbl */
@@ -657,15 +657,14 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
657657
((position = ?))
658658
`
659659
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
660-
require.Equal(t, []interface{}{3, "testname", 17, 23}, sharedArgs)
661-
require.Equal(t, []interface{}{17}, uniqueKeyArgs)
660+
require.Equal(t, []interface{}{3, "testname", 17, 23, 17}, updateArgs)
662661
}
663662
{
664663
sharedColumns := NewColumnList([]string{"id", "name", "position", "age"})
665664
uniqueKeyColumns := NewColumnList([]string{"position", "name"})
666665
builder, err := NewDMLUpdateQueryBuilder(databaseName, tableName, tableColumns, sharedColumns, sharedColumns, uniqueKeyColumns)
667666
require.NoError(t, err)
668-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
667+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
669668
require.NoError(t, err)
670669
expected := `
671670
update /* gh-ost mydb.tbl */
@@ -675,15 +674,14 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
675674
((position = ?) and (name = ?))
676675
`
677676
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
678-
require.Equal(t, []interface{}{3, "testname", 17, 23}, sharedArgs)
679-
require.Equal(t, []interface{}{17, "testname"}, uniqueKeyArgs)
677+
require.Equal(t, []interface{}{3, "testname", 17, 23, 17, "testname"}, updateArgs)
680678
}
681679
{
682680
sharedColumns := NewColumnList([]string{"id", "name", "position", "age"})
683681
uniqueKeyColumns := NewColumnList([]string{"age"})
684682
builder, err := NewDMLUpdateQueryBuilder(databaseName, tableName, tableColumns, sharedColumns, sharedColumns, uniqueKeyColumns)
685683
require.NoError(t, err)
686-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
684+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
687685
require.NoError(t, err)
688686
expected := `
689687
update /* gh-ost mydb.tbl */
@@ -693,15 +691,14 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
693691
((age = ?))
694692
`
695693
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
696-
require.Equal(t, []interface{}{3, "testname", 17, 23}, sharedArgs)
697-
require.Equal(t, []interface{}{56}, uniqueKeyArgs)
694+
require.Equal(t, []interface{}{3, "testname", 17, 23, 56}, updateArgs)
698695
}
699696
{
700697
sharedColumns := NewColumnList([]string{"id", "name", "position", "age"})
701698
uniqueKeyColumns := NewColumnList([]string{"age", "position", "id", "name"})
702699
builder, err := NewDMLUpdateQueryBuilder(databaseName, tableName, tableColumns, sharedColumns, sharedColumns, uniqueKeyColumns)
703700
require.NoError(t, err)
704-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
701+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
705702
require.NoError(t, err)
706703
expected := `
707704
update /* gh-ost mydb.tbl */
@@ -711,8 +708,7 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
711708
((age = ?) and (position = ?) and (id = ?) and (name = ?))
712709
`
713710
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
714-
require.Equal(t, []interface{}{3, "testname", 17, 23}, sharedArgs)
715-
require.Equal(t, []interface{}{56, 17, 3, "testname"}, uniqueKeyArgs)
711+
require.Equal(t, []interface{}{3, "testname", 17, 23, 56, 17, 3, "testname"}, updateArgs)
716712
}
717713
{
718714
sharedColumns := NewColumnList([]string{"id", "name", "position", "age"})
@@ -732,7 +728,7 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
732728
uniqueKeyColumns := NewColumnList([]string{"id"})
733729
builder, err := NewDMLUpdateQueryBuilder(databaseName, tableName, tableColumns, sharedColumns, mappedColumns, uniqueKeyColumns)
734730
require.NoError(t, err)
735-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
731+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
736732
require.NoError(t, err)
737733
expected := `
738734
update /* gh-ost mydb.tbl */
@@ -742,8 +738,7 @@ func TestBuildDMLUpdateQuery(t *testing.T) {
742738
((id = ?))
743739
`
744740
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
745-
require.Equal(t, []interface{}{3, "testname", 17, 23}, sharedArgs)
746-
require.Equal(t, []interface{}{3}, uniqueKeyArgs)
741+
require.Equal(t, []interface{}{3, "testname", 17, 23, 3}, updateArgs)
747742
}
748743
}
749744

@@ -759,7 +754,7 @@ func TestBuildDMLUpdateQuerySignedUnsigned(t *testing.T) {
759754
require.NoError(t, err)
760755
{
761756
// test signed
762-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
757+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
763758
require.NoError(t, err)
764759
expected := `
765760
update /* gh-ost mydb.tbl */
@@ -769,14 +764,13 @@ func TestBuildDMLUpdateQuerySignedUnsigned(t *testing.T) {
769764
((position = ?))
770765
`
771766
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
772-
require.Equal(t, []interface{}{3, "testname", int8(-17), int8(-2)}, sharedArgs)
773-
require.Equal(t, []interface{}{int8(-3)}, uniqueKeyArgs)
767+
require.Equal(t, []interface{}{3, "testname", int8(-17), int8(-2), int8(-3)}, updateArgs)
774768
}
775769
{
776770
// test unsigned
777771
sharedColumns.SetUnsigned("age")
778772
uniqueKeyColumns.SetUnsigned("position")
779-
query, sharedArgs, uniqueKeyArgs, err := builder.BuildQuery(valueArgs, whereArgs)
773+
query, updateArgs, err := builder.BuildQuery(valueArgs, whereArgs)
780774
require.NoError(t, err)
781775
expected := `
782776
update /* gh-ost mydb.tbl */
@@ -786,8 +780,7 @@ func TestBuildDMLUpdateQuerySignedUnsigned(t *testing.T) {
786780
((position = ?))
787781
`
788782
require.Equal(t, normalizeQuery(expected), normalizeQuery(query))
789-
require.Equal(t, []interface{}{3, "testname", int8(-17), uint8(254)}, sharedArgs)
790-
require.Equal(t, []interface{}{uint8(253)}, uniqueKeyArgs)
783+
require.Equal(t, []interface{}{3, "testname", int8(-17), uint8(254), uint8(253)}, updateArgs)
791784
}
792785
}
793786

go/sql/types.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type Column struct {
5757
MySQLType string
5858
}
5959

60-
func (this *Column) convertArg(arg interface{}, isUniqueKeyColumn bool) interface{} {
60+
func (this *Column) convertArg(arg interface{}) interface{} {
6161
var arg2Bytes []byte
6262
if s, ok := arg.(string); ok {
6363
arg2Bytes = []byte(s)
@@ -77,14 +77,14 @@ func (this *Column) convertArg(arg interface{}, isUniqueKeyColumn bool) interfac
7777
}
7878
}
7979

80-
if this.Type == BinaryColumnType && isUniqueKeyColumn {
80+
if this.Type == BinaryColumnType {
8181
size := len(arg2Bytes)
8282
if uint(size) < this.BinaryOctetLength {
8383
buf := bytes.NewBuffer(arg2Bytes)
8484
for i := uint(0); i < (this.BinaryOctetLength - uint(size)); i++ {
8585
buf.Write([]byte{0})
8686
}
87-
arg = buf.String()
87+
arg = buf.Bytes()
8888
}
8989
}
9090

0 commit comments

Comments
 (0)