Skip to main content

uqa_sql/assignment/
vectors.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Validate vector and tensor values used by physical indexes.
8
9use super::conversion::validate_vector_dimensions;
10use crate::catalog::type_metadata::column_type_name;
11use crate::expr::{value_to_tensor, value_to_vector};
12use crate::{ColumnType, SQLError};
13use uqa_core::Value;
14
15mod budgeted;
16pub use budgeted::index_vectors_for_type_budgeted;
17
18pub fn index_vectors_for_type(value: &Value, ty: &ColumnType) -> Result<Vec<Vec<f32>>, SQLError> {
19    // SQL VECTOR/TENSOR columns are nullable unless their declaration says
20    // otherwise. A NULL value therefore means that the row has no vectors to
21    // index; it is not a malformed vector. Returning an empty replacement set
22    // also clears any vectors left by an UPDATE ... SET field = NULL while
23    // retaining strict validation for every non-NULL value.
24    if matches!(value, Value::Null) {
25        return Ok(Vec::new());
26    }
27    match ty {
28        ColumnType::Vector(dim) => {
29            let vector = value_to_vector(value)?;
30            validate_vector_dimensions(*dim, vector.len())?;
31            Ok(vec![vector])
32        }
33        ColumnType::Tensor(dim) => {
34            let tensor = value_to_tensor(value)?;
35            for vector in &tensor {
36                validate_vector_dimensions(*dim, vector.len())?;
37            }
38            Ok(tensor)
39        }
40        _ => Err(SQLError::TypeMismatch(format!(
41            "{} is not vector-indexable",
42            column_type_name(ty)
43        ))),
44    }
45}