risingwavelabs/risingwave · error · SinkError::BigQuery

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

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.

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.

Appendix: 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)