1use std::sync::Arc;
16
17use common_error::ext::BoxedError;
18use common_function::function::FunctionContext;
19use common_function::function_registry::FUNCTION_REGISTRY;
20use common_query::error::RegisterUdfSnafu;
21use common_query::logical_plan::SubstraitPlanDecoder;
22use datafusion::catalog::CatalogProviderList;
23use datafusion::common::DataFusionError;
24use datafusion::error::Result;
25use datafusion::execution::context::SessionState;
26use datafusion::execution::registry::SerializerRegistry;
27use datafusion::execution::{FunctionRegistry, SessionStateBuilder};
28use datafusion::logical_expr::LogicalPlan;
29use datafusion_expr::UserDefinedLogicalNode;
30use greptime_proto::substrait_extension::MergeScan as PbMergeScan;
31use promql::functions::{
32 AbsentOverTime, AvgOverTime, Changes, CountOverTime, Delta, Deriv, DoubleExponentialSmoothing,
33 IDelta, Increase, LastOverTime, MaxOverTime, MinOverTime, NativeHistogramAbsentOverTime,
34 NativeHistogramAdd, NativeHistogramAggAvg, NativeHistogramAggSum, NativeHistogramAvg,
35 NativeHistogramAvgOverTime, NativeHistogramChanges, NativeHistogramCount,
36 NativeHistogramCountOverTime, NativeHistogramDelta, NativeHistogramDivScalar,
37 NativeHistogramDrop, NativeHistogramEq, NativeHistogramFraction, NativeHistogramIDelta,
38 NativeHistogramIRate, NativeHistogramIncrease, NativeHistogramLastOverTime,
39 NativeHistogramMulScalar, NativeHistogramNeg, NativeHistogramNotEq,
40 NativeHistogramPresentOverTime, NativeHistogramQuantile, NativeHistogramRate,
41 NativeHistogramResets, NativeHistogramScalarMul, NativeHistogramStddev, NativeHistogramStdvar,
42 NativeHistogramSub, NativeHistogramSum, NativeHistogramSumOverTime, NativeHistogramToString,
43 PredictLinear, PresentOverTime, QuantileOverTime, Rate, Resets, Round, StddevOverTime,
44 StdvarOverTime, SumOverTime, quantile_udaf,
45};
46use prost::Message;
47use session::context::QueryContextRef;
48use snafu::ResultExt;
49use substrait::extension_serializer::ExtensionSerializer;
50use substrait::{DFLogicalSubstraitConvertor, SubstraitPlan};
51
52use crate::dist_plan::MergeScanLogicalPlan;
53
54#[derive(Debug)]
56pub struct DefaultSerializer;
57
58impl SerializerRegistry for DefaultSerializer {
59 fn serialize_logical_plan(&self, node: &dyn UserDefinedLogicalNode) -> Result<Vec<u8>> {
60 if node.name() == MergeScanLogicalPlan::name() {
61 let merge_scan = node
62 .as_any()
63 .downcast_ref::<MergeScanLogicalPlan>()
64 .expect("Failed to downcast to MergeScanLogicalPlan");
65
66 let input = merge_scan.input();
67 let is_placeholder = merge_scan.is_placeholder();
68 let input = DFLogicalSubstraitConvertor
69 .encode(input, DefaultSerializer)
70 .map_err(|e| DataFusionError::External(Box::new(e)))?
71 .to_vec();
72
73 Ok(PbMergeScan {
74 is_placeholder,
75 input,
76 }
77 .encode_to_vec())
78 } else {
79 ExtensionSerializer.serialize_logical_plan(node)
80 }
81 }
82
83 fn deserialize_logical_plan(
84 &self,
85 name: &str,
86 bytes: &[u8],
87 ) -> Result<Arc<dyn UserDefinedLogicalNode>> {
88 if name == MergeScanLogicalPlan::name() {
89 Err(DataFusionError::Substrait(format!(
92 "Unsupported plan node: {name}"
93 )))
94 } else {
95 ExtensionSerializer.deserialize_logical_plan(name, bytes)
96 }
97 }
98}
99
100pub struct DefaultPlanDecoder {
102 session_state: SessionState,
103 query_ctx: QueryContextRef,
104}
105
106impl DefaultPlanDecoder {
107 pub fn new(
108 session_state: SessionState,
109 query_ctx: &QueryContextRef,
110 ) -> crate::error::Result<Self> {
111 Ok(Self {
112 session_state,
113 query_ctx: query_ctx.clone(),
114 })
115 }
116}
117
118#[async_trait::async_trait]
119impl SubstraitPlanDecoder for DefaultPlanDecoder {
120 async fn decode(
121 &self,
122 message: bytes::Bytes,
123 catalog_list: Arc<dyn CatalogProviderList>,
124 optimize: bool,
125 ) -> common_query::error::Result<LogicalPlan> {
126 let mut session_state = SessionStateBuilder::new_from_existing(self.session_state.clone())
128 .with_catalog_list(catalog_list)
129 .build();
130 for func in FUNCTION_REGISTRY.scalar_functions() {
137 let udf = func.provide(FunctionContext {
138 query_ctx: self.query_ctx.clone(),
139 state: Default::default(),
140 });
141 session_state
142 .register_udf(Arc::new(udf))
143 .context(RegisterUdfSnafu { name: func.name() })?;
144 }
145
146 for func in FUNCTION_REGISTRY.aggregate_functions() {
147 let name = func.name().to_string();
148 session_state
149 .register_udaf(Arc::new(func))
150 .context(RegisterUdfSnafu { name })?;
151 }
152
153 let _ = session_state.register_udaf(quantile_udaf());
154
155 let _ = session_state.register_udf(Arc::new(IDelta::<false>::scalar_udf()));
156 let _ = session_state.register_udf(Arc::new(IDelta::<true>::scalar_udf()));
157 let _ = session_state.register_udf(Arc::new(Rate::scalar_udf()));
158 let _ = session_state.register_udf(Arc::new(Increase::scalar_udf()));
159 let _ = session_state.register_udf(Arc::new(Delta::scalar_udf()));
160 let _ = session_state.register_udf(Arc::new(Resets::scalar_udf()));
161 let _ = session_state.register_udf(Arc::new(Changes::scalar_udf()));
162 let _ = session_state.register_udf(Arc::new(Deriv::scalar_udf()));
163 let _ = session_state.register_udf(Arc::new(Round::scalar_udf()));
164 let _ = session_state.register_udf(Arc::new(AvgOverTime::scalar_udf()));
165 let _ = session_state.register_udf(Arc::new(MinOverTime::scalar_udf()));
166 let _ = session_state.register_udf(Arc::new(MaxOverTime::scalar_udf()));
167 let _ = session_state.register_udf(Arc::new(SumOverTime::scalar_udf()));
168 let _ = session_state.register_udf(Arc::new(CountOverTime::scalar_udf()));
169 let _ = session_state.register_udf(Arc::new(LastOverTime::scalar_udf()));
170 let _ = session_state.register_udf(Arc::new(AbsentOverTime::scalar_udf()));
171 let _ = session_state.register_udf(Arc::new(PresentOverTime::scalar_udf()));
172 let _ = session_state.register_udf(Arc::new(StddevOverTime::scalar_udf()));
173 let _ = session_state.register_udf(Arc::new(StdvarOverTime::scalar_udf()));
174 let _ = session_state.register_udf(Arc::new(QuantileOverTime::scalar_udf()));
175 let _ = session_state.register_udf(Arc::new(PredictLinear::scalar_udf()));
176 let double_exponential_smoothing_udf =
177 DoubleExponentialSmoothing::scalar_udf().with_aliases(["prom_holt_winters"]);
178 let _ = session_state.register_udf(Arc::new(double_exponential_smoothing_udf));
179
180 for udf in [
181 NativeHistogramAbsentOverTime::scalar_udf(),
182 NativeHistogramAdd::scalar_udf(),
183 NativeHistogramAvg::scalar_udf(),
184 NativeHistogramAvgOverTime::scalar_udf(),
185 NativeHistogramChanges::scalar_udf(),
186 NativeHistogramCount::scalar_udf(),
187 NativeHistogramCountOverTime::scalar_udf(),
188 NativeHistogramDelta::scalar_udf(),
189 NativeHistogramDivScalar::scalar_udf(),
190 NativeHistogramDrop::bool_false_udf(String::new(), None),
191 NativeHistogramDrop::float_null_udf(String::new(), None),
192 NativeHistogramEq::scalar_udf(),
193 NativeHistogramFraction::scalar_udf(),
194 NativeHistogramIDelta::scalar_udf(),
195 NativeHistogramIRate::scalar_udf(),
196 NativeHistogramIncrease::scalar_udf(),
197 NativeHistogramLastOverTime::scalar_udf(),
198 NativeHistogramMulScalar::scalar_udf(),
199 NativeHistogramNeg::scalar_udf(),
200 NativeHistogramNotEq::scalar_udf(),
201 NativeHistogramPresentOverTime::scalar_udf(),
202 NativeHistogramQuantile::scalar_udf(),
203 NativeHistogramRate::scalar_udf(),
204 NativeHistogramResets::scalar_udf(),
205 NativeHistogramScalarMul::scalar_udf(),
206 NativeHistogramStddev::scalar_udf(),
207 NativeHistogramStdvar::scalar_udf(),
208 NativeHistogramSub::scalar_udf(),
209 NativeHistogramSum::scalar_udf(),
210 NativeHistogramSumOverTime::scalar_udf(),
211 NativeHistogramToString::scalar_udf(),
212 ] {
213 let _ = session_state.register_udf(Arc::new(udf));
214 }
215 for udaf in [
216 NativeHistogramAggAvg::aggregate_udf(),
217 NativeHistogramAggSum::aggregate_udf(),
218 ] {
219 let _ = session_state.register_udaf(Arc::new(udaf));
220 }
221
222 let logical_plan = DFLogicalSubstraitConvertor
223 .decode(message, session_state)
224 .await
225 .map_err(BoxedError::new)
226 .context(common_query::error::DecodePlanSnafu)?;
227
228 if optimize {
229 self.session_state
230 .optimize(&logical_plan)
231 .map_err(Into::into)
232 } else {
233 Ok(logical_plan)
234 }
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 use common_query::native_histogram::native_histogram_value_type;
241 use datafusion::catalog::TableProvider;
242 use datafusion::datasource::MemTable;
243 use datafusion_expr::expr::ScalarFunction;
244 use datafusion_expr::{Expr, LogicalPlanBuilder, LogicalTableSource, col, lit};
245 use datatypes::arrow::datatypes::{Field, Schema, SchemaRef};
246 use datatypes::data_type::DataType;
247 use session::context::QueryContext;
248
249 use super::*;
250 use crate::QueryEngineFactory;
251 use crate::dummy_catalog::DummyCatalogList;
252 use crate::optimizer::test_util::mock_table_provider;
253 use crate::options::QueryOptions;
254
255 fn mock_plan(schema: SchemaRef) -> LogicalPlan {
256 let table_source = LogicalTableSource::new(schema);
257 let projection = None;
258 let builder =
259 LogicalPlanBuilder::scan("devices", Arc::new(table_source), projection).unwrap();
260
261 builder
262 .filter(col("k0").eq(lit("hello")))
263 .unwrap()
264 .build()
265 .unwrap()
266 }
267
268 #[tokio::test]
269 async fn test_serializer_decode_plan() {
270 let catalog_list = catalog::memory::new_memory_catalog_manager().unwrap();
271 let factory = QueryEngineFactory::new(
272 catalog_list,
273 None,
274 None,
275 None,
276 None,
277 false,
278 QueryOptions::default(),
279 );
280
281 let engine = factory.query_engine();
282
283 let table_provider = Arc::new(mock_table_provider(1.into()));
284 let plan = mock_plan(table_provider.schema().clone());
285
286 let bytes = DFLogicalSubstraitConvertor
287 .encode(&plan, DefaultSerializer)
288 .unwrap();
289
290 let plan_decoder = engine
291 .engine_context(QueryContext::arc())
292 .new_plan_decoder()
293 .unwrap();
294 let catalog_list = Arc::new(DummyCatalogList::with_table_provider(table_provider));
295
296 let decode_plan = plan_decoder
297 .decode(bytes, catalog_list, false)
298 .await
299 .unwrap();
300
301 assert_eq!(
302 "Filter: devices.k0 = Utf8(\"hello\")
303 TableScan: devices",
304 decode_plan.to_string(),
305 );
306 }
307
308 #[tokio::test]
309 async fn test_serializer_decode_native_histogram_udf() {
310 let catalog_list = catalog::memory::new_memory_catalog_manager().unwrap();
311 let factory = QueryEngineFactory::new(
312 catalog_list,
313 None,
314 None,
315 None,
316 None,
317 false,
318 QueryOptions::default(),
319 );
320 let engine = factory.query_engine();
321 let schema = Arc::new(Schema::new(vec![Field::new(
322 "histogram",
323 native_histogram_value_type().as_arrow_type(),
324 true,
325 )]));
326 let plan = LogicalPlanBuilder::scan(
327 "devices",
328 Arc::new(LogicalTableSource::new(schema.clone())),
329 None,
330 )
331 .unwrap()
332 .project(vec![
333 Expr::ScalarFunction(ScalarFunction {
334 func: Arc::new(NativeHistogramCount::scalar_udf()),
335 args: vec![col("histogram")],
336 }),
337 Expr::ScalarFunction(ScalarFunction {
338 func: Arc::new(NativeHistogramDrop::bool_false_udf(
339 "ignored annotation".to_string(),
340 None,
341 )),
342 args: vec![col("histogram")],
343 }),
344 Expr::ScalarFunction(ScalarFunction {
345 func: Arc::new(NativeHistogramDrop::float_null_udf(
346 "ignored annotation".to_string(),
347 None,
348 )),
349 args: vec![col("histogram")],
350 }),
351 ])
352 .unwrap()
353 .build()
354 .unwrap();
355 let bytes = DFLogicalSubstraitConvertor
356 .encode(&plan, DefaultSerializer)
357 .unwrap();
358 let table_provider = Arc::new(MemTable::try_new(schema, vec![vec![]]).unwrap());
359 let plan_decoder = engine
360 .engine_context(QueryContext::arc())
361 .new_plan_decoder()
362 .unwrap();
363
364 let decoded = plan_decoder
365 .decode(
366 bytes,
367 Arc::new(DummyCatalogList::with_table_provider(table_provider)),
368 false,
369 )
370 .await
371 .unwrap();
372
373 let decoded = decoded.to_string();
374 assert!(decoded.contains("prom_native_histogram_count"));
375 assert!(decoded.contains("prom_native_histogram_drop_bool"));
376 assert!(decoded.contains("prom_native_histogram_drop_float"));
377 }
378}