1pub mod columnar_value;
16pub mod error;
17pub mod logical_plan;
18pub mod native_histogram;
19pub mod prelude;
20pub mod prometheus;
21pub mod promql_annotations;
22pub mod request;
23pub mod stream;
24#[cfg(any(test, feature = "testing"))]
25pub mod test_util;
26
27use std::fmt::{Debug, Display, Formatter};
28use std::future::Future;
29use std::pin::Pin;
30use std::sync::Arc;
31
32use api::greptime_proto::v1::AddColumnLocation as Location;
33use api::greptime_proto::v1::add_column_location::LocationType;
34use common_error::ext::BoxedError;
35use common_recordbatch::{
36 RecordBatches, SendableRecordBatchMapper, SendableRecordBatchStream, map_dictionary_to_values,
37 map_dictionary_to_values_schema,
38};
39use datafusion::physical_plan::ExecutionPlan;
40use serde::{Deserialize, Serialize};
41use snafu::IntoError;
42use sqlparser_derive::{Visit, VisitMut};
43
44#[derive(Debug)]
46pub struct Output {
47 pub data: OutputData,
48 pub meta: OutputMeta,
49}
50
51pub enum OutputData {
54 AffectedRows(OutputRows),
55 RecordBatches(RecordBatches),
56 Stream(SendableRecordBatchStream),
57}
58
59impl OutputData {
60 pub async fn pretty_print(self) -> String {
62 match self {
63 OutputData::AffectedRows(x) => {
64 format!("Affected Rows: {x}")
65 }
66 OutputData::RecordBatches(x) => x.pretty_print().unwrap_or_else(|e| e.to_string()),
67 OutputData::Stream(x) => common_recordbatch::util::collect_batches(x)
68 .await
69 .and_then(|x| x.pretty_print())
70 .unwrap_or_else(|e| e.to_string()),
71 }
72 }
73}
74
75#[derive(Debug, Default)]
77pub struct OutputMeta {
78 pub plan: Option<Arc<dyn ExecutionPlan>>,
80 pub cost: OutputCost,
81 pub write_completions: Vec<WriteCompletion>,
84}
85
86pub struct WriteCompletion(Pin<Box<dyn Future<Output = WriteProgress> + Send>>);
88
89#[derive(Debug, Default, Clone)]
92pub struct WriteProgress {
93 pub affected_rows: usize,
94 pub error: Option<Arc<BoxedError>>,
95}
96
97impl WriteProgress {
98 pub fn failed(error: BoxedError) -> Self {
99 Self {
100 affected_rows: 0,
101 error: Some(Arc::new(error)),
102 }
103 }
104
105 pub fn merge(&mut self, other: Self) {
106 self.affected_rows += other.affected_rows;
107 if self.error.is_none() {
108 self.error = other.error;
109 }
110 }
111
112 pub fn into_result(self) -> Result<usize, BoxedError> {
113 match self.error {
114 Some(error) => Err(BoxedError::new(error::StorageWriteSnafu.into_error(error))),
115 None => Ok(self.affected_rows),
116 }
117 }
118}
119
120impl WriteCompletion {
121 pub fn new(completion: impl Future<Output = Result<(), BoxedError>> + Send + 'static) -> Self {
124 Self::with_progress(async move {
125 match completion.await {
126 Ok(()) => WriteProgress::default(),
127 Err(error) => WriteProgress::failed(error),
128 }
129 })
130 }
131
132 pub fn with_progress(completion: impl Future<Output = WriteProgress> + Send + 'static) -> Self {
133 Self(Box::pin(completion))
134 }
135
136 pub async fn progress(self) -> WriteProgress {
137 self.0.await
138 }
139
140 pub async fn wait(self) -> Result<(), BoxedError> {
142 self.0.await.into_result().map(|_| ())
143 }
144}
145
146impl Debug for WriteCompletion {
147 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
148 f.debug_struct("WriteCompletion").finish_non_exhaustive()
149 }
150}
151
152impl Output {
153 pub async fn write_progress(self) -> WriteProgress {
155 if self.meta.write_completions.is_empty() {
156 return WriteProgress {
157 affected_rows: self.extract_rows_and_cost().0,
158 error: None,
159 };
160 }
161 let mut progress = WriteProgress::default();
162 for completion in self.meta.write_completions {
163 progress.merge(completion.progress().await);
164 }
165 progress
166 }
167 pub fn new_with_affected_rows(affected_rows: OutputRows) -> Self {
168 Self {
169 data: OutputData::AffectedRows(affected_rows),
170 meta: Default::default(),
171 }
172 }
173
174 pub fn new_with_record_batches(recordbatches: RecordBatches) -> Self {
175 Self {
176 data: OutputData::RecordBatches(recordbatches),
177 meta: Default::default(),
178 }
179 }
180
181 pub fn new_with_stream(stream: SendableRecordBatchStream) -> Self {
182 Self {
183 data: OutputData::Stream(stream),
184 meta: Default::default(),
185 }
186 }
187
188 pub fn new(data: OutputData, meta: OutputMeta) -> Self {
189 Self { data, meta }
190 }
191
192 pub fn map_dictionary_to_values(self) -> common_recordbatch::error::Result<Self> {
194 let Self { data, meta } = self;
195 let data = match data {
196 OutputData::AffectedRows(rows) => OutputData::AffectedRows(rows),
197 OutputData::RecordBatches(record_batches) => {
198 let original_schema = record_batches.schema();
199 let (mapped_schema, apply_mapper) =
200 map_dictionary_to_values_schema(original_schema.clone());
201 if !apply_mapper {
202 OutputData::RecordBatches(record_batches)
203 } else {
204 let batches = record_batches
205 .into_iter()
206 .map(|batch| {
207 map_dictionary_to_values(batch, &original_schema, &mapped_schema)
208 })
209 .collect::<common_recordbatch::error::Result<Vec<_>>>()?;
210 OutputData::RecordBatches(RecordBatches::try_new(mapped_schema, batches)?)
211 }
212 }
213 OutputData::Stream(stream) => {
214 let (_, apply_mapper) = map_dictionary_to_values_schema(stream.schema());
215 if apply_mapper {
216 OutputData::Stream(Box::pin(SendableRecordBatchMapper::new(
217 stream,
218 map_dictionary_to_values,
219 map_dictionary_to_values_schema,
220 )))
221 } else {
222 OutputData::Stream(stream)
223 }
224 }
225 };
226 Ok(Self { data, meta })
227 }
228
229 pub fn extract_rows_and_cost(&self) -> (OutputRows, OutputCost) {
230 match self.data {
231 OutputData::AffectedRows(rows) => (rows, self.meta.cost),
232 _ => (0, self.meta.cost),
233 }
234 }
235}
236
237impl Debug for OutputData {
238 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
239 match self {
240 OutputData::AffectedRows(rows) => write!(f, "OutputData::AffectedRows({rows})"),
241 OutputData::RecordBatches(recordbatches) => {
242 write!(f, "OutputData::RecordBatches({recordbatches:?})")
243 }
244 OutputData::Stream(s) => {
245 write!(f, "OutputData::Stream(<{}>)", s.name())
246 }
247 }
248 }
249}
250
251impl OutputMeta {
252 pub fn new(plan: Option<Arc<dyn ExecutionPlan>>, cost: usize) -> Self {
253 Self {
254 plan,
255 cost,
256 ..Default::default()
257 }
258 }
259
260 pub fn new_with_plan(plan: Arc<dyn ExecutionPlan>) -> Self {
261 Self {
262 plan: Some(plan),
263 cost: 0,
264 ..Default::default()
265 }
266 }
267
268 pub fn new_with_cost(cost: usize) -> Self {
269 Self {
270 cost,
271 ..Default::default()
272 }
273 }
274}
275
276#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Visit, VisitMut)]
277pub enum AddColumnLocation {
278 First,
279 After { column_name: String },
280}
281
282impl Display for AddColumnLocation {
283 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
284 match self {
285 AddColumnLocation::First => write!(f, r#"FIRST"#),
286 AddColumnLocation::After { column_name } => {
287 write!(f, r#"AFTER {column_name}"#)
288 }
289 }
290 }
291}
292
293impl From<&AddColumnLocation> for Location {
294 fn from(value: &AddColumnLocation) -> Self {
295 match value {
296 AddColumnLocation::First => Location {
297 location_type: LocationType::First.into(),
298 after_column_name: String::default(),
299 },
300 AddColumnLocation::After { column_name } => Location {
301 location_type: LocationType::After.into(),
302 after_column_name: column_name.clone(),
303 },
304 }
305 }
306}
307
308pub type OutputRows = usize;
309pub type OutputCost = usize;