databendlabs/databend · error

must array type

Error message

must array type

What it means

ArrayColumn<T>::upcast converts a typed array column to ArrayColumn<AnyType>, and first extracts the inner element type via DataType::as_array(). The panic fires when the supplied data_type is not an array type (e.g. a scalar or struct type), which violates the caller's contract: upcast is only meaningful for columns whose logical type is Array.

Solutions

  1. Verify the DataType passed to upcast corresponds to the array column (it must be Array(inner_type)).
  2. Unwrap Nullable before/consistently with how the column values were built.
  3. Return a typed error instead of expect if the input type is externally supplied.

Example fix

// before
let values_type = data_type.as_array().expect("must array type");
// after
let values_type = data_type.as_array().ok_or_else(|| ErrorCode::BadDataValueType(format!("expected array type, got {data_type}")))?;
Defensive patterns

Strategy: type-guard

Validate before calling

if data_type.as_array().is_none() {
    return Err(ErrorCode::BadDataValueType(format!("expected array type, got {data_type}")));
}
let out = column.upcast(&data_type);

Type guard

fn is_array_type(dt: &DataType) -> bool { dt.as_array().is_some() }

Prevention

When it happens

Trigger: Calling upcast with a DataType that is not Array(..), e.g. passing the column's outer type when it is Nullable/Variant, or a type-mismatched metadata/type pairing in a cast or aggregation generic path.

Common situations: Generic expression code that upcasts array columns but receives metadata for a non-array type after nullable unwrapping mismatches; a function registered for arrays receiving scalar arguments due to a signature mix-up.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/b57de7da9acbf456. Report an issue: GitHub.

Appendix: source

Thrown at src/query/expression/src/types/array.rs:333

                len
            )));
        }

        for i in 1..len {
            if offsets[i] < offsets[i - 1] {
                return Err(ErrorCode::Internal(format!(
                    "ArrayColumn offsets value must be equal or greater than previous value, but got {}",
                    offsets[i]
                )));
            }
        }
        Ok(())
    }
}

impl<T: ValueType> ArrayColumn<T> {
    pub fn upcast(self, data_type: &DataType) -> ArrayColumn<AnyType> {
        let values_type = data_type.as_array().expect("must array type");
        ArrayColumn {
            values: T::upcast_column_with_type(self.values, values_type),
            offsets: self.offsets,
        }
    }
}

impl ArrayColumn<AnyType> {
    pub fn try_downcast<T: AccessType>(&self) -> Result<ArrayColumn<T>> {
        Ok(ArrayColumn {
            values: T::try_downcast_column(&self.values)?,
            offsets: self.offsets.clone(),
        })
    }
}

pub struct ArrayIterator<'a, T: AccessType> {
    values: &'a T::Column,

View on GitHub (pinned to 288d84d76e)