@@ -37,9 +37,9 @@ type TableMapEvent struct {
37
37
// The followings are available only after MySQL-8.0.1, see: `--binlog_row_metadata` and
38
38
// https://mysqlhighavailability.com/more-metadata-is-written-into-binary-log/
39
39
40
- OptionalMeta []byte
40
+ optionalMeta []byte
41
41
42
- SignednessBitmap []byte // len = (ColumnCount + 7) / 8
42
+ SignednessBitmap []byte
43
43
ColumnName [][]byte
44
44
PrimaryKey []uint64 // A sequence of column indexes
45
45
PrimaryKeyPrefix []uint64 // Prefix length 0 means that the whole column value is used
@@ -99,12 +99,12 @@ func (e *TableMapEvent) Decode(data []byte) error {
99
99
100
100
pos += nullBitmapSize
101
101
102
- e .OptionalMeta = data [pos :]
103
- if len (e .OptionalMeta ) == 0 {
102
+ e .optionalMeta = data [pos :]
103
+ if len (e .optionalMeta ) == 0 {
104
104
return nil
105
105
}
106
106
107
- if err = e .decodeOptionalMeta (e .OptionalMeta ); err != nil {
107
+ if err = e .decodeOptionalMeta (e .optionalMeta ); err != nil {
108
108
return err
109
109
}
110
110
@@ -259,6 +259,7 @@ func (e *TableMapEvent) decodeOptionalMeta(data []byte) error {
259
259
}
260
260
261
261
default :
262
+ // TODO: other meta
262
263
}
263
264
264
265
}
@@ -275,17 +276,86 @@ func (e *TableMapEvent) Dump(w io.Writer) {
275
276
fmt .Fprintf (w , "Column count: %d\n " , e .ColumnCount )
276
277
fmt .Fprintf (w , "Column type: \n %s" , hex .Dump (e .ColumnType ))
277
278
fmt .Fprintf (w , "NULL bitmap: \n %s" , hex .Dump (e .NullBitmap ))
278
- fmt .Fprintf (w , "Optional meta: \n %s" , hex .Dump (e .OptionalMeta ))
279
- fmt .Fprintf (w , "Signedness bitmap\n %s" , hex .Dump (e .SignednessBitmap ))
280
- fmt .Fprintf (w , "Column name: \n " )
281
- for _ , name := range e .ColumnName {
282
- fmt .Fprintf (w , " %s\n " , name )
283
- }
279
+ fmt .Fprintf (w , "Optional meta: \n %s" , hex .Dump (e .optionalMeta ))
280
+ fmt .Fprintf (w , "Signedness bitmap: \n %s" , hex .Dump (e .SignednessBitmap ))
284
281
fmt .Fprintf (w , "Primary key: %v\n " , e .PrimaryKey )
285
282
fmt .Fprintf (w , "Primary key prefix: %v\n " , e .PrimaryKeyPrefix )
283
+
284
+ colNameArr := e .ColumnNameArray ()
285
+ nullArr := e .NullableArray ()
286
+ unsignedArr := e .UnsignedArray ()
287
+ fmt .Fprintf (w , "Columns: \n " )
288
+ for i := 0 ; i < int (e .ColumnCount ); i ++ {
289
+ if colNameArr != nil {
290
+ fmt .Fprintf (w , " %s" , colNameArr [i ])
291
+ } else {
292
+ fmt .Fprintf (w , " <noname>" )
293
+ }
294
+
295
+ fmt .Fprintf (w , " type:%d" , e .ColumnType [i ])
296
+
297
+ if unsignedArr != nil && unsignedArr [i ] {
298
+ fmt .Fprintf (w , " unsigned" )
299
+ }
300
+
301
+ if nullArr != nil {
302
+ if nullArr [i ] {
303
+ fmt .Fprintf (w , " null" )
304
+ } else {
305
+ fmt .Fprintf (w , " notnull" )
306
+ }
307
+ }
308
+
309
+ fmt .Fprintf (w , "\n " )
310
+ }
286
311
fmt .Fprintln (w )
287
312
}
288
313
314
+ // NullableArray returns an array of nullablity for each column: true if the column is nullable.
315
+ // It returns nil if not available.
316
+ func (e * TableMapEvent ) NullableArray () []bool {
317
+ if len (e .NullBitmap ) == 0 {
318
+ return nil
319
+ }
320
+ ret := make ([]bool , e .ColumnCount )
321
+ for i := 0 ; i < len (ret ); i ++ {
322
+ ret [i ] = e .NullBitmap [i / 8 ]& (1 << (i % 8 )) != 0
323
+ }
324
+ return ret
325
+ }
326
+
327
+ // ColumnNameArray returns an array of column names.
328
+ // It returns nil if not available.
329
+ func (e * TableMapEvent ) ColumnNameArray () []string {
330
+ if len (e .ColumnName ) == 0 {
331
+ return nil
332
+ }
333
+ ret := make ([]string , e .ColumnCount )
334
+ for i := 0 ; i < len (ret ); i ++ {
335
+ ret [i ] = string (e .ColumnName [i ])
336
+ }
337
+ return ret
338
+ }
339
+
340
+ // UnsignedArray returns an array of signedness for each column: true if the column is numeric and it's unsigned.
341
+ // It returns nil if not available.
342
+ func (e * TableMapEvent ) UnsignedArray () []bool {
343
+ if len (e .SignednessBitmap ) == 0 {
344
+ return nil
345
+ }
346
+ p := 0
347
+ ret := make ([]bool , e .ColumnCount )
348
+ for i := 0 ; i < len (ret ); i ++ {
349
+ if ! IsNumericType (e .ColumnType [i ]) {
350
+ ret [i ] = false
351
+ continue
352
+ }
353
+ ret [i ] = e .SignednessBitmap [p / 8 ]& (1 << (7 - p % 8 )) != 0
354
+ p ++
355
+ }
356
+ return ret
357
+ }
358
+
289
359
// RowsEventStmtEndFlag is set in the end of the statement.
290
360
const RowsEventStmtEndFlag = 0x01
291
361
0 commit comments