risingwavelabs/risingwave · error · ConnectorError

MySQL CURRENT_TIMESTAMP and custom expression default value

Error message

MySQL CURRENT_TIMESTAMP and custom expression default value not supported

What it means

The MySQL CDC connector cannot represent CURRENT_TIMESTAMP defaults or arbitrary custom expression defaults, because RisingWave must replay the exact default value. derive_default_value explicitly bails when it encounters ColumnDefault::CurrentTimestamp or ColumnDefault::CustomExpr.

Source

Thrown at src/connector/src/source/cdc/external/mysql.rs:255

            DataType::Float32 => Some(ScalarImpl::Float32(F32::from(val as f32))),
            DataType::Float64 => Some(ScalarImpl::Float64(val.into())),
            DataType::Decimal => Some(ScalarImpl::Decimal(
                Decimal::try_from(val).context("failed to convert default value to decimal")?,
            )),
            _ => bail!("unexpected default value type for real"),
        },
        ColumnDefault::String(mut val) => {
            // mysql timestamp is mapped to timestamptz, we use UTC timezone to
            // interpret its value
            if data_type == &DataType::Timestamptz {
                val = timestamp_val_to_timestamptz(val.as_str())?;
            }
            Some(ScalarImpl::from_text(val.as_str(), data_type).map_err(|e| anyhow!(e)).context(
                "failed to parse mysql default value expression, only constant is supported",
            )?)
        }
        ColumnDefault::CurrentTimestamp | ColumnDefault::CustomExpr(_) => {
            bail!("MySQL CURRENT_TIMESTAMP and custom expression default value not supported")
        }
    };
    Ok(datum)
}

pub fn timestamp_val_to_timestamptz(value_text: &str) -> ConnectorResult<String> {
    let format = "%Y-%m-%d %H:%M:%S";
    let naive_datetime = NaiveDateTime::parse_from_str(value_text, format)
        .map_err(|err| anyhow!("failed to parse mysql timestamp value").context(err))?;
    let postgres_timestamptz: DateTime<chrono::Utc> =
        DateTime::<chrono::Utc>::from_naive_utc_and_offset(naive_datetime, chrono::Utc);
    Ok(postgres_timestamptz
        .format("%Y-%m-%d %H:%M:%S%:z")
        .to_string())
}

pub fn type_name_to_mysql_type(ty_name: &str) -> Option<ColumnType> {
    // Debezium schema change message may include extra qualifiers, e.g. `BIGINT UNSIGNED`,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove the CURRENT_TIMESTAMP/expression default from the MySQL column, or replace it with a constant literal.
  2. Exclude the column from the CDC table definition if it is not needed in RW.
  3. Handle timestamping on the RisingWave side (e.g. compute at insert time) instead of relying on MySQL defaults.

Example fix

// before (MySQL)
CREATE TABLE t (created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
// after
CREATE TABLE t (created_at TIMESTAMP NULL DEFAULT NULL);
Defensive patterns

Strategy: validation

Validate before calling

SELECT COLUMN_NAME FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='mydb' AND TABLE_NAME='t'
  AND (UPPER(COLUMN_DEFAULT) LIKE 'CURRENT_TIMESTAMP%' OR UPPER(COLUMN_DEFAULT) = 'NOW()');

Type guard

function hasCurrentTimestampDefault(col) {
  return /^current_timestamp(\(\d*\))?$/i.test(String(col.COLUMN_DEFAULT).trim());
}

Try / catch

try { await createCdcTable('t'); } catch (e) { if (String(e).includes('CURRENT_TIMESTAMP and custom expression default value not supported')) { /* drop/replace the default, then retry */ } else throw e; }

Prevention

When it happens

Trigger: Creating a CDC table whose MySQL column has DEFAULT CURRENT_TIMESTAMP (or ON UPDATE CURRENT_TIMESTAMP captured as such), or any parenthesized expression default.

Common situations: Very common audit columns (created_at/updated_at with CURRENT_TIMESTAMP); MySQL 8.0 expression defaults; tables auto-generated by ORMs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/c836ca53780007d9. Report an issue: GitHub.