risingwavelabs/risingwave · error · SinkError::BigQuery

REAL is not supported for BigQuery sink. Please convert to F

Error message

REAL is not supported for BigQuery sink. Please convert to FLOAT64 or other supported types.

What it means

The BigQuery sink does not map RisingWave's 32-bit Float32 (SQL REAL) to any BigQuery type — BigQuery has no REAL type and the connector deliberately refuses rather than silently widening. Any sink schema containing a REAL/Float32 column fails validation.

Source

Thrown at src/connector/src/sink/big_query.rs:397

            if !Self::is_data_type_compatible(&i.data_type, value)? {
                return Err(SinkError::BigQuery(anyhow::anyhow!(
                    "Data type mismatch for column `{:?}`. BigQuery side: `{:?}`, RisingWave side: `{:?}`. ",
                    i.name,
                    value,
                    data_type_string
                )));
            };
        }
        Ok(())
    }

    fn get_string_and_check_support_from_datatype(rw_data_type: &DataType) -> Result<String> {
        match rw_data_type {
            DataType::Boolean => Ok("BOOL".to_owned()),
            DataType::Int16 => Ok("INT64".to_owned()),
            DataType::Int32 => Ok("INT64".to_owned()),
            DataType::Int64 => Ok("INT64".to_owned()),
            DataType::Float32 => Err(SinkError::BigQuery(anyhow::anyhow!(
                "REAL is not supported for BigQuery sink. Please convert to FLOAT64 or other supported types."
            ))),
            DataType::Float64 => Ok("FLOAT64".to_owned()),
            DataType::Decimal => Ok("NUMERIC".to_owned()),
            DataType::Date => Ok("DATE".to_owned()),
            DataType::Varchar => Ok("STRING".to_owned()),
            DataType::Time => Ok("TIME".to_owned()),
            DataType::Timestamp => Ok("DATETIME".to_owned()),
            DataType::Timestamptz => Ok("TIMESTAMP".to_owned()),
            DataType::Interval => Ok("INTERVAL".to_owned()),
            DataType::Struct(structs) => {
                let mut elements_vec = vec![];
                for (name, datatype) in structs.iter() {
                    let element_string =
                        Self::get_string_and_check_support_from_datatype(datatype)?;
                    elements_vec.push(format!("{} {}", name, element_string));
                }
                Ok(format!("STRUCT<{}>", elements_vec.join(", ")))

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Change the column to DOUBLE PRECISION / FLOAT64 on the RisingWave side before sinking
  2. Or wrap the column in the MV: CAST(col AS DOUBLE PRECISION) AS col
  3. Recreate the sink after the type change

Example fix

-- before
CREATE MATERIALIZED VIEW mv AS SELECT r FROM t; -- r is REAL
-- after
CREATE MATERIALIZED VIEW mv AS SELECT CAST(r AS DOUBLE PRECISION) AS r FROM t;
Defensive patterns

Strategy: validation

Validate before calling

SELECT column_name FROM information_schema.columns
WHERE table_name = 'mv' AND udt_name IN ('real','float4');
-- must return zero rows before CREATE SINK

Type guard

fn sink_ready(field: &Field) -> bool { !matches!(field.data_type(), DataType::Float32) }

Try / catch

match get_string_and_check_support_from_datatype(&dt) {
    Err(e) if e.to_string().contains("REAL is not supported") => {
        eprintln!("cast REAL columns to DOUBLE PRECISION in the MV");
    }
    _ => {}
}

Prevention

When it happens

Trigger: Creating a BigQuery sink whose source relation has a `REAL` / `FLOAT4` / `FLOAT32` column; validation calls `get_string_and_check_support_from_datatype` which errors on DataType::Float32.

Common situations: Legacy tables using REAL columns; ports from Postgres schemas where REAL is common.

Related errors


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