1use std::collections::HashMap;
10
11use crate::ast::ColumnType;
12
13use super::{ColumnIdentity, RowSchema, SchemaBuildMetadata, NULL_SLOT};
14
15impl RowSchema {
16 pub fn remap_typed_physical_identities(
20 input: &Self,
21 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
22 aliases: &[(ColumnIdentity, usize, Option<ColumnType>)],
23 ) -> Self {
24 let mut collations = input.index.cold.collations.clone();
25 collations.clear_columns();
26 for (position, (_, _, source, ty)) in columns.iter().enumerate() {
27 collations.column(
28 position,
29 input.inherited_physical_collation(*source),
30 ty.as_ref(),
31 );
32 }
33 let output_names = columns
34 .iter()
35 .map(|(output, _, _, _)| output.clone())
36 .collect();
37 let identities = columns
38 .iter()
39 .map(|(_, identity, _, _)| identity.clone())
40 .collect();
41 let slots = columns
42 .iter()
43 .map(|(_, _, physical, _)| {
44 if *physical < input.physical_width() {
45 *physical
46 } else {
47 NULL_SLOT
48 }
49 })
50 .collect();
51 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
52 let wildcard_hidden = columns
53 .iter()
54 .enumerate()
55 .filter_map(|(output, (_, _, physical, _))| {
56 input
57 .index
58 .cold
59 .wildcard_hidden
60 .iter()
61 .any(|logical| input.slot(*logical) == Some(*physical))
62 .then_some(output)
63 })
64 .collect();
65 let mut lookup_aliases = input.index.aliases.clone();
66 let mut alias_types = input.index.cold.aliases.clone();
67 for (identity, physical, ty) in aliases {
68 collations.alias(
69 identity,
70 input.inherited_physical_collation(*physical),
71 ty.as_ref(),
72 );
73 lookup_aliases.insert(
74 identity.clone(),
75 if *physical < input.physical_width() {
76 *physical
77 } else {
78 NULL_SLOT
79 },
80 );
81 alias_types.insert(identity.clone(), ty.clone());
82 }
83 Self::from_typed_parts_with_aliases_and_exact_precedence(
84 output_names,
85 identities,
86 types,
87 slots,
88 input.physical_width(),
89 SchemaBuildMetadata {
90 collations,
91 record_fields: input.index.cold.record_fields.clone(),
92 aliases: lookup_aliases,
93 alias_types,
94 internal: input.index.executor_attributes.clone(),
95 internal_types: input.index.cold.executor_attribute_types.clone(),
96 score_sources: input.index.cold.score_sources.clone(),
97 wildcard_hidden,
98 binding_only: input.index.cold.binding_only.clone(),
99 row_types: input.index.cold.row_types.clone(),
100 open_qualifiers: input.index.cold.open_qualifiers.clone(),
101 ..SchemaBuildMetadata::default()
102 },
103 )
104 }
105
106 pub fn remap_typed_identities(
108 input: &Self,
109 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
110 aliases: &[(ColumnIdentity, usize)],
111 ) -> Self {
112 let mut collations = input.index.cold.collations.clone();
113 collations.clear_columns();
114 for (position, (_, _, source, ty)) in columns.iter().enumerate() {
115 collations.column(
116 position,
117 input.inherited_column_collation(*source),
118 ty.as_ref(),
119 );
120 }
121 let output_names = columns
122 .iter()
123 .map(|(output, _, _, _)| output.clone())
124 .collect();
125 let identities = columns
126 .iter()
127 .map(|(_, identity, _, _)| identity.clone())
128 .collect();
129 let slots = columns
130 .iter()
131 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
132 .collect();
133 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
134 let wildcard_hidden = columns
135 .iter()
136 .enumerate()
137 .filter_map(|(output, (_, _, logical, _))| {
138 input
139 .index
140 .cold
141 .wildcard_hidden
142 .contains(logical)
143 .then_some(output)
144 })
145 .collect();
146 let mut lookup_aliases = input.index.aliases.clone();
147 let mut alias_types = input.index.cold.aliases.clone();
148 for (identity, logical) in aliases {
149 collations.alias(
150 identity,
151 input.inherited_column_collation(*logical),
152 input.column_type(*logical),
153 );
154 lookup_aliases.insert(identity.clone(), input.slot(*logical).unwrap_or(NULL_SLOT));
155 alias_types.insert(identity.clone(), input.column_type(*logical).cloned());
156 }
157 Self::from_typed_parts_with_aliases_and_exact_precedence(
158 output_names,
159 identities,
160 types,
161 slots,
162 input.physical_width(),
163 SchemaBuildMetadata {
164 collations,
165 record_fields: input.index.cold.record_fields.clone(),
166 aliases: lookup_aliases,
167 alias_types,
168 internal: input.index.executor_attributes.clone(),
169 internal_types: input.index.cold.executor_attribute_types.clone(),
170 score_sources: input.index.cold.score_sources.clone(),
171 wildcard_hidden,
172 binding_only: input.index.cold.binding_only.clone(),
173 row_types: input.index.cold.row_types.clone(),
174 open_qualifiers: input.index.cold.open_qualifiers.clone(),
175 ..SchemaBuildMetadata::default()
176 },
177 )
178 }
179
180 pub fn remap_typed_identities_without_input_aliases(
182 input: &Self,
183 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
184 ) -> Self {
185 let mut collations = input.index.cold.collations.clone();
186 collations.clear_columns();
187 for (position, (_, _, source, ty)) in columns.iter().enumerate() {
188 collations.column(
189 position,
190 input.inherited_column_collation(*source),
191 ty.as_ref(),
192 );
193 }
194 let output_names = columns
195 .iter()
196 .map(|(output, _, _, _)| output.clone())
197 .collect();
198 let identities = columns
199 .iter()
200 .map(|(_, identity, _, _)| identity.clone())
201 .collect();
202 let slots = columns
203 .iter()
204 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
205 .collect();
206 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
207 let wildcard_hidden = columns
208 .iter()
209 .enumerate()
210 .filter_map(|(output, (_, _, logical, _))| {
211 input
212 .index
213 .cold
214 .wildcard_hidden
215 .contains(logical)
216 .then_some(output)
217 })
218 .collect();
219 Self::from_typed_parts_with_aliases_and_exact_precedence(
220 output_names,
221 identities,
222 types,
223 slots,
224 input.physical_width(),
225 SchemaBuildMetadata {
226 collations,
227 record_fields: input.index.cold.record_fields.clone(),
228 aliases: HashMap::new(),
229 alias_types: HashMap::new(),
230 internal: input.index.executor_attributes.clone(),
231 internal_types: input.index.cold.executor_attribute_types.clone(),
232 score_sources: input.index.cold.score_sources.clone(),
233 wildcard_hidden,
234 binding_only: HashMap::new(),
235 ..SchemaBuildMetadata::default()
236 },
237 )
238 }
239}