1use super::SQLResult;
10use crate::expr::datums::contains_datum;
11use crate::expr::enums::{contains_enum_carrier, render_enum_labels, EnumLabelCatalog};
12use crate::SQLError;
13use uqa_core::Value;
14
15pub fn render_result_enum_labels(
17 catalog: Option<&dyn EnumLabelCatalog>,
18 result: &mut SQLResult,
19) -> Result<(), SQLError> {
20 for row in &mut result.rows {
21 for value in row.values_mut() {
22 if contains_datum(value) {
23 *value = read_datums(value, catalog)?;
24 }
25 if contains_enum_carrier(value) {
26 *value = render_enum_labels(catalog, value)?;
27 }
28 }
29 }
30 for row in result.positional_rows.iter_mut().flatten() {
31 for value in row {
32 if contains_datum(value) {
33 *value = read_datums(value, catalog)?;
34 }
35 if contains_enum_carrier(value) {
36 *value = render_enum_labels(catalog, value)?;
37 }
38 }
39 }
40 Ok(())
41}
42
43fn read_datums(value: &Value, catalog: Option<&dyn EnumLabelCatalog>) -> Result<Value, SQLError> {
44 Ok(match value {
45 Value::Datum(datum) => read_datums(
46 &*crate::expr::datums::read_with_value_catalog_and_control(
47 datum,
48 catalog,
49 &uqa_core::memory::ProductionControl::uncontrolled(),
50 )?,
51 catalog,
52 )?,
53 Value::Array(array) => Value::Array(
54 uqa_core::ArrayValue::with_lower_bounds(
55 array
56 .elements()
57 .iter()
58 .map(|value| read_datums(value, catalog))
59 .collect::<Result<_, _>>()?,
60 array.lower_bounds().to_vec(),
61 )
62 .ok_or_else(|| SQLError::Internal("datum output changed array shape".into()))?
63 .with_element_type_oid(array.element_type_oid()),
64 ),
65 Value::List(values) => Value::List(
66 values
67 .iter()
68 .map(|value| read_datums(value, catalog))
69 .collect::<Result<_, _>>()?,
70 ),
71 Value::Row(values) => Value::Row(
72 values.clone().with_values(
73 values
74 .iter()
75 .map(|value| read_datums(value, catalog))
76 .collect::<Result<_, _>>()?,
77 )?,
78 ),
79 Value::Record(fields) => Value::Record(uqa_core::RecordValue::from_parts(
80 fields
81 .iter()
82 .map(|(name, value)| Ok((name.clone(), read_datums(value, catalog)?)))
83 .collect::<Result<_, SQLError>>()?,
84 fields.type_oid(),
85 )),
86 Value::Map(values) => Value::Map(
87 values
88 .iter()
89 .map(|(name, value)| Ok((name.clone(), read_datums(value, catalog)?)))
90 .collect::<Result<_, SQLError>>()?,
91 ),
92 other => other.clone(),
93 })
94}