@@ -330,7 +330,7 @@ func (e *TableMapEvent) Dump(w io.Writer) {
330330fmt .Fprintf (w , nameFmt , e .ColumnName [i ])
331331}
332332
333- fmt .Fprintf (w , " type=%-3d" , e .ColumnType [ i ] )
333+ fmt .Fprintf (w , " type=%-3d" , e .realType ( i ) )
334334
335335if IsNumericType (e .ColumnType [i ]) {
336336if len (unsignedMap ) == 0 {
@@ -340,7 +340,7 @@ func (e *TableMapEvent) Dump(w io.Writer) {
340340} else {
341341fmt .Fprintf (w , " unsigned=no " )
342342}
343- } else if IsCharacterType ( e . ColumnType [ i ] ) {
343+ } else if e . isCharacterField ( i ) {
344344if len (collationMap ) == 0 {
345345fmt .Fprintf (w , " collation=<n/a>" )
346346} else {
@@ -413,7 +413,7 @@ func (e *TableMapEvent) CollationMap() map[int]uint64 {
413413p := 0
414414ret := make (map [int ]uint64 )
415415for i := 0 ; i < int (e .ColumnCount ); i ++ {
416- if ! IsCharacterType ( e . ColumnType [ i ] ) {
416+ if ! e . isCharacterField ( i ) {
417417continue
418418}
419419
@@ -433,7 +433,7 @@ func (e *TableMapEvent) CollationMap() map[int]uint64 {
433433p := 0
434434ret := make (map [int ]uint64 )
435435for i := 0 ; i < int (e .ColumnCount ); i ++ {
436- if ! IsCharacterType ( e . ColumnType [ i ] ) {
436+ if ! e . isCharacterField ( i ) {
437437continue
438438}
439439
@@ -447,6 +447,54 @@ func (e *TableMapEvent) CollationMap() map[int]uint64 {
447447return nil
448448}
449449
450+ // Get the `real_type` of column i. Note that types stored in ColumnType are the `binlog_type`.
451+ // See: mysql-8.0/sql/rpl_utility.h table_def::type
452+ // Also see: notes/field_type.md
453+ func (e * TableMapEvent ) realType (i int ) byte {
454+
455+ typ := e .ColumnType [i ]
456+ meta := e .ColumnMeta [i ]
457+
458+ switch typ {
459+ case MYSQL_TYPE_STRING :
460+ realTyp := byte (meta >> 8 )
461+ if realTyp == MYSQL_TYPE_ENUM || realTyp == MYSQL_TYPE_SET {
462+ return realTyp
463+ }
464+
465+ case MYSQL_TYPE_DATE :
466+ return MYSQL_TYPE_NEWDATE
467+
468+ }
469+
470+ return typ
471+
472+ }
473+
474+ // Returns true if the i-th column is numeric field.
475+ // See: mysql-8.0/sql/log_event.cc is_numeric_field
476+ func (e * TableMapEvent ) isNumericField (i int ) bool {
477+ return IsNumericType (e .ColumnType [i ])
478+ }
479+
480+ // Returns true if the i-th column is character field.
481+ // See: mysql-8.0/sql/log_event.cc is_character_field
482+ func (e * TableMapEvent ) isCharacterField (i int ) bool {
483+ return IsCharacterType (e .realType (i ))
484+ }
485+
486+ // Returns true if the i-th column is enum field.
487+ // See: mysql-8.0/sql/log_event.cc is_enum_field
488+ func (e * TableMapEvent ) isEnumField (i int ) bool {
489+ return e .realType (i ) == MYSQL_TYPE_ENUM
490+ }
491+
492+ // Returns true if the i-th column is set field.
493+ // See: mysql-8.0/sql/log_event.cc is_set_field
494+ func (e * TableMapEvent ) isSetField (i int ) bool {
495+ return e .realType (i ) == MYSQL_TYPE_SET
496+ }
497+
450498// RowsEventStmtEndFlag is set in the end of the statement.
451499const RowsEventStmtEndFlag = 0x01
452500
0 commit comments