diff --git a/dml_events.go b/dml_events.go index 9935da66..f5a6172a 100644 --- a/dml_events.go +++ b/dml_events.go @@ -292,7 +292,7 @@ func NewBinlogDMLEvents(table *TableSchema, ev *replication.BinlogEvent, pos, re ) } for i, col := range table.Columns { - if col.IsUnsigned { + if col.IsUnsigned && col.Type != schema.TYPE_MEDIUM_INT { switch v := row[i].(type) { case int64: row[i] = uint64(v) @@ -305,6 +305,11 @@ func NewBinlogDMLEvents(table *TableSchema, ev *replication.BinlogEvent, pos, re case int: row[i] = uint(v) } + } else if col.IsUnsigned && col.Type == schema.TYPE_MEDIUM_INT { + if row[i] != nil { + val := row[i].(int32) + row[i] = NewUint24(val).Uint32() + } } } } diff --git a/uint24.go b/uint24.go new file mode 100644 index 00000000..fac9c15e --- /dev/null +++ b/uint24.go @@ -0,0 +1,27 @@ +// with the courtesy of this github file: https://github.com/Cryptkeeper/go-fseq/blob/v0.2.6/pkg/uint24/uint24.go +// used to convert a int32 to uint24 (mediumint) +package ghostferry + +const MaxUint24 = 1<<24 - 1 + +func NewUint24(val int32) *Uint24 { + var u = new(Uint24) + u.Set(val) + return u +} + +type Uint24 [3]uint8 + +func (u *Uint24) Set(val int32) { + // panic since this is closer to how a compiler/runtime would treat an overflow compared to err returns + if val > MaxUint24 { + panic("cannot set Uint24 larger than uint24.MaxUint24") + } + (*u)[0] = uint8(val & 0xFF) + (*u)[1] = uint8((val >> 8) & 0xFF) + (*u)[2] = uint8((val >> 16) & 0xFF) +} + +func (u Uint24) Uint32() uint32 { + return uint32(u[0]) | uint32(u[1])<<8 | uint32(u[2])<<16 +} \ No newline at end of file