Encode a variable-length value, appending to the data buffer. Handles both native Value types and SQL coercion sources.
(var_data: &mut Vec<u8>, col_type: &ColumnType, value: &Value)
| 291 | /// |
| 292 | /// Handles both native Value types and SQL coercion sources. |
| 293 | fn encode_variable(var_data: &mut Vec<u8>, col_type: &ColumnType, value: &Value) { |
| 294 | match (col_type, value) { |
| 295 | (ColumnType::String, Value::String(s)) => { |
| 296 | var_data.extend_from_slice(s.as_bytes()); |
| 297 | } |
| 298 | (ColumnType::Bytes, Value::Bytes(b)) => { |
| 299 | var_data.extend_from_slice(b); |
| 300 | } |
| 301 | // Geometry: native Geometry (JSON-serialized) + String (WKT/GeoJSON passthrough). |
| 302 | (ColumnType::Geometry, Value::Geometry(g)) => { |
| 303 | if let Ok(json) = sonic_rs::to_vec(g) { |
| 304 | var_data.extend_from_slice(&json); |
| 305 | } |
| 306 | } |
| 307 | (ColumnType::Geometry, Value::String(s)) => { |
| 308 | var_data.extend_from_slice(s.as_bytes()); |
| 309 | } |
| 310 | (ColumnType::Json, Value::String(s)) => { |
| 311 | // String input for JSON column: parse as JSON, then serialize as MessagePack. |
| 312 | // This handles VALUES ('{"key":"val"}') where the SQL planner passes a string literal. |
| 313 | let parsed = sonic_rs::from_str::<serde_json::Value>(s) |
| 314 | .ok() |
| 315 | .map(nodedb_types::Value::from); |
| 316 | let to_encode = parsed.as_ref().unwrap_or(value); |
| 317 | if let Ok(bytes) = nodedb_types::value_to_msgpack(to_encode) { |
| 318 | var_data.extend_from_slice(&bytes); |
| 319 | } |
| 320 | } |
| 321 | (ColumnType::Json, value) => { |
| 322 | // Non-string input (Object, Array, etc.): serialize directly as MessagePack. |
| 323 | if let Ok(bytes) = nodedb_types::value_to_msgpack(value) { |
| 324 | var_data.extend_from_slice(&bytes); |
| 325 | } |
| 326 | } |
| 327 | _ => {} |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | #[cfg(test)] |
| 332 | mod tests { |
no test coverage detected