Skip to content

Commit 9dc8c6c

Browse files
committed
amend to provider suffix and add converter func tests
1 parent 7d07eac commit 9dc8c6c

File tree

12 files changed

+212
-53
lines changed

12 files changed

+212
-53
lines changed

.gitattributes

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,3 @@ enginetest/testdata/loaddata_enclosed.dat binary
2020
enginetest/testdata/loaddata_single_quotes.dat binary
2121
enginetest/testdata/loaddata_nulls.dat binary
2222
enginetest/testdata/loaddata_escape.dat binary
23-
enginetest/testdata/binlog_*.txt binary

enginetest/enginetests.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,6 @@ func TestLoadDataFailing(t *testing.T, harness Harness) {
10981098
}
10991099
}
11001100

1101-
11021101
func TestSelectIntoFile(t *testing.T, harness Harness) {
11031102
harness.Setup(setup.MydbData, setup.MytableData, setup.EmptytableData, setup.NiltableData)
11041103
e := mustNewEngine(t, harness)

sql/analyzer/catalog.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ func (c *Catalog) DropDbStats(ctx *sql.Context, db string, flush bool) error {
5555
}
5656

5757
var _ sql.Catalog = (*Catalog)(nil)
58-
var _ binlogreplication.BinlogConsumerCatalog = (*Catalog)(nil)
59-
var _ binlogreplication.BinlogReplicaCatalog = (*Catalog)(nil)
60-
var _ binlogreplication.BinlogPrimaryCatalog = (*Catalog)(nil)
58+
var _ binlogreplication.BinlogConsumerProvider = (*Catalog)(nil)
59+
var _ binlogreplication.BinlogReplicaProvider = (*Catalog)(nil)
60+
var _ binlogreplication.BinlogPrimaryProvider = (*Catalog)(nil)
6161

6262
type tableLocks map[string]struct{}
6363

sql/binlogreplication/binlog_replication.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,28 @@ type ReplicaStatus struct {
158158
SourceSsl bool
159159
}
160160

161-
// BinlogConsumerCatalog extends the Catalog interface and provides methods for accessing a BinlogConsumer
162-
// for BINLOG statement execution and other binlog event processing.
163-
type BinlogConsumerCatalog interface {
164-
// HasBinlogConsumer returns true if a non-nil BinlogConsumer is available for this catalog.
161+
// BinlogConsumerProvider provides methods for accessing a BinlogConsumer for BINLOG statement execution and other binlog
162+
// event processing. Typically implemented by sql.Catalog.
163+
type BinlogConsumerProvider interface {
164+
// HasBinlogConsumer returns true if a non-nil BinlogConsumer is available.
165165
HasBinlogConsumer() bool
166-
// GetBinlogConsumer returns the BinlogConsumer registered with this catalog.
166+
// GetBinlogConsumer returns the BinlogConsumer.
167167
GetBinlogConsumer() BinlogConsumer
168168
}
169169

170-
// BinlogReplicaCatalog extends the Catalog interface and provides methods for accessing a BinlogReplicaController
171-
// for a Catalog.
172-
type BinlogReplicaCatalog interface {
173-
// HasBinlogReplicaController returns true if a non-nil BinlogReplicaController is available for this BinlogReplicaCatalog.
170+
// BinlogReplicaProvider provides methods for accessing a BinlogReplicaController for binlog replica operations.
171+
type BinlogReplicaProvider interface {
172+
// HasBinlogReplicaController returns true if a non-nil BinlogReplicaController is available.
174173
HasBinlogReplicaController() bool
175-
// GetBinlogReplicaController returns the BinlogReplicaController registered with this BinlogReplicaCatalog.
174+
// GetBinlogReplicaController returns the BinlogReplicaController.
176175
GetBinlogReplicaController() BinlogReplicaController
177176
}
178177

179-
// BinlogPrimaryCatalog extends the Catalog interface and provides methods for accessing a BinlogPrimaryController
180-
// for a Catalog.
181-
type BinlogPrimaryCatalog interface {
182-
// HasBinlogPrimaryController returns true if a non-nil BinlogPrimaryController is available for this BinlogPrimaryCatalog.
178+
// BinlogPrimaryProvider provides methods for accessing a BinlogPrimaryController for binlog primary operations.
179+
type BinlogPrimaryProvider interface {
180+
// HasBinlogPrimaryController returns true if a non-nil BinlogPrimaryController is available.
183181
HasBinlogPrimaryController() bool
184-
// GetBinlogPrimaryController returns the BinlogPrimaryController registered with this BinlogPrimaryCatalog.
182+
// GetBinlogPrimaryController returns the BinlogPrimaryController.
185183
GetBinlogPrimaryController() BinlogPrimaryController
186184
}
187185

sql/collations.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -984,12 +984,6 @@ func ConvertCollationID(val any) (string, error) {
984984
} else {
985985
return string(v), nil
986986
}
987-
case string:
988-
if n, err := strconv.ParseUint(v, 10, 64); err == nil {
989-
collationID = n
990-
} else {
991-
return v, nil
992-
}
993987
case int8:
994988
collationID = uint64(v)
995989
case int16:
@@ -1014,6 +1008,10 @@ func ConvertCollationID(val any) (string, error) {
10141008
return fmt.Sprintf("%v", val), nil
10151009
}
10161010

1011+
if collationID >= uint64(len(collationArray)) {
1012+
return fmt.Sprintf("%v", val), nil
1013+
}
1014+
10171015
collation := CollationID(collationID).Collation()
10181016
return collation.Name, nil
10191017
}

sql/collations_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,61 @@ func testParseCollation(t *testing.T, charset string, collation string, binaryAt
6969
}
7070
})
7171
}
72+
73+
func TestConvertCollationID(t *testing.T) {
74+
tests := []struct {
75+
input any
76+
expected string
77+
}{
78+
{uint64(33), "utf8mb3_general_ci"},
79+
{int64(33), "utf8mb3_general_ci"},
80+
{[]byte("33"), "utf8mb3_general_ci"},
81+
{uint64(8), "latin1_swedish_ci"},
82+
{int32(8), "latin1_swedish_ci"},
83+
84+
{45, "utf8mb4_general_ci"},
85+
{uint64(46), "utf8mb4_bin"},
86+
{255, "utf8mb4_0900_ai_ci"},
87+
{uint64(309), "utf8mb4_0900_bin"},
88+
89+
{83, "utf8mb3_bin"},
90+
{uint64(223), "utf8mb3_general_mysql500_ci"},
91+
92+
{uint64(47), "latin1_bin"},
93+
{48, "latin1_general_ci"},
94+
{49, "latin1_general_cs"},
95+
96+
{uint64(63), "binary"},
97+
98+
{uint64(11), "ascii_general_ci"},
99+
{65, "ascii_bin"},
100+
101+
{uint64(15), "latin1_danish_ci"},
102+
{31, "latin1_german2_ci"},
103+
{94, "latin1_spanish_ci"},
104+
105+
{int8(8), "latin1_swedish_ci"},
106+
{int16(8), "latin1_swedish_ci"},
107+
{int(8), "latin1_swedish_ci"},
108+
{uint8(8), "latin1_swedish_ci"},
109+
{uint16(8), "latin1_swedish_ci"},
110+
{uint(8), "latin1_swedish_ci"},
111+
{uint32(8), "latin1_swedish_ci"},
112+
113+
{"utf8mb4_0900_bin", "utf8mb4_0900_bin"},
114+
{"utf8mb3_general_ci", "utf8mb3_general_ci"},
115+
{"", ""},
116+
117+
{uint64(99999), "99999"},
118+
{uint64(1000), "1000"},
119+
{int(500), "500"},
120+
}
121+
122+
for _, tt := range tests {
123+
t.Run(fmt.Sprintf("%T(%v)", tt.input, tt.input), func(t *testing.T) {
124+
result, err := ConvertCollationID(tt.input)
125+
assert.NoError(t, err)
126+
assert.Equal(t, tt.expected, result)
127+
})
128+
}
129+
}

sql/planbuilder/binlog_replication.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (b *Builder) buildChangeReplicationSource(inScope *scope, n *ast.ChangeRepl
3535
convertedOptions = append(convertedOptions, *convertedOption)
3636
}
3737
repSrc := plan.NewChangeReplicationSource(convertedOptions)
38-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
38+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
3939
repSrc.ReplicaController = binCat.GetBinlogReplicaController()
4040
}
4141
outScope.node = repSrc
@@ -77,7 +77,7 @@ func (b *Builder) buildChangeReplicationFilter(inScope *scope, n *ast.ChangeRepl
7777
convertedOptions = append(convertedOptions, *convertedOption)
7878
}
7979
changeFilter := plan.NewChangeReplicationFilter(convertedOptions)
80-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
80+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
8181
changeFilter.ReplicaController = binCat.GetBinlogReplicaController()
8282
}
8383
outScope.node = changeFilter

sql/planbuilder/builder.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ func (b *Builder) buildSubquery(inScope *scope, stmt ast.Statement, subQuery str
307307
}
308308
outScope = inScope.push()
309309
startRep := plan.NewStartReplica()
310-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
310+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
311311
startRep.ReplicaController = binCat.GetBinlogReplicaController()
312312
}
313313
outScope.node = startRep
@@ -317,7 +317,7 @@ func (b *Builder) buildSubquery(inScope *scope, stmt ast.Statement, subQuery str
317317
}
318318
outScope = inScope.push()
319319
stopRep := plan.NewStopReplica()
320-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
320+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
321321
stopRep.ReplicaController = binCat.GetBinlogReplicaController()
322322
}
323323
outScope.node = stopRep
@@ -327,7 +327,7 @@ func (b *Builder) buildSubquery(inScope *scope, stmt ast.Statement, subQuery str
327327
}
328328
outScope = inScope.push()
329329
resetRep := plan.NewResetReplica(n.All)
330-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
330+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
331331
resetRep.ReplicaController = binCat.GetBinlogReplicaController()
332332
}
333333
outScope.node = resetRep
@@ -407,7 +407,7 @@ func (b *Builder) buildSubquery(inScope *scope, stmt ast.Statement, subQuery str
407407
}
408408
outScope = inScope.push()
409409
binlogNode := plan.NewBinlog(n.Base64Str)
410-
if binCat, ok := b.cat.(binlogreplication.BinlogConsumerCatalog); ok && binCat.HasBinlogConsumer() {
410+
if binCat, ok := b.cat.(binlogreplication.BinlogConsumerProvider); ok && binCat.HasBinlogConsumer() {
411411
binlogNode = binlogNode.WithBinlogConsumer(binCat.GetBinlogConsumer()).(*plan.Binlog)
412412
}
413413
outScope.node = binlogNode

sql/planbuilder/show.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,21 +84,21 @@ func (b *Builder) buildShow(inScope *scope, s *ast.Show) (outScope *scope) {
8484
case "binary log status":
8585
outScope = inScope.push()
8686
showRep := plan.NewShowBinlogStatus()
87-
if binCat, ok := b.cat.(binlogreplication.BinlogPrimaryCatalog); ok && binCat.HasBinlogPrimaryController() {
87+
if binCat, ok := b.cat.(binlogreplication.BinlogPrimaryProvider); ok && binCat.HasBinlogPrimaryController() {
8888
showRep.PrimaryController = binCat.GetBinlogPrimaryController()
8989
}
9090
outScope.node = showRep
9191
case "binary logs":
9292
outScope = inScope.push()
9393
showRep := plan.NewShowBinlogs()
94-
if binCat, ok := b.cat.(binlogreplication.BinlogPrimaryCatalog); ok && binCat.HasBinlogPrimaryController() {
94+
if binCat, ok := b.cat.(binlogreplication.BinlogPrimaryProvider); ok && binCat.HasBinlogPrimaryController() {
9595
showRep.PrimaryController = binCat.GetBinlogPrimaryController()
9696
}
9797
outScope.node = showRep
9898
case "replica status":
9999
outScope = inScope.push()
100100
showRep := plan.NewShowReplicaStatus()
101-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
101+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
102102
showRep.ReplicaController = binCat.GetBinlogReplicaController()
103103
}
104104
outScope.node = showRep
@@ -107,7 +107,7 @@ func (b *Builder) buildShow(inScope *scope, s *ast.Show) (outScope *scope) {
107107
// but uses a schema with different column names so we create the node differently here.
108108
outScope = inScope.push()
109109
showRep := plan.NewShowSlaveStatus()
110-
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaCatalog); ok && binCat.HasBinlogReplicaController() {
110+
if binCat, ok := b.cat.(binlogreplication.BinlogReplicaProvider); ok && binCat.HasBinlogReplicaController() {
111111
showRep.ReplicaController = binCat.GetBinlogReplicaController()
112112
}
113113
outScope.node = showRep

sql/sql_mode.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const (
5151
TimeTruncateFractional = "TIME_TRUNCATE_FRACTIONAL"
5252
)
5353

54-
// Bits for different SQL modes (from mysql-server/sql/system_variables.h)
54+
// Bits for different SQL modes
55+
// https://github.com/mysql/mysql-server/blob/f362272c18e856930c867952a7dd1d840cbdb3b1/sql/system_variables.h#L123-L173
5556
const (
5657
modeRealAsFloat = 1
5758
modePipesAsConcat = 2
@@ -74,6 +75,21 @@ const (
7475
modeNoEngineSubstitution = modeHighNotPrecedence * 2
7576
modePadCharToFullLength = 1 << 31
7677
modeTimeTruncateFractional = 1 << 32
78+
79+
// modeIgnoredMask contains deprecated/obsolete SQL mode bits that can be safely ignored
80+
// during binlog replication. These modes existed in older MySQL versions but are no longer used.
81+
// See: https://github.com/mysql/mysql-server/blob/trunk/sql/system_variables.h MODE_IGNORED_MASK
82+
modeIgnoredMask = 0x00100 | // was: MODE_POSTGRESQL
83+
0x00200 | // was: MODE_ORACLE
84+
0x00400 | // was: MODE_MSSQL
85+
0x00800 | // was: MODE_DB2
86+
0x01000 | // was: MODE_MAXDB
87+
0x02000 | // was: MODE_NO_KEY_OPTIONS
88+
0x04000 | // was: MODE_NO_TABLE_OPTIONS
89+
0x08000 | // was: MODE_NO_FIELD_OPTIONS
90+
0x10000 | // was: MODE_MYSQL323
91+
0x20000 | // was: MODE_MYSQL40
92+
0x10000000 // was: MODE_NO_AUTO_CREATE_USER
7793
)
7894

7995
// sqlModeBitMap maps SQL mode bit flags to their string names.
@@ -94,6 +110,7 @@ var sqlModeBitMap = map[uint64]string{
94110
modeAllowInvalidDates: AllowInvalidDates,
95111
modeErrorForDivisionByZero: ErrorForDivisionByZero,
96112
modeTraditional: Traditional,
113+
// Note: modeNoAutoCreateUser is NOT in this map - it's in modeIgnoredMask and filtered out
97114
modeHighNotPrecedence: HighNotPrecedence,
98115
modeNoEngineSubstitution: NoEngineSubstitution,
99116
modePadCharToFullLength: PadCharToFullLength,
@@ -233,14 +250,6 @@ func ConvertSqlModeBitmask(val any) (string, error) {
233250
case []byte:
234251
if n, err := strconv.ParseUint(string(v), 10, 64); err == nil {
235252
bitmask = n
236-
} else {
237-
return string(v), nil
238-
}
239-
case string:
240-
if n, err := strconv.ParseUint(v, 10, 64); err == nil {
241-
bitmask = n
242-
} else {
243-
return v, nil
244253
}
245254
case int8:
246255
bitmask = uint64(v)
@@ -266,13 +275,21 @@ func ConvertSqlModeBitmask(val any) (string, error) {
266275
return fmt.Sprintf("%v", val), nil
267276
}
268277

278+
bitmask = bitmask &^ modeIgnoredMask
279+
269280
var modes []string
281+
var matchedBits uint64
270282
for bit, modeName := range sqlModeBitMap {
271283
if bitmask&bit != 0 {
272284
modes = append(modes, modeName)
285+
matchedBits |= bit
273286
}
274287
}
275288

289+
if bitmask != 0 && matchedBits != bitmask {
290+
return fmt.Sprintf("%v", val), nil
291+
}
292+
276293
if len(modes) == 0 {
277294
return "", nil
278295
}

0 commit comments

Comments
 (0)