mz_expr_parser/
catalog.rs1use std::collections::BTreeMap;
11
12use mz_ore::cast::CastFrom;
13use mz_repr::explain::{DummyHumanizer, ExprHumanizer};
14use mz_repr::{GlobalId, RelationType, ScalarType};
15
16#[derive(Debug, Default)]
21pub struct TestCatalog {
22 objects: BTreeMap<String, (GlobalId, Vec<String>, RelationType)>,
23 names: BTreeMap<GlobalId, String>,
24}
25
26impl<'a> TestCatalog {
27 pub fn insert(
36 &mut self,
37 name: &str,
38 cols: Vec<String>,
39 typ: RelationType,
40 transient: bool,
41 ) -> Result<GlobalId, String> {
42 if self.objects.contains_key(name) {
43 return Err(format!("Object {name} already exists in catalog"));
44 }
45 let id = if transient {
46 GlobalId::Transient(u64::cast_from(self.objects.len()))
47 } else {
48 GlobalId::User(u64::cast_from(self.objects.len()))
49 };
50 self.objects.insert(name.to_string(), (id, cols, typ));
51 self.names.insert(id, name.to_string());
52 Ok(id)
53 }
54
55 pub fn get(&'a self, name: &str) -> Option<&'a (GlobalId, Vec<String>, RelationType)> {
56 self.objects.get(name)
57 }
58
59 pub fn get_source_name(&'a self, id: &GlobalId) -> Option<&'a String> {
61 self.names.get(id)
62 }
63
64 pub fn remove_transient_objects(&mut self) {
66 self.objects
67 .retain(|_, (id, _, _)| !matches!(id, GlobalId::Transient(_)));
68 self.names
69 .retain(|k, _| !matches!(k, GlobalId::Transient(_)));
70 }
71}
72
73impl ExprHumanizer for TestCatalog {
74 fn humanize_id(&self, id: GlobalId) -> Option<String> {
75 self.names.get(&id).map(|s| s.to_string())
76 }
77
78 fn humanize_id_unqualified(&self, id: GlobalId) -> Option<String> {
79 self.names.get(&id).map(|s| s.to_string())
80 }
81
82 fn humanize_id_parts(&self, id: GlobalId) -> Option<Vec<String>> {
83 self.humanize_id_unqualified(id).map(|name| vec![name])
84 }
85
86 fn humanize_scalar_type(&self, ty: &ScalarType, postgres_compat: bool) -> String {
87 DummyHumanizer.humanize_scalar_type(ty, postgres_compat)
88 }
89
90 fn column_names_for_id(&self, id: GlobalId) -> Option<Vec<String>> {
91 let src_name = self.get_source_name(&id)?;
92 self.objects.get(src_name).map(|(_, cols, _)| cols.clone())
93 }
94
95 fn humanize_column(&self, id: GlobalId, column: usize) -> Option<String> {
96 let src_name = self.get_source_name(&id)?;
97 self.objects
98 .get(src_name)
99 .map(|(_, cols, _)| cols[column].clone())
100 }
101
102 fn id_exists(&self, id: GlobalId) -> bool {
103 self.names.contains_key(&id)
104 }
105}