risingwavelabs/risingwave · error · SinkError::Config

Turbopuffer sink does not support column type {}

Error message

Turbopuffer sink does not support column type {}

What it means

turbopuffer_type maps RisingWave data types to Turbopuffer schema types ([N]f32 vectors, string, int, boolean, etc.). Any column type outside the supported set reaches the catch-all arm, which produces this error naming the unsupported Rust DataType. The sink cannot be created until all columns map to a supported Turbopuffer type.

Source

Thrown at src/connector/src/sink/turbopuffer.rs:871

        DataType::List(list_type) => match list_type.elem() {
            DataType::Boolean => Ok("[]bool".to_owned()),
            DataType::Int16 | DataType::Int32 | DataType::Int64 | DataType::Serial => {
                Ok("[]int".to_owned())
            }
            DataType::Float32 | DataType::Float64 | DataType::Decimal => Ok("[]float".to_owned()),
            DataType::Varchar => Ok("[]string".to_owned()),
            DataType::Date | DataType::Timestamp | DataType::Timestamptz => {
                Ok("[]datetime".to_owned())
            }
            elem_type => Err(unsupported_type(&format!("list element {:?}", elem_type))),
        },
        DataType::Vector(dimension) => Ok(format!("[{}]f32", dimension)),
        data_type => Err(unsupported_type(&format!("{:?}", data_type))),
    }
}

fn unsupported_type(data_type: &str) -> SinkError {
    SinkError::Config(anyhow!(
        "Turbopuffer sink does not support column type {}",
        data_type
    ))
}

#[cfg(test)]
mod tests {
    #[cfg(not(madsim))]
    use std::collections::VecDeque;
    #[cfg(not(madsim))]
    use std::io::{Read, Write};
    #[cfg(not(madsim))]
    use std::net::TcpListener;
    #[cfg(not(madsim))]
    use std::sync::{Arc, Mutex, mpsc};
    #[cfg(not(madsim))]
    use std::thread;

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Inspect the type name in the error and exclude that column from the sink (or from the schema list).
  2. Cast unsupported columns in a materialized view: DECIMAL→DOUBLE PRECISION (if float mapping exists) or TIMESTAMP/DATE→VARCHAR.
  3. Flatten STRUCT columns into scalars or serialize them to JSON strings before sinking.
  4. Check turbopuffer_type in src/connector/src/sink/turbopuffer.rs for the currently supported type set.

Example fix

// before: created_at TIMESTAMP column sinking to turbopuffer
// after
CREATE MVIEW mv AS SELECT *, created_at::VARCHAR AS created_at FROM src;
-- sink from mv
Defensive patterns

Strategy: validation

Validate before calling

-- check all sink columns map to supported Turbopuffer types
-- SELECT name, data_type FROM rw_catalog.rw_columns WHERE relation_id = <table_id>;
fn tpuf_supported(dt: &str) -> bool {
    matches!(dt,
        "BOOLEAN" | "SMALLINT" | "INTEGER" | "BIGINT" | "REAL" | "DOUBLE PRECISION" |
        "VARCHAR" | "VARCHAR[]" | "DATE" ) || dt.starts_with("VECTOR")
}

Prevention

When it happens

Trigger: Creating a Turbopuffer sink whose table contains a column of an unmapped type — e.g. DECIMAL, DATE/TIME/TIMESTAMP, JSONB, STRUCT, MAP, LIST of non-string elements, BYTEA — detected during schema construction in try_from.

Common situations: Sinking tables with decimal money columns or timestamp columns directly; complex nested structs from upstream sources; bytea blobs.

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


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