@@ -37,9 +37,9 @@ type TableMapEvent struct {
3737// The followings are available only after MySQL-8.0.1, see: `--binlog_row_metadata` and
3838// https://mysqlhighavailability.com/more-metadata-is-written-into-binary-log/
3939
40- OptionalMeta []byte
40+ optionalMeta []byte
4141
42- SignednessBitmap []byte // len = (ColumnCount + 7) / 8
42+ SignednessBitmap []byte
4343ColumnName [][]byte
4444PrimaryKey []uint64 // A sequence of column indexes
4545PrimaryKeyPrefix []uint64 // Prefix length 0 means that the whole column value is used
@@ -99,12 +99,12 @@ func (e *TableMapEvent) Decode(data []byte) error {
9999
100100pos += nullBitmapSize
101101
102- e .OptionalMeta = data [pos :]
103- if len (e .OptionalMeta ) == 0 {
102+ e .optionalMeta = data [pos :]
103+ if len (e .optionalMeta ) == 0 {
104104return nil
105105}
106106
107- if err = e .decodeOptionalMeta (e .OptionalMeta ); err != nil {
107+ if err = e .decodeOptionalMeta (e .optionalMeta ); err != nil {
108108return err
109109}
110110
@@ -259,6 +259,7 @@ func (e *TableMapEvent) decodeOptionalMeta(data []byte) error {
259259}
260260
261261default :
262+ // TODO: other meta
262263}
263264
264265}
@@ -275,17 +276,86 @@ func (e *TableMapEvent) Dump(w io.Writer) {
275276fmt .Fprintf (w , "Column count: %d\n " , e .ColumnCount )
276277fmt .Fprintf (w , "Column type: \n %s" , hex .Dump (e .ColumnType ))
277278fmt .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 ))
284281fmt .Fprintf (w , "Primary key: %v\n " , e .PrimaryKey )
285282fmt .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+ }
286311fmt .Fprintln (w )
287312}
288313
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+
289359// RowsEventStmtEndFlag is set in the end of the statement.
290360const RowsEventStmtEndFlag = 0x01
291361
0 commit comments