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 aliases: lookup_aliases,
77 alias_types,
78 internal: input.index.executor_attributes.clone(),
79 internal_types: input.index.cold.executor_attribute_types.clone(),
80 score_sources: input.index.cold.score_sources.clone(),
81 wildcard_hidden,
82 binding_only: input.index.cold.binding_only.clone(),
83 open_qualifiers: input.index.cold.open_qualifiers.clone(),
84 ..SchemaBuildMetadata::default()
85 },
86 )
87 }
88
89 pub fn remap_typed_identities(
91 input: &Self,
92 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
93 aliases: &[(ColumnIdentity, usize)],
94 ) -> Self {
95 let output_names = columns
96 .iter()
97 .map(|(output, _, _, _)| output.clone())
98 .collect();
99 let identities = columns
100 .iter()
101 .map(|(_, identity, _, _)| identity.clone())
102 .collect();
103 let slots = columns
104 .iter()
105 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
106 .collect();
107 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
108 let wildcard_hidden = columns
109 .iter()
110 .enumerate()
111 .filter_map(|(output, (_, _, logical, _))| {
112 input
113 .index
114 .cold
115 .wildcard_hidden
116 .contains(logical)
117 .then_some(output)
118 })
119 .collect();
120 let mut lookup_aliases = input.index.aliases.clone();
121 let mut alias_types = input.index.cold.aliases.clone();
122 for (identity, logical) in aliases {
123 lookup_aliases.insert(identity.clone(), input.slot(*logical).unwrap_or(NULL_SLOT));
124 alias_types.insert(identity.clone(), input.column_type(*logical).cloned());
125 }
126 Self::from_typed_parts_with_aliases_and_exact_precedence(
127 output_names,
128 identities,
129 types,
130 slots,
131 input.physical_width(),
132 SchemaBuildMetadata {
133 aliases: lookup_aliases,
134 alias_types,
135 internal: input.index.executor_attributes.clone(),
136 internal_types: input.index.cold.executor_attribute_types.clone(),
137 score_sources: input.index.cold.score_sources.clone(),
138 wildcard_hidden,
139 binding_only: input.index.cold.binding_only.clone(),
140 open_qualifiers: input.index.cold.open_qualifiers.clone(),
141 ..SchemaBuildMetadata::default()
142 },
143 )
144 }
145
146 pub fn remap_typed_identities_without_input_aliases(
148 input: &Self,
149 columns: &[(String, ColumnIdentity, usize, Option<ColumnType>)],
150 ) -> Self {
151 let output_names = columns
152 .iter()
153 .map(|(output, _, _, _)| output.clone())
154 .collect();
155 let identities = columns
156 .iter()
157 .map(|(_, identity, _, _)| identity.clone())
158 .collect();
159 let slots = columns
160 .iter()
161 .map(|(_, _, logical, _)| input.slot(*logical).unwrap_or(NULL_SLOT))
162 .collect();
163 let types = columns.iter().map(|(_, _, _, ty)| ty.clone()).collect();
164 let wildcard_hidden = columns
165 .iter()
166 .enumerate()
167 .filter_map(|(output, (_, _, logical, _))| {
168 input
169 .index
170 .cold
171 .wildcard_hidden
172 .contains(logical)
173 .then_some(output)
174 })
175 .collect();
176 Self::from_typed_parts_with_aliases_and_exact_precedence(
177 output_names,
178 identities,
179 types,
180 slots,
181 input.physical_width(),
182 SchemaBuildMetadata {
183 aliases: HashMap::new(),
184 alias_types: HashMap::new(),
185 internal: input.index.executor_attributes.clone(),
186 internal_types: input.index.cold.executor_attribute_types.clone(),
187 score_sources: input.index.cold.score_sources.clone(),
188 wildcard_hidden,
189 binding_only: HashMap::new(),
190 ..SchemaBuildMetadata::default()
191 },
192 )
193 }
194}