risingwavelabs/risingwave · error

failed to parse mysql default value expression, only constan

Error message

failed to parse mysql default value expression, only constant is supported

What it means

RisingWave CDC schema discovery supports only constant (literal) MySQL default values. When the default is a string/expression form, the connector tries to parse its text into the RW type via from_text; any parse failure surfaces as this context-wrapped error. It effectively means 'the default value is not a plain constant we can represent'.

Source

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

                Some(ScalarImpl::from(val.to_string()))
            }
            _ => bail!("unexpected default value type for integer"),
        },
        ColumnDefault::Real(val) => match data_type {
            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")

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Replace the MySQL column default with a constant literal compatible with the column type.
  2. If the value must be dynamic, drop the default in MySQL and handle it in the producer application.
  3. Check the literal text parses for the RW type (e.g. valid timestamp format for timestamp columns).

Example fix

// before (MySQL)
CREATE TABLE t (id INT, created TIMESTAMP DEFAULT (NOW()));
// after
CREATE TABLE t (id INT, created TIMESTAMP DEFAULT '2024-01-01 00:00:00');
Defensive patterns

Strategy: validation

Validate before calling

-- find non-literal (expression) defaults, MySQL 8+
SELECT COLUMN_NAME, COLUMN_DEFAULT, EXTRA FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='mydb' AND TABLE_NAME='t'
  AND COLUMN_DEFAULT IS NOT NULL
  AND (COLUMN_DEFAULT LIKE '%(%' OR EXTRA LIKE '%DEFAULT_GENERATED%');

Type guard

function isConstantDefault(d) {
  return typeof d === "string" && !d.includes("(") && !/^current_/i.test(d.trim());
}

Try / catch

try { await createCdcTable('t'); } catch (e) { if (String(e).includes('only constant is supported')) { /* replace expression default with a literal in MySQL, retry */ } else throw e; }

Prevention

When it happens

Trigger: A MySQL column whose DEFAULT is a non-literal expression (e.g. DEFAULT (NOW()), DEFAULT (UUID()), computed expressions) that fails from_text parsing into the target type.

Common situations: MySQL 8.0 expression defaults; defaults with functions or casts; string defaults containing formatting that doesn't fit the RW type (e.g. bad date literals).

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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