1use datafusion_common::DFSchema;
16use datatypes::data_type::DataType;
17use datatypes::prelude::ConcreteDataType;
18use serde::{Deserialize, Serialize};
19use snafu::{ResultExt, ensure};
20
21use crate::error::{DatafusionSnafu, InternalSnafu, InvalidQuerySnafu, Result};
22
23#[derive(Default, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
25pub struct Key {
26 pub column_indices: Vec<usize>,
28}
29
30impl Key {
31 pub fn new() -> Self {
33 Default::default()
34 }
35
36 pub fn from(mut column_indices: Vec<usize>) -> Self {
38 column_indices.sort_unstable();
39 Self { column_indices }
40 }
41
42 pub fn add_col(&mut self, col: usize) {
44 self.column_indices.push(col);
45 }
46
47 pub fn remove_col(&mut self, col: usize) {
49 self.column_indices.retain(|&r| r != col);
50 }
51
52 pub fn get(&self) -> &Vec<usize> {
54 &self.column_indices
55 }
56
57 pub fn is_empty(&self) -> bool {
59 self.column_indices.is_empty()
60 }
61
62 pub fn subset_of(&self, other: &Key) -> bool {
64 self.column_indices
65 .iter()
66 .all(|c| other.column_indices.contains(c))
67 }
68}
69
70#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
72pub struct RelationType {
73 pub column_types: Vec<ColumnType>,
75 pub keys: Vec<Key>,
85 pub time_index: Option<usize>,
87 pub auto_columns: Vec<usize>,
89}
90
91impl RelationType {
92 pub fn with_autos(mut self, auto_cols: &[usize]) -> Self {
93 self.auto_columns = auto_cols.to_vec();
94 self
95 }
96
97 pub fn empty() -> Self {
100 RelationType::new(vec![])
101 }
102
103 pub fn new(column_types: Vec<ColumnType>) -> Self {
107 RelationType {
108 column_types,
109 keys: Vec::new(),
110 time_index: None,
111 auto_columns: vec![],
112 }
113 }
114
115 pub fn with_key(mut self, mut indices: Vec<usize>) -> Self {
119 if indices.is_empty() {
120 return self;
121 }
122 indices.sort_unstable();
123 let key = Key::from(indices);
124 if !self.keys.contains(&key) {
125 self.keys.push(key);
126 }
127 self
128 }
129
130 pub fn with_keys(mut self, keys: Vec<Vec<usize>>) -> Self {
134 for key in keys {
135 self = self.with_key(key)
136 }
137 self
138 }
139
140 pub fn with_time_index(mut self, time_index: Option<usize>) -> Self {
142 self.time_index = time_index;
143 for key in &mut self.keys {
144 key.remove_col(time_index.unwrap_or(usize::MAX));
145 }
146 self.keys.retain(|key| !key.is_empty());
148 self
149 }
150
151 pub fn arity(&self) -> usize {
153 self.column_types.len()
154 }
155
156 pub fn default_key(&self) -> Vec<usize> {
158 if let Some(key) = self.keys.first() {
159 if key.is_empty() {
160 (0..self.column_types.len()).collect()
161 } else {
162 key.get().clone()
163 }
164 } else {
165 (0..self.column_types.len()).collect()
166 }
167 }
168
169 pub fn subtypes(&self, other: &RelationType) -> bool {
175 if self.column_types.len() != other.column_types.len() {
176 return false;
177 }
178
179 for (col1, col2) in self.column_types.iter().zip(other.column_types.iter()) {
180 if col1.nullable && !col2.nullable {
181 return false;
182 }
183 if col1.scalar_type != col2.scalar_type {
184 return false;
185 }
186 }
187
188 let all_keys = other
189 .keys
190 .iter()
191 .all(|key1| self.keys.iter().any(|key2| key1.subset_of(key2)));
192 if !all_keys {
193 return false;
194 }
195
196 true
197 }
198
199 pub fn into_named(self, names: Vec<Option<ColumnName>>) -> RelationDesc {
201 RelationDesc { typ: self, names }
202 }
203
204 pub fn into_unnamed(self) -> RelationDesc {
206 RelationDesc {
207 names: vec![None; self.column_types.len()],
208 typ: self,
209 }
210 }
211}
212
213#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
221pub struct ColumnType {
222 pub scalar_type: ConcreteDataType,
224 #[serde(default = "return_true")]
226 pub nullable: bool,
227}
228
229impl ColumnType {
230 pub fn new(scalar_type: ConcreteDataType, nullable: bool) -> Self {
232 ColumnType {
233 scalar_type,
234 nullable,
235 }
236 }
237
238 pub fn new_nullable(scalar_type: ConcreteDataType) -> Self {
241 ColumnType {
242 scalar_type,
243 nullable: true,
244 }
245 }
246
247 pub fn scalar_type(&self) -> &ConcreteDataType {
249 &self.scalar_type
250 }
251
252 pub fn nullable(&self) -> bool {
254 self.nullable
255 }
256}
257
258#[inline(always)]
264fn return_true() -> bool {
265 true
266}
267
268#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
273pub struct RelationDesc {
274 pub typ: RelationType,
275 pub names: Vec<Option<ColumnName>>,
276}
277
278impl RelationDesc {
279 pub fn len(&self) -> Result<usize> {
280 ensure!(
281 self.typ.column_types.len() == self.names.len(),
282 InternalSnafu {
283 reason: "Expect typ and names field to be of same length"
284 }
285 );
286 Ok(self.names.len())
287 }
288
289 pub fn to_df_schema(&self) -> Result<DFSchema> {
290 let fields: Vec<_> = self
291 .iter()
292 .enumerate()
293 .map(|(i, (name, typ))| {
294 let name = name.clone().unwrap_or(format!("Col_{i}"));
295 let nullable = typ.nullable;
296 let data_type = typ.scalar_type.clone().as_arrow_type();
297 arrow_schema::Field::new(name, data_type, nullable)
298 })
299 .collect();
300 let arrow_schema = arrow_schema::Schema::new(fields);
301
302 DFSchema::try_from(arrow_schema.clone()).with_context(|_e| DatafusionSnafu {
303 context: format!("Error when converting to DFSchema: {:?}", arrow_schema),
304 })
305 }
306}
307
308impl RelationDesc {
309 pub fn empty() -> Self {
312 RelationDesc {
313 typ: RelationType::empty(),
314 names: vec![],
315 }
316 }
317
318 pub fn try_new<I, N>(typ: RelationType, names: I) -> Result<Self>
322 where
323 I: IntoIterator<Item = N>,
324 N: Into<Option<ColumnName>>,
325 {
326 let names: Vec<_> = names.into_iter().map(|name| name.into()).collect();
327 ensure!(
328 typ.arity() == names.len(),
329 InvalidQuerySnafu {
330 reason: format!(
331 "Length mismatch between RelationType {:?} and column names {:?}",
332 typ.column_types, names
333 )
334 }
335 );
336 Ok(RelationDesc { typ, names })
337 }
338
339 pub fn new_unchecked<I, N>(typ: RelationType, names: I) -> Self
347 where
348 I: IntoIterator<Item = N>,
349 N: Into<Option<ColumnName>>,
350 {
351 let names: Vec<_> = names.into_iter().map(|name| name.into()).collect();
352 assert_eq!(typ.arity(), names.len());
353 RelationDesc { typ, names }
354 }
355
356 pub fn from_names_and_types<I, T, N>(iter: I) -> Self
357 where
358 I: IntoIterator<Item = (N, T)>,
359 T: Into<ColumnType>,
360 N: Into<Option<ColumnName>>,
361 {
362 let (names, types): (Vec<_>, Vec<_>) = iter.into_iter().unzip();
363 let types = types.into_iter().map(Into::into).collect();
364 let typ = RelationType::new(types);
365 Self::new_unchecked(typ, names)
366 }
367 pub fn concat(mut self, other: Self) -> Self {
369 let self_len = self.typ.column_types.len();
370 self.names.extend(other.names);
371 self.typ.column_types.extend(other.typ.column_types);
372 for k in other.typ.keys {
373 let k = k
374 .column_indices
375 .into_iter()
376 .map(|idx| idx + self_len)
377 .collect();
378 self = self.with_key(k);
379 }
380 self
381 }
382
383 pub fn with_column<N>(mut self, name: N, column_type: ColumnType) -> Self
385 where
386 N: Into<Option<ColumnName>>,
387 {
388 self.typ.column_types.push(column_type);
389 self.names.push(name.into());
390 self
391 }
392
393 pub fn with_key(mut self, indices: Vec<usize>) -> Self {
395 self.typ = self.typ.with_key(indices);
396 self
397 }
398
399 pub fn try_with_names<I, N>(self, names: I) -> Result<Self>
403 where
404 I: IntoIterator<Item = N>,
405 N: Into<Option<ColumnName>>,
406 {
407 Self::try_new(self.typ, names)
408 }
409
410 pub fn arity(&self) -> usize {
412 self.typ.arity()
413 }
414
415 pub fn typ(&self) -> &RelationType {
417 &self.typ
418 }
419
420 pub fn iter(&self) -> impl Iterator<Item = (&Option<ColumnName>, &ColumnType)> {
422 self.iter_names().zip(self.iter_types())
423 }
424
425 pub fn iter_types(&self) -> impl Iterator<Item = &ColumnType> {
427 self.typ.column_types.iter()
428 }
429
430 pub fn iter_names(&self) -> impl Iterator<Item = &Option<ColumnName>> {
432 self.names.iter()
433 }
434
435 pub fn get_by_name(&self, name: &ColumnName) -> Option<(usize, &ColumnType)> {
441 self.iter_names()
442 .position(|n| n.as_ref() == Some(name))
443 .map(|i| (i, &self.typ.column_types[i]))
444 }
445
446 pub fn get_name(&self, i: usize) -> &Option<ColumnName> {
452 &self.names[i]
453 }
454}
455
456pub type ColumnName = String;