@@ -40,6 +40,13 @@ type TableMapEvent struct {
40
40
41
41
SignednessBitmap []byte
42
42
43
+ // DefaultCharset[0] is the default collation;
44
+ // For character columns that have different charset,
45
+ // (character column index, column collation) pairs follows
46
+ DefaultCharset []uint64
47
+ // ColumnCharset contains collation sequence for all character columns
48
+ ColumnCharset []uint64
49
+
43
50
ColumnName [][]byte
44
51
PrimaryKey []uint64 // A sequence of column indexes
45
52
PrimaryKeyPrefix []uint64 // Prefix length 0 means that the whole column value is used
@@ -219,6 +226,22 @@ func (e *TableMapEvent) decodeOptionalMeta(data []byte) error {
219
226
case TABLE_MAP_OPT_META_SIGNEDNESS :
220
227
e .SignednessBitmap = v
221
228
229
+ case TABLE_MAP_OPT_META_DEFAULT_CHARSET :
230
+ p := 0
231
+ for p < len (v ) {
232
+ c , _ , n := LengthEncodedInt (v [p :])
233
+ p += n
234
+ e .DefaultCharset = append (e .DefaultCharset , c )
235
+ }
236
+
237
+ case TABLE_MAP_OPT_META_COLUMN_CHARSET :
238
+ p := 0
239
+ for p < len (v ) {
240
+ c , _ , n := LengthEncodedInt (v [p :])
241
+ p += n
242
+ e .ColumnCharset = append (e .ColumnCharset , c )
243
+ }
244
+
222
245
case TABLE_MAP_OPT_META_COLUMN_NAME :
223
246
p := 0
224
247
e .ColumnName = make ([][]byte , 0 , e .ColumnCount )
@@ -273,10 +296,15 @@ func (e *TableMapEvent) Dump(w io.Writer) {
273
296
fmt .Fprintf (w , "NULL bitmap: \n %s" , hex .Dump (e .NullBitmap ))
274
297
275
298
fmt .Fprintf (w , "Signedness bitmap: \n %s" , hex .Dump (e .SignednessBitmap ))
299
+ fmt .Fprintf (w , "Default charset: %v\n " , e .DefaultCharset )
300
+ fmt .Fprintf (w , "Column charset: %v\n " , e .ColumnCharset )
276
301
fmt .Fprintf (w , "Primary key: %v\n " , e .PrimaryKey )
277
302
fmt .Fprintf (w , "Primary key prefix: %v\n " , e .PrimaryKeyPrefix )
278
303
279
304
unsignedMap := e .UnsignedMap ()
305
+ fmt .Fprintf (w , "UnsignedMap: %#v\n " , unsignedMap )
306
+ collationMap := e .CollationMap ()
307
+ fmt .Fprintf (w , "CollationMap: %#v\n " , collationMap )
280
308
281
309
nameMaxLen := 0
282
310
for _ , name := range e .ColumnName {
@@ -305,13 +333,19 @@ func (e *TableMapEvent) Dump(w io.Writer) {
305
333
fmt .Fprintf (w , " type=%-3d" , e .ColumnType [i ])
306
334
307
335
if IsNumericType (e .ColumnType [i ]) {
308
- if unsignedMap == nil {
336
+ if len ( unsignedMap ) == 0 {
309
337
fmt .Fprintf (w , " unsigned=<n/a>" )
310
338
} else if unsignedMap [i ] {
311
339
fmt .Fprintf (w , " unsigned=yes" )
312
340
} else {
313
341
fmt .Fprintf (w , " unsigned=no " )
314
342
}
343
+ } else if IsCharacterType (e .ColumnType [i ]) {
344
+ if len (collationMap ) == 0 {
345
+ fmt .Fprintf (w , " collation=<n/a>" )
346
+ } else {
347
+ fmt .Fprintf (w , " collation=%d " , collationMap [i ])
348
+ }
315
349
}
316
350
317
351
available , nullable := e .Nullable (i )
@@ -344,7 +378,7 @@ func (e *TableMapEvent) Nullable(i int) (available, nullable bool) {
344
378
345
379
// UnsignedMap returns a map: column index -> unsigned.
346
380
// Note that only numeric columns will be returned.
347
- // If signedness bits are not available, nil is returned .
381
+ // nil is returned if not available or no numeric columns at all .
348
382
func (e * TableMapEvent ) UnsignedMap () map [int ]bool {
349
383
if len (e .SignednessBitmap ) == 0 {
350
384
return nil
@@ -355,12 +389,64 @@ func (e *TableMapEvent) UnsignedMap() map[int]bool {
355
389
if ! IsNumericType (e .ColumnType [i ]) {
356
390
continue
357
391
}
392
+
358
393
ret [i ] = e .SignednessBitmap [p / 8 ]& (1 << uint (7 - p % 8 )) != 0
359
394
p ++
360
395
}
361
396
return ret
362
397
}
363
398
399
+ // CollationMap returns a map: column index -> collation id.
400
+ // Note that only character columns will be returned.
401
+ // nil is returned if not available or no character columns at all.
402
+ func (e * TableMapEvent ) CollationMap () map [int ]uint64 {
403
+
404
+ ret := make (map [int ]uint64 )
405
+
406
+ if len (e .DefaultCharset ) != 0 {
407
+ defaultCollation := e .DefaultCharset [0 ]
408
+
409
+ // character column index -> collation
410
+ collations := make (map [int ]uint64 )
411
+ for i := 1 ; i < len (e .DefaultCharset ); i += 2 {
412
+ collations [int (e .DefaultCharset [i ])] = e .DefaultCharset [i + 1 ]
413
+ }
414
+
415
+ p := 0
416
+ for i := 0 ; i < int (e .ColumnCount ); i ++ {
417
+ if ! IsCharacterType (e .ColumnType [i ]) {
418
+ continue
419
+ }
420
+
421
+ if collation , ok := collations [p ]; ok {
422
+ ret [i ] = collation
423
+ } else {
424
+ ret [i ] = defaultCollation
425
+ }
426
+ p ++
427
+ }
428
+
429
+ return ret
430
+ }
431
+
432
+ if len (e .ColumnCharset ) != 0 {
433
+
434
+ p := 0
435
+ for i := 0 ; i < int (e .ColumnCount ); i ++ {
436
+ if ! IsCharacterType (e .ColumnType [i ]) {
437
+ continue
438
+ }
439
+
440
+ ret [i ] = e .ColumnCharset [p ]
441
+ p ++
442
+ }
443
+
444
+ return ret
445
+ }
446
+
447
+ return nil
448
+ }
449
+
364
450
// RowsEventStmtEndFlag is set in the end of the statement.
365
451
const RowsEventStmtEndFlag = 0x01
366
452
0 commit comments