mysqlbinlog/parse_event_convert_unsigned_test.go

96 lines
3.0 KiB
Go
Raw Permalink Normal View History

package binlog
import (
"testing"
"github.com/starainrt/go-mysql/mysql"
"github.com/starainrt/go-mysql/replication"
)
func TestNormalizeRowsByUnsigned_AllIntegerKinds(t *testing.T) {
event := &replication.RowsEvent{
Table: &replication.TableMapEvent{
ColumnCount: 5,
ColumnType: []byte{mysql.MYSQL_TYPE_TINY, mysql.MYSQL_TYPE_SHORT, mysql.MYSQL_TYPE_INT24, mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_LONGLONG},
SignednessBitmap: []byte{0xF8},
},
Rows: [][]interface{}{{int8(-1), int16(-2), int32(-1), int32(-1), int64(-1)}},
}
got := normalizeRowsByUnsigned(event)
row := got[0]
if v, ok := row[0].(uint8); !ok || v != 255 {
t.Fatalf("tiny unsigned mismatch: %T %v", row[0], row[0])
}
if v, ok := row[1].(uint16); !ok || v != 65534 {
t.Fatalf("short unsigned mismatch: %T %v", row[1], row[1])
}
if v, ok := row[2].(uint32); !ok || v != 16777215 {
t.Fatalf("int24 unsigned mismatch: %T %v", row[2], row[2])
}
if v, ok := row[3].(uint32); !ok || v != 4294967295 {
t.Fatalf("long unsigned mismatch: %T %v", row[3], row[3])
}
if v, ok := row[4].(uint64); !ok || v != 18446744073709551615 {
t.Fatalf("longlong unsigned mismatch: %T %v", row[4], row[4])
}
}
func TestNormalizeRowsByUnsigned_NoSignednessMetadata(t *testing.T) {
event := &replication.RowsEvent{
Table: &replication.TableMapEvent{
ColumnCount: 1,
ColumnType: []byte{mysql.MYSQL_TYPE_LONGLONG},
},
Rows: [][]interface{}{{int64(-1)}},
}
got := normalizeRowsByUnsigned(event)
if v, ok := got[0][0].(int64); !ok || v != -1 {
t.Fatalf("value should remain signed when metadata missing: %T %v", got[0][0], got[0][0])
}
}
func TestParseBinlogEvent_IncludeColumnMetadata(t *testing.T) {
event := &replication.RowsEvent{
Table: &replication.TableMapEvent{
ColumnCount: 3,
ColumnType: []byte{mysql.MYSQL_TYPE_VAR_STRING, mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_VAR_STRING},
DefaultCharset: []uint64{45}, // utf8mb4_general_ci
},
Rows: [][]interface{}{{"name", int32(1), "desc"}},
}
ev := &replication.BinlogEvent{
Header: &replication.EventHeader{EventType: replication.WRITE_ROWS_EVENTv2},
Event: event,
}
events := ParseBinlogEvent(ev)
if len(events) != 1 {
t.Fatalf("expected 1 event, got %d", len(events))
}
got := events[0]
if len(got.ColumnTypes) != 3 {
t.Fatalf("unexpected column type length: %d", len(got.ColumnTypes))
}
if got.ColumnTypes[0] != int(mysql.MYSQL_TYPE_VAR_STRING) || got.ColumnTypes[1] != int(mysql.MYSQL_TYPE_LONG) {
t.Fatalf("unexpected column types: %v", got.ColumnTypes)
}
if len(got.ColumnCollationIDs) != 3 {
t.Fatalf("unexpected column collation length: %d", len(got.ColumnCollationIDs))
}
if got.ColumnCollationIDs[0] != 45 {
t.Fatalf("unexpected collation for column 0: %d", got.ColumnCollationIDs[0])
}
if got.ColumnCollationIDs[2] != 45 {
t.Fatalf("unexpected collation for column 2: %d", got.ColumnCollationIDs[2])
}
if got.ColumnCollationIDs[1] != 0 {
t.Fatalf("non-character column should keep zero collation: %d", got.ColumnCollationIDs[1])
}
}