@@ -81,6 +81,9 @@ type TableMapEvent struct {
81
81
// EnumSetDefaultCharset/EnumSetColumnCharset is similar to DefaultCharset/ColumnCharset but for enum/set columns.
82
82
EnumSetDefaultCharset []uint64
83
83
EnumSetColumnCharset []uint64
84
+
85
+ // VisibilityBitmap stores bits that are set if corresponding column is not invisible (MySQL 8.0.23+)
86
+ VisibilityBitmap []byte
84
87
}
85
88
86
89
func (e * TableMapEvent ) Decode (data []byte ) error {
@@ -312,6 +315,9 @@ func (e *TableMapEvent) decodeOptionalMeta(data []byte) (err error) {
312
315
return err
313
316
}
314
317
318
+ case TABLE_MAP_OPT_META_COLUMN_VISIBILITY :
319
+ e .VisibilityBitmap = v
320
+
315
321
default :
316
322
// Ignore for future extension
317
323
}
@@ -421,6 +427,7 @@ func (e *TableMapEvent) Dump(w io.Writer) {
421
427
fmt .Fprintf (w , "Primary key prefix: %v\n " , e .PrimaryKeyPrefix )
422
428
fmt .Fprintf (w , "Enum/set default charset: %v\n " , e .EnumSetDefaultCharset )
423
429
fmt .Fprintf (w , "Enum/set column charset: %v\n " , e .EnumSetColumnCharset )
430
+ fmt .Fprintf (w , "Invisible Column bitmap: \n %s" , hex .Dump (e .VisibilityBitmap ))
424
431
425
432
unsignedMap := e .UnsignedMap ()
426
433
fmt .Fprintf (w , "UnsignedMap: %#v\n " , unsignedMap )
@@ -440,6 +447,9 @@ func (e *TableMapEvent) Dump(w io.Writer) {
440
447
geometryTypeMap := e .GeometryTypeMap ()
441
448
fmt .Fprintf (w , "GeometryTypeMap: %#v\n " , geometryTypeMap )
442
449
450
+ visibilityMap := e .VisibilityMap ()
451
+ fmt .Fprintf (w , "VisibilityMap: %#v\n " , visibilityMap )
452
+
443
453
nameMaxLen := 0
444
454
for _ , name := range e .ColumnName {
445
455
if len (name ) > nameMaxLen {
@@ -608,14 +618,19 @@ func (e *TableMapEvent) UnsignedMap() map[int]bool {
608
618
if len (e .SignednessBitmap ) == 0 {
609
619
return nil
610
620
}
611
- p := 0
612
621
ret := make (map [int ]bool )
613
- for i := 0 ; i < int (e .ColumnCount ); i ++ {
614
- if ! e .IsNumericColumn (i ) {
615
- continue
622
+ i := 0
623
+ for _ , field := range e .SignednessBitmap {
624
+ for c := 0x80 ; c != 0 ; {
625
+ if e .IsNumericColumn (i ) {
626
+ ret [i ] = field & byte (c ) != 0
627
+ c >>= 1
628
+ }
629
+ i ++
630
+ if i >= int (e .ColumnCount ) {
631
+ return ret
632
+ }
616
633
}
617
- ret [i ] = e .SignednessBitmap [p / 8 ]& (1 << uint (7 - p % 8 )) != 0
618
- p ++
619
634
}
620
635
return ret
621
636
}
@@ -730,6 +745,27 @@ func (e *TableMapEvent) GeometryTypeMap() map[int]uint64 {
730
745
return ret
731
746
}
732
747
748
+ // VisibilityMap returns a map: column index -> visiblity.
749
+ // Invisible column was introduced in MySQL 8.0.23
750
+ // nil is returned if not available.
751
+ func (e * TableMapEvent ) VisibilityMap () map [int ]bool {
752
+ if len (e .VisibilityBitmap ) == 0 {
753
+ return nil
754
+ }
755
+ ret := make (map [int ]bool )
756
+ i := 0
757
+ for _ , field := range e .VisibilityBitmap {
758
+ for c := 0x80 ; c != 0 ; c >>= 1 {
759
+ ret [i ] = field & byte (c ) != 0
760
+ i ++
761
+ if uint64 (i ) >= e .ColumnCount {
762
+ return ret
763
+ }
764
+ }
765
+ }
766
+ return ret
767
+ }
768
+
733
769
// Below realType and IsXXXColumn are base from:
734
770
// table_def::type in sql/rpl_utility.h
735
771
// Table_map_log_event::print_columns in mysql-8.0/sql/log_event.cc and mariadb-10.5/sql/log_event_client.cc
0 commit comments