Parse a PostgreSQL range literal into a structured Value. Accepts the four standard bound forms: `[lo,hi)`, `(lo,hi]`, `[lo,hi]`, `(lo,hi)`. The bounds are stored as string tokens so the caller can interpret them as any scalar type.
(s: &str, col_name: &str)
| 41 | /// `(lo,hi)`. The bounds are stored as string tokens so the caller can |
| 42 | /// interpret them as any scalar type. |
| 43 | fn parse_range_literal(s: &str, col_name: &str) -> Result<Vec<u8>, ColumnarError> { |
| 44 | let s = s.trim(); |
| 45 | let (lower_inclusive, rest) = if let Some(r) = s.strip_prefix('[') { |
| 46 | (true, r) |
| 47 | } else if let Some(r) = s.strip_prefix('(') { |
| 48 | (false, r) |
| 49 | } else { |
| 50 | return Err(ColumnarError::RangeParse { |
| 51 | column: col_name.to_string(), |
| 52 | literal: s.to_string(), |
| 53 | }); |
| 54 | }; |
| 55 | |
| 56 | let (body, upper_inclusive) = if let Some(b) = rest.strip_suffix(']') { |
| 57 | (b, true) |
| 58 | } else if let Some(b) = rest.strip_suffix(')') { |
| 59 | (b, false) |
| 60 | } else { |
| 61 | return Err(ColumnarError::RangeParse { |
| 62 | column: col_name.to_string(), |
| 63 | literal: s.to_string(), |
| 64 | }); |
| 65 | }; |
| 66 | |
| 67 | let comma = body.find(',').ok_or_else(|| ColumnarError::RangeParse { |
| 68 | column: col_name.to_string(), |
| 69 | literal: s.to_string(), |
| 70 | })?; |
| 71 | let lower = body[..comma].trim().to_string(); |
| 72 | let upper = body[comma + 1..].trim().to_string(); |
| 73 | |
| 74 | let mut map = std::collections::HashMap::new(); |
| 75 | map.insert("lower".to_string(), Value::String(lower)); |
| 76 | map.insert("upper".to_string(), Value::String(upper)); |
| 77 | map.insert("lower_inclusive".to_string(), Value::Bool(lower_inclusive)); |
| 78 | map.insert("upper_inclusive".to_string(), Value::Bool(upper_inclusive)); |
| 79 | let structured = Value::Object(map); |
| 80 | |
| 81 | value_to_msgpack(&structured).map_err(|e| ColumnarError::MsgpackSerialize { |
| 82 | column: col_name.to_string(), |
| 83 | source: e, |
| 84 | }) |
| 85 | } |
| 86 | |
| 87 | impl ColumnData { |
| 88 | /// Push a validity bit (if the column is nullable). |
no test coverage detected