Build a `SqlPlan::VectorPrimaryInsert` from parsed rows. Extracts the vector-field column into `vector: Vec ` and collects all remaining columns into `payload_fields`. Rows missing the vector column are rejected.
(
collection: &str,
vpc: &nodedb_types::VectorPrimaryConfig,
_columns: &[String],
rows: Vec<Vec<(String, SqlValue)>>,
)
| 221 | /// all remaining columns into `payload_fields`. Rows missing the vector |
| 222 | /// column are rejected. |
| 223 | pub(super) fn build_vector_primary_insert_plan( |
| 224 | collection: &str, |
| 225 | vpc: &nodedb_types::VectorPrimaryConfig, |
| 226 | _columns: &[String], |
| 227 | rows: Vec<Vec<(String, SqlValue)>>, |
| 228 | ) -> Result<Vec<SqlPlan>> { |
| 229 | let mut result_rows = Vec::with_capacity(rows.len()); |
| 230 | for row in rows { |
| 231 | let mut vector: Option<Vec<f32>> = None; |
| 232 | let mut payload_fields = std::collections::HashMap::new(); |
| 233 | |
| 234 | for (col, val) in row { |
| 235 | if col == vpc.vector_field { |
| 236 | match val { |
| 237 | SqlValue::Array(items) => { |
| 238 | let floats: Result<Vec<f32>> = items |
| 239 | .iter() |
| 240 | .map(|v| match v { |
| 241 | SqlValue::Float(f) => Ok(*f as f32), |
| 242 | SqlValue::Int(i) => Ok(*i as f32), |
| 243 | SqlValue::Decimal(d) => { |
| 244 | use rust_decimal::prelude::ToPrimitive; |
| 245 | d.to_f32().ok_or_else(|| SqlError::Parse { |
| 246 | detail: format!( |
| 247 | "vector element decimal '{d}' is out of f32 range" |
| 248 | ), |
| 249 | }) |
| 250 | } |
| 251 | other => Err(SqlError::Parse { |
| 252 | detail: format!( |
| 253 | "vector field must contain numbers, got {other:?}" |
| 254 | ), |
| 255 | }), |
| 256 | }) |
| 257 | .collect(); |
| 258 | vector = Some(floats?); |
| 259 | } |
| 260 | other => { |
| 261 | return Err(SqlError::Parse { |
| 262 | detail: format!( |
| 263 | "vector field '{}' must be an array literal, got {other:?}", |
| 264 | vpc.vector_field |
| 265 | ), |
| 266 | }); |
| 267 | } |
| 268 | } |
| 269 | } else { |
| 270 | payload_fields.insert(col, val); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | let vector = vector.ok_or_else(|| SqlError::Parse { |
| 275 | detail: format!( |
| 276 | "vector-primary INSERT missing required vector field '{}'", |
| 277 | vpc.vector_field |
| 278 | ), |
| 279 | })?; |
| 280 |