risingwavelabs/risingwave · error · SinkError::BigQuery
VARIANT is not supported for BigQuery sink.
Error message
VARIANT is not supported for BigQuery sink.
What it means
RisingWave's VARIANT (semi-structured) type has no BigQuery counterpart in this connector's type mapping, so `get_string_and_check_support_from_datatype` rejects any sink schema containing a VARIANT column.
Source
Thrown at src/connector/src/sink/big_query.rs:423
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(", ")))
}
DataType::List(l) => {
let element_string = Self::get_string_and_check_support_from_datatype(l.elem())?;
Ok(format!("ARRAY<{}>", element_string))
}
DataType::Bytea => Ok("BYTES".to_owned()),
DataType::Jsonb => Ok("JSON".to_owned()),
DataType::Variant => Err(SinkError::BigQuery(anyhow::anyhow!(
"VARIANT is not supported for BigQuery sink."
))),
DataType::Serial => Ok("INT64".to_owned()),
DataType::Int256 => Err(SinkError::BigQuery(anyhow::anyhow!(
"INT256 is not supported for BigQuery sink."
))),
DataType::Map(_) => Err(SinkError::BigQuery(anyhow::anyhow!(
"MAP is not supported for BigQuery sink."
))),
DataType::Vector(_) => Err(SinkError::BigQuery(anyhow::anyhow!(
"VECTOR is not supported for BigQuery sink."
))),
}
}
fn map_field(rw_field: &Field) -> Result<TableFieldSchema> {
let tfs = match &rw_field.data_type {
DataType::Boolean => TableFieldSchema::bool(&rw_field.name),View on GitHub (pinned to 6469eb736d)
Solutions
- Convert the VARIANT column to JSONB in the MV (CAST(col AS JSONB)) which maps to BigQuery JSON
- Or extract the needed fields from the VARIANT into typed columns
- Recreate the sink after the schema change
Example fix
-- before CREATE MATERIALIZED VIEW mv AS SELECT v FROM t; -- v is VARIANT -- after CREATE MATERIALIZED VIEW mv AS SELECT CAST(v AS JSONB) AS v FROM t;
Defensive patterns
Strategy: validation
Validate before calling
SELECT column_name FROM information_schema.columns WHERE table_name = 'mv' AND udt_name = 'variant'; -- must return zero rows before CREATE SINK
Type guard
fn sink_ready(field: &Field) -> bool { !matches!(field.data_type(), DataType::Variant) } Try / catch
match get_string_and_check_support_from_datatype(&dt) {
Err(e) if e.to_string().contains("VARIANT is not supported") => {
eprintln!("cast VARIANT to JSONB in the MV");
}
_ => {}
} Prevention
- Flatten VARIANT columns into typed fields before sinking
- Use JSONB (maps to BigQuery JSON) for semi-structured data
- Reject VARIANT in a pre-flight schema lint
When it happens
Trigger: Creating a BigQuery sink on a relation with a VARIANT column (e.g. from a Snowflake-compatible or JSON-ingested source); validation enumerates all fields and errors on the VARIANT one.
Common situations: Semi-structured payloads ingested as VARIANT being piped to BigQuery; users expecting automatic conversion to BigQuery JSON.
Related errors
- REAL is not supported for BigQuery sink. Please convert to F
- INT256 is not supported for BigQuery sink.
- Don't support Variant
- Don't support Float32 and Int256
- Don't support Map
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/870e58cef7a2da7c.
Report an issue: GitHub.