Extract a single row value from a `DecodedColumn`. Returns `Err(ColumnarError::MsgpackDeserialize)` if a `Json` column contains bytes that cannot be decoded as MessagePack — this indicates segment corruption rather than a missing value, so `Value::Null` would silently hide the problem.
(
col: &DecodedColumn,
row_idx: usize,
col_type: &nodedb_types::columnar::ColumnType,
col_name: &str,
)
| 14 | /// segment corruption rather than a missing value, so `Value::Null` would |
| 15 | /// silently hide the problem. |
| 16 | pub(super) fn extract_row_value( |
| 17 | col: &DecodedColumn, |
| 18 | row_idx: usize, |
| 19 | col_type: &nodedb_types::columnar::ColumnType, |
| 20 | col_name: &str, |
| 21 | ) -> Result<nodedb_types::value::Value, ColumnarError> { |
| 22 | use nodedb_types::value::Value; |
| 23 | |
| 24 | let v = match col { |
| 25 | DecodedColumn::Int64 { values, valid } => { |
| 26 | if !valid[row_idx] { |
| 27 | Value::Null |
| 28 | } else { |
| 29 | Value::Integer(values[row_idx]) |
| 30 | } |
| 31 | } |
| 32 | DecodedColumn::Float64 { values, valid } => { |
| 33 | if !valid[row_idx] { |
| 34 | Value::Null |
| 35 | } else { |
| 36 | Value::Float(values[row_idx]) |
| 37 | } |
| 38 | } |
| 39 | DecodedColumn::Timestamp { values, valid } => { |
| 40 | if !valid[row_idx] { |
| 41 | Value::Null |
| 42 | } else { |
| 43 | let micros = values[row_idx]; |
| 44 | let dt = nodedb_types::datetime::NdbDateTime::from_micros(micros); |
| 45 | match col_type { |
| 46 | nodedb_types::columnar::ColumnType::Timestamptz |
| 47 | | nodedb_types::columnar::ColumnType::SystemTimestamp => Value::DateTime(dt), |
| 48 | // Timestamp (naive) and anything else that maps to i64 storage. |
| 49 | _ => Value::NaiveDateTime(dt), |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | DecodedColumn::Bool { values, valid } => { |
| 54 | if !valid[row_idx] { |
| 55 | Value::Null |
| 56 | } else { |
| 57 | Value::Bool(values[row_idx]) |
| 58 | } |
| 59 | } |
| 60 | DecodedColumn::Binary { |
| 61 | data, |
| 62 | offsets, |
| 63 | valid, |
| 64 | } => { |
| 65 | if !valid[row_idx] { |
| 66 | Value::Null |
| 67 | } else { |
| 68 | let start = offsets[row_idx] as usize; |
| 69 | let end = offsets[row_idx + 1] as usize; |
| 70 | let bytes = &data[start..end]; |
| 71 | |
| 72 | match col_type { |
| 73 | nodedb_types::columnar::ColumnType::String => { |