1use std::pin::Pin;
16use std::sync::Arc;
17
18use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
19use common_error::ext::BoxedError;
20use common_recordbatch::adapter::RecordBatchMetrics;
21use common_recordbatch::error::Result as RecordBatchResult;
22use common_recordbatch::{OrderOption, RecordBatch, RecordBatchStream, SendableRecordBatchStream};
23use datafusion::arrow::record_batch::RecordBatch as DfRecordBatch;
24use datatypes::arrow::array::UInt32Array;
25use datatypes::data_type::ConcreteDataType;
26use datatypes::schema::{ColumnSchema, SchemaBuilder, SchemaRef};
27use futures::Stream;
28use futures::task::{Context, Poll};
29use store_api::data_source::DataSource;
30use store_api::storage::ScanRequest;
31
32use crate::metadata::{
33 FilterPushDownType, TableId, TableInfoBuilder, TableInfoRef, TableMeta, TableType,
34};
35use crate::{Table, TableRef};
36
37const NUMBER_COLUMN: &str = "number";
38
39pub const NUMBERS_TABLE_NAME: &str = "numbers";
40
41#[derive(Debug, Clone)]
43pub struct NumbersTable;
44
45impl NumbersTable {
46 pub fn table(table_id: TableId) -> TableRef {
47 Self::table_with_name(table_id, NUMBERS_TABLE_NAME.to_string())
48 }
49
50 pub fn table_with_name(table_id: TableId, name: String) -> TableRef {
51 let data_source = Arc::new(NumbersDataSource::new(Self::schema()));
52 let table = Table::new(
53 Self::table_info(table_id, name, "test_engine".to_string()),
54 FilterPushDownType::Unsupported,
55 data_source,
56 );
57 Arc::new(table)
58 }
59
60 pub fn schema() -> SchemaRef {
61 let column_schemas = vec![ColumnSchema::new(
62 NUMBER_COLUMN,
63 ConcreteDataType::uint32_datatype(),
64 false,
65 )];
66 let schema = SchemaBuilder::try_from_columns(column_schemas)
67 .unwrap()
68 .build()
69 .unwrap();
70 Arc::new(schema)
71 }
72
73 pub fn table_info(table_id: TableId, name: String, engine: String) -> TableInfoRef {
74 let table_meta = TableMeta {
75 schema: Self::schema(),
76 primary_key_indices: vec![0],
77 value_indices: vec![],
78 engine,
79 next_column_id: 1,
80 options: Default::default(),
81 created_on: Default::default(),
82 updated_on: Default::default(),
83 partition_key_indices: vec![],
84 column_ids: vec![],
85 };
86
87 let table_info = TableInfoBuilder::default()
88 .table_id(table_id)
89 .name(name)
90 .catalog_name(DEFAULT_CATALOG_NAME)
91 .schema_name(DEFAULT_SCHEMA_NAME)
92 .table_version(0)
93 .table_type(TableType::Temporary)
94 .meta(table_meta)
95 .build()
96 .unwrap();
97 Arc::new(table_info)
98 }
99}
100
101struct NumbersDataSource {
102 schema: SchemaRef,
103}
104
105impl NumbersDataSource {
106 pub fn new(schema: SchemaRef) -> Self {
107 Self { schema }
108 }
109}
110
111impl DataSource for NumbersDataSource {
112 fn get_stream(&self, request: ScanRequest) -> Result<SendableRecordBatchStream, BoxedError> {
113 let projection = request.projection_input.map(|input| input.projection);
114 let projected_schema = match &projection {
115 Some(projection) => Arc::new(self.schema.try_project(projection).unwrap()),
116 None => self.schema.clone(),
117 };
118 Ok(Box::pin(NumbersStream {
119 limit: request.limit.unwrap_or(100) as u32,
120 schema: self.schema.clone(),
121 already_run: false,
122 projection,
123 projected_schema,
124 }))
125 }
126}
127
128struct NumbersStream {
130 limit: u32,
131 schema: SchemaRef,
132 already_run: bool,
133 projection: Option<Vec<usize>>,
134 projected_schema: SchemaRef,
135}
136
137impl RecordBatchStream for NumbersStream {
138 fn schema(&self) -> SchemaRef {
139 self.projected_schema.clone()
140 }
141
142 fn output_ordering(&self) -> Option<&[OrderOption]> {
143 None
144 }
145
146 fn metrics(&self) -> Option<RecordBatchMetrics> {
147 None
148 }
149}
150
151impl Stream for NumbersStream {
152 type Item = RecordBatchResult<RecordBatch>;
153
154 fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
155 if self.already_run {
156 return Poll::Ready(None);
157 }
158 self.already_run = true;
159 let numbers: Vec<u32> = (0..self.limit).collect();
160 let mut batch = DfRecordBatch::try_new(
161 self.schema.arrow_schema().clone(),
162 vec![Arc::new(UInt32Array::from(numbers))],
163 )
164 .unwrap();
165 if let Some(projection) = &self.projection {
166 batch = batch.project(projection).unwrap();
167 }
168
169 Poll::Ready(Some(Ok(RecordBatch::from_df_record_batch(
170 self.projected_schema.clone(),
171 batch,
172 ))))
173 }
174}