Convert a single row from a `DecodedColumn` to a `nodedb_types::value::Value`. Returns `Value::Null` if the row index is out of range or the validity bit is false.
(
col: &nodedb_columnar::reader::DecodedColumn,
row_idx: usize,
)
| 263 | /// |
| 264 | /// Returns `Value::Null` if the row index is out of range or the validity bit is false. |
| 265 | pub(in crate::data::executor) fn decoded_col_to_value( |
| 266 | col: &nodedb_columnar::reader::DecodedColumn, |
| 267 | row_idx: usize, |
| 268 | ) -> nodedb_types::value::Value { |
| 269 | use nodedb_columnar::reader::DecodedColumn; |
| 270 | use nodedb_types::value::Value; |
| 271 | |
| 272 | match col { |
| 273 | DecodedColumn::Int64 { values, valid } => { |
| 274 | if row_idx < valid.len() && valid[row_idx] { |
| 275 | Value::Integer(values[row_idx]) |
| 276 | } else { |
| 277 | Value::Null |
| 278 | } |
| 279 | } |
| 280 | DecodedColumn::Float64 { values, valid } => { |
| 281 | if row_idx < valid.len() && valid[row_idx] { |
| 282 | Value::Float(values[row_idx]) |
| 283 | } else { |
| 284 | Value::Null |
| 285 | } |
| 286 | } |
| 287 | DecodedColumn::Timestamp { values, valid } => { |
| 288 | if row_idx < valid.len() && valid[row_idx] { |
| 289 | // Represent as integer microseconds (same as Value::Integer for timestamps). |
| 290 | Value::Integer(values[row_idx]) |
| 291 | } else { |
| 292 | Value::Null |
| 293 | } |
| 294 | } |
| 295 | DecodedColumn::Bool { values, valid } => { |
| 296 | if row_idx < valid.len() && valid[row_idx] { |
| 297 | Value::Bool(values[row_idx]) |
| 298 | } else { |
| 299 | Value::Null |
| 300 | } |
| 301 | } |
| 302 | DecodedColumn::Binary { |
| 303 | data, |
| 304 | offsets, |
| 305 | valid, |
| 306 | } => { |
| 307 | if row_idx < valid.len() && valid[row_idx] && row_idx + 1 < offsets.len() { |
| 308 | let start = offsets[row_idx] as usize; |
| 309 | let end = offsets[row_idx + 1] as usize; |
| 310 | if start <= end && end <= data.len() { |
| 311 | let bytes = &data[start..end]; |
| 312 | // Best-effort UTF-8 interpretation; fall back to bytes. |
| 313 | match std::str::from_utf8(bytes) { |
| 314 | Ok(s) => Value::String(s.to_string()), |
| 315 | Err(_) => Value::Bytes(bytes.to_vec()), |
| 316 | } |
| 317 | } else { |
| 318 | Value::Null |
| 319 | } |
| 320 | } else { |
| 321 | Value::Null |
| 322 | } |
no test coverage detected