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