@@ -438,11 +438,14 @@ func (c *Canal) GenerateCharsetQuery() (string, error) {
438438query := `
439439 SELECT
440440 c.ORDINAL_POSITION,
441- CASE
442- WHEN c.CHARACTER_SET_NAME IS NOT NULL THEN c.CHARACTER_SET_NAME
443- WHEN c.DATA_TYPE IN ('binary','varbinary','tinyblob','blob','mediumblob','longblob') THEN col.CHARACTER_SET_NAME
444- ELSE col.CHARACTER_SET_NAME
445- END AS CHARACTER_SET_NAME,
441+ COALESCE(
442+ CASE
443+ WHEN c.CHARACTER_SET_NAME IS NOT NULL THEN c.CHARACTER_SET_NAME
444+ WHEN c.DATA_TYPE IN ('binary','varbinary','tinyblob','blob','mediumblob','longblob') THEN col.CHARACTER_SET_NAME
445+ ELSE col.CHARACTER_SET_NAME
446+ END,
447+ 'utf8mb4'
448+ ) AS CHARACTER_SET_NAME,
446449 c.COLUMN_NAME
447450 FROM
448451 information_schema.COLUMNS c
@@ -465,12 +468,19 @@ func (c *Canal) setColumnsCharsetFromRows(tableRegex string, rows *sql.Rows) err
465468c .cfg .ColumnCharset [tableRegex ] = make (map [int ]string )
466469for rows .Next () {
467470var ordinal int
468- var charset , columnName string
471+ var charset , columnName sql. NullString
469472if err := rows .Scan (& ordinal , & charset , & columnName ); err != nil {
470473return errors .Annotate (err , "failed to scan charset row" )
471474}
472- c .cfg .ColumnCharset [tableRegex ][ordinal ] = charset
473- log .Infof ("Column Name: %s, Ordinal: %d, Charset: %s" , columnName , ordinal , charset )
475+
476+ // Handle NULL charset values properly
477+ charsetValue := "utf8mb4" // default charset
478+ if charset .Valid && charset .String != "" {
479+ charsetValue = charset .String
480+ }
481+
482+ c .cfg .ColumnCharset [tableRegex ][ordinal ] = charsetValue
483+ log .Infof ("Column Name: %s, Ordinal: %d, Charset: %s" , columnName .String , ordinal , charsetValue )
474484}
475485
476486return rows .Err ()
@@ -514,13 +524,12 @@ func (c *Canal) GetColumnsCharsets() error {
514524return fmt .Errorf ("error occurred while executing query: %s on db: %s on table: %s. error: %v" ,
515525query , dbName , tableName , errors .Trace (err ))
516526}
517- // Ensure rows are closed after processing
518- func () {
519- defer rows .Close ()
520- if err := c .setColumnsCharsetFromRows (tableRegex , rows ); err != nil {
521- panic (fmt .Errorf ("failed to set charset from rows: %w" , err ))
522- }
523- }()
527+
528+ // Process rows with proper error handling
529+ defer rows .Close ()
530+ if err := c .setColumnsCharsetFromRows (tableRegex , rows ); err != nil {
531+ return fmt .Errorf ("failed to set charset from rows for table %s: %w" , tableRegex , err )
532+ }
524533
525534}
526535
0 commit comments