1use crate::ast::{ColumnType, InternalColumnRef};
10use std::collections::{HashMap, HashSet};
11use std::sync::Arc;
12
13mod name_binding;
14mod open_columns;
15mod outer_scope;
16mod record_fields;
17mod schema_composition;
18mod schema_construction;
19mod schema_layout;
20mod schema_projection;
21mod schema_remap;
22pub use record_fields::RecordFields;
23
24const NULL_SLOT: usize = usize::MAX;
25
26#[derive(Debug, thiserror::Error)]
28#[error("{0}")]
29pub struct SchemaLayoutError(pub String);
30
31type SchemaLayoutResult<T> = Result<T, SchemaLayoutError>;
32
33#[derive(
35 Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
36)]
37pub struct ColumnIdentity {
38 qualifier: Option<Box<str>>,
39 column: Box<str>,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
44struct ScoreSource {
45 qualifier: Option<Box<str>>,
46 column: InternalColumnRef,
47}
48
49impl ColumnIdentity {
50 #[must_use]
51 pub fn unqualified(column: impl Into<String>) -> Self {
52 Self {
53 qualifier: None,
54 column: Box::<str>::from(column.into()),
55 }
56 }
57
58 #[must_use]
59 pub fn qualified(qualifier: impl Into<String>, column: impl Into<String>) -> Self {
60 Self {
61 qualifier: Some(Box::<str>::from(qualifier.into())),
62 column: Box::<str>::from(column.into()),
63 }
64 }
65
66 #[must_use]
67 pub fn qualifier(&self) -> Option<&str> {
68 self.qualifier.as_deref()
69 }
70
71 #[must_use]
72 pub fn column(&self) -> &str {
73 &self.column
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78struct SchemaIndex {
79 columns: Box<[String]>,
81 identities: Box<[ColumnIdentity]>,
83 slots: Box<[usize]>,
85 physical_width: usize,
86 exact: HashMap<Box<str>, usize>,
88 unqualified: HashMap<Box<str>, usize>,
89 qualified: HashMap<ColumnIdentity, usize>,
90 aliases: HashMap<ColumnIdentity, usize>,
92 executor_attributes: HashMap<InternalColumnRef, usize>,
95 ambiguous_unqualified: HashSet<Box<str>>,
97 ambiguous_qualified: HashSet<ColumnIdentity>,
99 cold: Box<SchemaColdMetadata>,
101}
102
103#[derive(Debug, Clone, PartialEq, Eq)]
104struct SchemaColdMetadata {
105 record_fields: HashMap<usize, RecordFields>,
106 columns: Box<[Option<ColumnType>]>,
108 aliases: HashMap<ColumnIdentity, Option<ColumnType>>,
109 executor_attribute_types: HashMap<InternalColumnRef, Option<ColumnType>>,
110 score_sources: Vec<ScoreSource>,
111 wildcard_hidden: HashSet<usize>,
115 binding_only: HashMap<ColumnIdentity, Option<ColumnType>>,
118 open_qualifiers: HashSet<Option<Box<str>>>,
120 identity_layout: bool,
121 local_width: Option<usize>,
123}
124
125#[derive(Default)]
126struct SchemaBuildMetadata {
127 record_fields: HashMap<usize, RecordFields>,
128 aliases: HashMap<ColumnIdentity, usize>,
129 alias_types: HashMap<ColumnIdentity, Option<ColumnType>>,
130 internal: HashMap<InternalColumnRef, usize>,
131 internal_types: HashMap<InternalColumnRef, Option<ColumnType>>,
132 score_sources: Vec<ScoreSource>,
133 wildcard_hidden: HashSet<usize>,
134 binding_only: HashMap<ColumnIdentity, Option<ColumnType>>,
135 open_qualifiers: HashSet<Option<Box<str>>>,
136 exact_unqualified_precedence: bool,
137 extra_ambiguous_unqualified: HashSet<Box<str>>,
138 extra_ambiguous_qualified: HashSet<ColumnIdentity>,
139 local_width: Option<usize>,
140}
141
142pub struct PhysicalLayout {
143 pub columns: Vec<String>,
144 pub identities: Vec<ColumnIdentity>,
145 pub types: Vec<Option<ColumnType>>,
146 pub slots: Vec<Option<usize>>,
147 pub physical_width: usize,
148 pub aliases: Vec<(ColumnIdentity, Option<usize>, Option<ColumnType>)>,
149 pub internal: Vec<(InternalColumnRef, Option<usize>, Option<ColumnType>)>,
150 pub score_sources: Vec<(Option<String>, InternalColumnRef)>,
151 pub wildcard_hidden: HashSet<usize>,
152}
153
154#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct RowSchema {
161 index: Arc<SchemaIndex>,
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq)]
166pub enum ProjectedSlot {
167 Input(Option<usize>),
168 Computed(usize),
169}
170
171impl RowSchema {
172 #[doc(hidden)]
174 pub fn layout_slots(&self) -> &[usize] {
175 &self.index.slots
176 }
177
178 #[doc(hidden)]
179 pub fn is_identity_layout(&self) -> bool {
180 self.index.cold.identity_layout
181 }
182}
183
184pub mod join_output;
185
186mod declarations;
187pub mod expressions;
188pub use declarations::{SchemaBindingContext, SchemaExpressionCatalog};
189pub mod generated;
190pub mod indexes;
191
192pub mod columns;
193pub mod composites;
194pub mod constraints;
195pub mod defaults;
196pub mod domains;
197
198pub mod dependencies;
199
200pub mod check_inheritance;
201
202pub mod table_creation;
203
204pub mod inheritance;
205
206pub mod foreign_keys;
207
208pub mod referenced_partitions;
209
210pub mod sequences;
211
212pub mod constraint_metadata;
213
214pub mod keys;
215
216pub mod constraint_changes;
217
218pub mod constraint_views;
219
220pub mod table_alteration;
221
222pub mod removal;
223
224pub mod namespaces;
225pub mod relation_alteration;
226pub mod view_creation;
227
228pub mod truncate;
229
230pub mod type_objects;
231
232pub mod foreign_servers;
233pub mod foreign_tables;
234pub mod foreign_wrappers;
235
236pub mod retention;
237
238mod type_lookup;
239pub use type_lookup::{ColumnTypeSchema, ScalarTypeSchema};