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 output_names = columns
25 .iter()
26 .map(|(output, _, _, _)| output.clone())
27 .collect();
28 let identities = columns
29 .iter()
30 .map(|(_, identity, _, _)| identity.clone())
31 .collect();
32 let slots = columns
33 .iter()
34 .map(|(_, _, physical, _)| {
35 if *physical < input.physical_width() {
36 *physical
37 } else {
38 NULL_SLOT
39 }
40 })
41 .collect();
42 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
43 let wildcard_hidden = columns
44 .iter()
45 .enumerate()
46 .filter_map(|(output, (_, _, physical, _))| {
47 input
48 .index
49 .cold
50 .wildcard_hidden
51 .iter()
52 .any(|logical| input.slot(*logical) == Some(*physical))
53 .then_some(output)
54 })
55 .collect();
56 let mut lookup_aliases = input.index.aliases.clone();
57 let mut alias_types = input.index.cold.aliases.clone();
58 for (identity, physical, ty) in aliases {
59 lookup_aliases.insert(
60 identity.clone(),
61 if *physical < input.physical_width() {
62 *physical
63 } else {
64 NULL_SLOT
65 },
66 );
67 alias_types.insert(identity.clone(), ty.clone());
68 }
69 Self::from_typed_parts_with_aliases_and_exact_precedence(
70 output_names,
71 identities,
72 types,
73 slots,
74 input.physical_width(),
75 SchemaBuildMetadata {
76 record_fields: input.index.cold.record_fields.clone(),
77 aliases: lookup_aliases,
78 alias_types,
79 internal: input.index.executor_attributes.clone(),
80 internal_types: input.index.cold.executor_attribute_types.clone(),
81 score_sources: input.index.cold.score_sources.clone(),
82 wildcard_hidden,
83 binding_only: input.index.cold.binding_only.clone(),
84 open_qualifiers: input.index.cold.open_qualifiers.clone(),
85 ..SchemaBuildMetadata::default()
86 },
87 )
88 }
89
90 pub fn remap_typed_identities(
92 input: &Self,
93 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
94 aliases: &[(ColumnIdentity, usize)],
95 ) -> Self {
96 let output_names = columns
97 .iter()
98 .map(|(output, _, _, _)| output.clone())
99 .collect();
100 let identities = columns
101 .iter()
102 .map(|(_, identity, _, _)| identity.clone())
103 .collect();
104 let slots = columns
105 .iter()
106 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
107 .collect();
108 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
109 let wildcard_hidden = columns
110 .iter()
111 .enumerate()
112 .filter_map(|(output, (_, _, logical, _))| {
113 input
114 .index
115 .cold
116 .wildcard_hidden
117 .contains(logical)
118 .then_some(output)
119 })
120 .collect();
121 let mut lookup_aliases = input.index.aliases.clone();
122 let mut alias_types = input.index.cold.aliases.clone();
123 for (identity, logical) in aliases {
124 lookup_aliases.insert(identity.clone(), input.slot(*logical).unwrap_or(NULL_SLOT));
125 alias_types.insert(identity.clone(), input.column_type(*logical).cloned());
126 }
127 Self::from_typed_parts_with_aliases_and_exact_precedence(
128 output_names,
129 identities,
130 types,
131 slots,
132 input.physical_width(),
133 SchemaBuildMetadata {
134 record_fields: input.index.cold.record_fields.clone(),
135 aliases: lookup_aliases,
136 alias_types,
137 internal: input.index.executor_attributes.clone(),
138 internal_types: input.index.cold.executor_attribute_types.clone(),
139 score_sources: input.index.cold.score_sources.clone(),
140 wildcard_hidden,
141 binding_only: input.index.cold.binding_only.clone(),
142 open_qualifiers: input.index.cold.open_qualifiers.clone(),
143 ..SchemaBuildMetadata::default()
144 },
145 )
146 }
147
148 pub fn remap_typed_identities_without_input_aliases(
150 input: &Self,
151 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
152 ) -> Self {
153 let output_names = columns
154 .iter()
155 .map(|(output, _, _, _)| output.clone())
156 .collect();
157 let identities = columns
158 .iter()
159 .map(|(_, identity, _, _)| identity.clone())
160 .collect();
161 let slots = columns
162 .iter()
163 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
164 .collect();
165 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
166 let wildcard_hidden = columns
167 .iter()
168 .enumerate()
169 .filter_map(|(output, (_, _, logical, _))| {
170 input
171 .index
172 .cold
173 .wildcard_hidden
174 .contains(logical)
175 .then_some(output)
176 })
177 .collect();
178 Self::from_typed_parts_with_aliases_and_exact_precedence(
179 output_names,
180 identities,
181 types,
182 slots,
183 input.physical_width(),
184 SchemaBuildMetadata {
185 record_fields: input.index.cold.record_fields.clone(),
186 aliases: HashMap::new(),
187 alias_types: HashMap::new(),
188 internal: input.index.executor_attributes.clone(),
189 internal_types: input.index.cold.executor_attribute_types.clone(),
190 score_sources: input.index.cold.score_sources.clone(),
191 wildcard_hidden,
192 binding_only: HashMap::new(),
193 ..SchemaBuildMetadata::default()
194 },
195 )
196 }
197}