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
- Remove the CURRENT_TIMESTAMP/expression default from the MySQL column, or replace it with a constant literal.
- Exclude the column from the CDC table definition if it is not needed in RW.
- 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
- Avoid DEFAULT CURRENT_TIMESTAMP / ON UPDATE CURRENT_TIMESTAMP columns in CDC sources
- Let the application or RisingWave set timestamps instead
- Audit information_schema.COLUMNS for CURRENT_TIMESTAMP defaults before onboarding
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
- unexpected default value type for integer
- unexpected default value type for real
- failed to parse mysql default value expression, only constan
- received a DDL message, please set `canal.instance.filter.qu
- no value found at column: {}, index: {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c836ca53780007d9.
Report an issue: GitHub.