arrow_flight/sql/metadata/
table_types.rs1use std::sync::{Arc, LazyLock};
10
11use arrow_array::{ArrayRef, RecordBatch, builder::StringBuilder};
12use arrow_schema::{DataType, Field, Schema, SchemaRef};
13use arrow_select::take::take;
14
15use crate::error::*;
16use crate::sql::CommandGetTableTypes;
17
18use super::lexsort_to_indices;
19
20#[derive(Default)]
26pub struct GetTableTypesBuilder {
27 table_type: StringBuilder,
29}
30
31impl CommandGetTableTypes {
32 pub fn into_builder(self) -> GetTableTypesBuilder {
34 self.into()
35 }
36}
37
38impl From<CommandGetTableTypes> for GetTableTypesBuilder {
39 fn from(_value: CommandGetTableTypes) -> Self {
40 Self::new()
41 }
42}
43
44impl GetTableTypesBuilder {
45 pub fn new() -> Self {
47 Self {
48 table_type: StringBuilder::new(),
49 }
50 }
51
52 pub fn append(&mut self, table_type: impl AsRef<str>) {
54 self.table_type.append_value(table_type);
55 }
56
57 pub fn build(self) -> Result<RecordBatch> {
59 let schema = self.schema();
60 let Self { mut table_type } = self;
61
62 let table_type = table_type.finish();
64
65 let batch = RecordBatch::try_new(schema, vec![Arc::new(table_type) as ArrayRef])?;
66
67 let indices = lexsort_to_indices(batch.columns());
69 let columns = batch
70 .columns()
71 .iter()
72 .map(|c| take(c, &indices, None))
73 .collect::<std::result::Result<Vec<_>, _>>()?;
74
75 Ok(RecordBatch::try_new(batch.schema(), columns)?)
76 }
77
78 pub fn schema(&self) -> SchemaRef {
81 get_table_types_schema()
82 }
83}
84
85fn get_table_types_schema() -> SchemaRef {
86 Arc::clone(&GET_TABLE_TYPES_SCHEMA)
87}
88
89static GET_TABLE_TYPES_SCHEMA: LazyLock<SchemaRef> = LazyLock::new(|| {
91 Arc::new(Schema::new(vec![Field::new(
92 "table_type",
93 DataType::Utf8,
94 false,
95 )]))
96});
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use arrow_array::StringArray;
102
103 fn get_ref_batch() -> RecordBatch {
104 RecordBatch::try_new(
105 get_table_types_schema(),
106 vec![Arc::new(StringArray::from(vec![
107 "a_table_type",
108 "b_table_type",
109 "c_table_type",
110 "d_table_type",
111 ])) as ArrayRef],
112 )
113 .unwrap()
114 }
115
116 #[test]
117 fn test_table_types_are_sorted() {
118 let ref_batch = get_ref_batch();
119
120 let mut builder = GetTableTypesBuilder::new();
121 builder.append("b_table_type");
122 builder.append("a_table_type");
123 builder.append("d_table_type");
124 builder.append("c_table_type");
125 let schema_batch = builder.build().unwrap();
126
127 assert_eq!(schema_batch, ref_batch)
128 }
129
130 #[test]
131 fn test_builder_from_query() {
132 let ref_batch = get_ref_batch();
133 let query = CommandGetTableTypes {};
134
135 let mut builder = query.into_builder();
136 builder.append("a_table_type");
137 builder.append("b_table_type");
138 builder.append("c_table_type");
139 builder.append("d_table_type");
140 let schema_batch = builder.build().unwrap();
141
142 assert_eq!(schema_batch, ref_batch)
143 }
144}