From 49a2b9456ecbacd43fd0e9d2fc6b7fcbde041c69 Mon Sep 17 00:00:00 2001 From: kould Date: Wed, 17 Dec 2025 10:06:34 +0800 Subject: [PATCH 01/12] perf: remove #[typetag::serde], Static dispatch implementation of serde using enum. --- .../physical_add_stream_column.rs | 1 - .../physical_aggregate_expand.rs | 1 - .../physical_aggregate_final.rs | 1 - .../physical_aggregate_partial.rs | 1 - .../src/physical_plans/physical_async_func.rs | 1 - .../src/physical_plans/physical_broadcast.rs | 2 - .../src/physical_plans/physical_cache_scan.rs | 1 - .../physical_column_mutation.rs | 1 - .../physical_plans/physical_commit_sink.rs | 1 - .../physical_plans/physical_compact_source.rs | 1 - .../physical_constant_table_scan.rs | 1 - .../physical_copy_into_location.rs | 1 - .../physical_copy_into_table.rs | 1 - .../physical_plans/physical_cte_consumer.rs | 1 - .../physical_distributed_insert_select.rs | 1 - .../physical_plans/physical_eval_scalar.rs | 1 - .../src/physical_plans/physical_exchange.rs | 1 - .../physical_plans/physical_exchange_sink.rs | 1 - .../physical_exchange_source.rs | 1 - .../physical_expression_scan.rs | 1 - .../src/physical_plans/physical_filter.rs | 1 - .../src/physical_plans/physical_hash_join.rs | 1 - .../src/physical_plans/physical_limit.rs | 3 +- .../physical_materialized_cte.rs | 1 - .../physical_multi_table_insert.rs | 9 - .../src/physical_plans/physical_mutation.rs | 1 - .../physical_mutation_into_organize.rs | 1 - .../physical_mutation_into_split.rs | 1 - .../physical_mutation_manipulate.rs | 1 - .../physical_mutation_source.rs | 1 - .../src/physical_plans/physical_plan.rs | 621 +++++++++++++++++- .../physical_plans/physical_project_set.rs | 1 - .../src/physical_plans/physical_r_cte_scan.rs | 1 - .../src/physical_plans/physical_range_join.rs | 1 - .../src/physical_plans/physical_recluster.rs | 2 - .../physical_replace_async_source.rs | 1 - .../physical_replace_deduplicate.rs | 1 - .../physical_plans/physical_replace_into.rs | 1 - .../src/physical_plans/physical_row_fetch.rs | 1 - .../physical_plans/physical_secure_filter.rs | 1 - .../src/physical_plans/physical_sequence.rs | 1 - .../src/physical_plans/physical_sort.rs | 1 - .../src/physical_plans/physical_table_scan.rs | 1 - .../src/physical_plans/physical_udf.rs | 1 - .../src/physical_plans/physical_union_all.rs | 1 - .../src/physical_plans/physical_window.rs | 1 - .../physical_window_partition.rs | 1 - .../src/servers/flight/v1/packets/mod.rs | 2 +- .../flight/v1/packets/packet_fragment.rs | 3 +- 49 files changed, 601 insertions(+), 83 deletions(-) diff --git a/src/query/service/src/physical_plans/physical_add_stream_column.rs b/src/query/service/src/physical_plans/physical_add_stream_column.rs index 6b91b0703470b..be64e12bdb81e 100644 --- a/src/query/service/src/physical_plans/physical_add_stream_column.rs +++ b/src/query/service/src/physical_plans/physical_add_stream_column.rs @@ -55,7 +55,6 @@ pub struct AddStreamColumn { pub stream_columns: Vec, } -#[typetag::serde] impl IPhysicalPlan for AddStreamColumn { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_aggregate_expand.rs b/src/query/service/src/physical_plans/physical_aggregate_expand.rs index 9f5a6ce5069d2..bc89ea8d4a84f 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_expand.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_expand.rs @@ -45,7 +45,6 @@ pub struct AggregateExpand { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for AggregateExpand { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_aggregate_final.rs b/src/query/service/src/physical_plans/physical_aggregate_final.rs index a87b6b6b8cc6f..ae2c7ed5d43aa 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_final.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_final.rs @@ -64,7 +64,6 @@ pub struct AggregateFinal { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for AggregateFinal { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_aggregate_partial.rs b/src/query/service/src/physical_plans/physical_aggregate_partial.rs index fbaeb0157d5a1..e041e64ca2480 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_partial.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_partial.rs @@ -67,7 +67,6 @@ pub struct AggregatePartial { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for AggregatePartial { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_async_func.rs b/src/query/service/src/physical_plans/physical_async_func.rs index d3595c2436225..fb2a49b4a41b9 100644 --- a/src/query/service/src/physical_plans/physical_async_func.rs +++ b/src/query/service/src/physical_plans/physical_async_func.rs @@ -46,7 +46,6 @@ pub struct AsyncFunction { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for AsyncFunction { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_broadcast.rs b/src/query/service/src/physical_plans/physical_broadcast.rs index 88f961c5103ed..369c2f66a16c3 100644 --- a/src/query/service/src/physical_plans/physical_broadcast.rs +++ b/src/query/service/src/physical_plans/physical_broadcast.rs @@ -35,7 +35,6 @@ pub struct BroadcastSource { pub broadcast_id: u32, } -#[typetag::serde] impl IPhysicalPlan for BroadcastSource { fn as_any(&self) -> &dyn Any { self @@ -75,7 +74,6 @@ pub struct BroadcastSink { pub input: PhysicalPlan, } -#[typetag::serde] impl IPhysicalPlan for BroadcastSink { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_cache_scan.rs b/src/query/service/src/physical_plans/physical_cache_scan.rs index 6988ab483fbdf..8ce47add85ef6 100644 --- a/src/query/service/src/physical_plans/physical_cache_scan.rs +++ b/src/query/service/src/physical_plans/physical_cache_scan.rs @@ -41,7 +41,6 @@ pub struct CacheScan { pub output_schema: DataSchemaRef, } -#[typetag::serde] impl IPhysicalPlan for CacheScan { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_column_mutation.rs b/src/query/service/src/physical_plans/physical_column_mutation.rs index c1bb9b709ec8b..791fb423920c1 100644 --- a/src/query/service/src/physical_plans/physical_column_mutation.rs +++ b/src/query/service/src/physical_plans/physical_column_mutation.rs @@ -52,7 +52,6 @@ pub struct ColumnMutation { pub udf_col_num: usize, } -#[typetag::serde] impl IPhysicalPlan for ColumnMutation { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_commit_sink.rs b/src/query/service/src/physical_plans/physical_commit_sink.rs index c8f584484b0f0..ac4928807af7e 100644 --- a/src/query/service/src/physical_plans/physical_commit_sink.rs +++ b/src/query/service/src/physical_plans/physical_commit_sink.rs @@ -58,7 +58,6 @@ pub struct CommitSink { pub recluster_info: Option, } -#[typetag::serde] impl IPhysicalPlan for CommitSink { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_compact_source.rs b/src/query/service/src/physical_plans/physical_compact_source.rs index 52fa41a4b8533..50c4723f28dac 100644 --- a/src/query/service/src/physical_plans/physical_compact_source.rs +++ b/src/query/service/src/physical_plans/physical_compact_source.rs @@ -59,7 +59,6 @@ pub struct CompactSource { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for CompactSource { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_constant_table_scan.rs b/src/query/service/src/physical_plans/physical_constant_table_scan.rs index fd9865d9e3c8b..86b18bc3254b6 100644 --- a/src/query/service/src/physical_plans/physical_constant_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_constant_table_scan.rs @@ -38,7 +38,6 @@ pub struct ConstantTableScan { pub output_schema: DataSchemaRef, } -#[typetag::serde] impl IPhysicalPlan for ConstantTableScan { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_copy_into_location.rs b/src/query/service/src/physical_plans/physical_copy_into_location.rs index 982beaa49d70c..ee4ed64edb7ad 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_location.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_location.rs @@ -45,7 +45,6 @@ pub struct CopyIntoLocation { pub info: CopyIntoLocationInfo, } -#[typetag::serde] impl IPhysicalPlan for CopyIntoLocation { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_copy_into_table.rs b/src/query/service/src/physical_plans/physical_copy_into_table.rs index a5b3bdaa34e3a..8e45028be76d1 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_table.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_table.rs @@ -51,7 +51,6 @@ pub struct CopyIntoTable { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for CopyIntoTable { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_cte_consumer.rs b/src/query/service/src/physical_plans/physical_cte_consumer.rs index 9d221cf5fee05..6304d2563db06 100644 --- a/src/query/service/src/physical_plans/physical_cte_consumer.rs +++ b/src/query/service/src/physical_plans/physical_cte_consumer.rs @@ -42,7 +42,6 @@ pub struct MaterializeCTERef { pub meta: PhysicalPlanMeta, } -#[typetag::serde] impl IPhysicalPlan for MaterializeCTERef { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs index 3c7280778f4a6..66a628e74a86a 100644 --- a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs +++ b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs @@ -40,7 +40,6 @@ pub struct DistributedInsertSelect { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for DistributedInsertSelect { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_eval_scalar.rs b/src/query/service/src/physical_plans/physical_eval_scalar.rs index dfa77296fbf31..7dd418ee01e7a 100644 --- a/src/query/service/src/physical_plans/physical_eval_scalar.rs +++ b/src/query/service/src/physical_plans/physical_eval_scalar.rs @@ -65,7 +65,6 @@ pub struct EvalScalar { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for EvalScalar { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_exchange.rs b/src/query/service/src/physical_plans/physical_exchange.rs index ba19faecbb359..62ee27d393daa 100644 --- a/src/query/service/src/physical_plans/physical_exchange.rs +++ b/src/query/service/src/physical_plans/physical_exchange.rs @@ -41,7 +41,6 @@ pub struct Exchange { pub allow_adjust_parallelism: bool, } -#[typetag::serde] impl IPhysicalPlan for Exchange { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_exchange_sink.rs b/src/query/service/src/physical_plans/physical_exchange_sink.rs index 17f2e3b51d9e5..5a30fb0bff35a 100644 --- a/src/query/service/src/physical_plans/physical_exchange_sink.rs +++ b/src/query/service/src/physical_plans/physical_exchange_sink.rs @@ -45,7 +45,6 @@ pub struct ExchangeSink { pub allow_adjust_parallelism: bool, } -#[typetag::serde] impl IPhysicalPlan for ExchangeSink { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_exchange_source.rs b/src/query/service/src/physical_plans/physical_exchange_source.rs index 79076f92fb2b4..89421c7650d73 100644 --- a/src/query/service/src/physical_plans/physical_exchange_source.rs +++ b/src/query/service/src/physical_plans/physical_exchange_source.rs @@ -37,7 +37,6 @@ pub struct ExchangeSource { pub query_id: String, } -#[typetag::serde] impl IPhysicalPlan for ExchangeSource { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_expression_scan.rs b/src/query/service/src/physical_plans/physical_expression_scan.rs index 8d13ffbe9ed7f..a92073ec66b74 100644 --- a/src/query/service/src/physical_plans/physical_expression_scan.rs +++ b/src/query/service/src/physical_plans/physical_expression_scan.rs @@ -41,7 +41,6 @@ pub struct ExpressionScan { pub output_schema: DataSchemaRef, } -#[typetag::serde] impl IPhysicalPlan for ExpressionScan { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_filter.rs b/src/query/service/src/physical_plans/physical_filter.rs index d9d0f15d9edff..ca63475d6e1c5 100644 --- a/src/query/service/src/physical_plans/physical_filter.rs +++ b/src/query/service/src/physical_plans/physical_filter.rs @@ -48,7 +48,6 @@ pub struct Filter { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for Filter { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_hash_join.rs b/src/query/service/src/physical_plans/physical_hash_join.rs index 9a2e5802f105f..979b594c47aa0 100644 --- a/src/query/service/src/physical_plans/physical_hash_join.rs +++ b/src/query/service/src/physical_plans/physical_hash_join.rs @@ -142,7 +142,6 @@ pub struct HashJoin { pub broadcast_id: Option, } -#[typetag::serde] impl IPhysicalPlan for HashJoin { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_limit.rs b/src/query/service/src/physical_plans/physical_limit.rs index 33dd52a60d495..b752fc2c5ebd5 100644 --- a/src/query/service/src/physical_plans/physical_limit.rs +++ b/src/query/service/src/physical_plans/physical_limit.rs @@ -38,7 +38,7 @@ use crate::pipelines::PipelineBuilder; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct Limit { - meta: PhysicalPlanMeta, + pub(crate) meta: PhysicalPlanMeta, pub input: PhysicalPlan, pub limit: Option, pub offset: usize, @@ -47,7 +47,6 @@ pub struct Limit { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for Limit { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_materialized_cte.rs b/src/query/service/src/physical_plans/physical_materialized_cte.rs index fc6f6b476db38..85aa1591ef68a 100644 --- a/src/query/service/src/physical_plans/physical_materialized_cte.rs +++ b/src/query/service/src/physical_plans/physical_materialized_cte.rs @@ -44,7 +44,6 @@ pub struct MaterializedCTE { pub meta: PhysicalPlanMeta, } -#[typetag::serde] impl IPhysicalPlan for MaterializedCTE { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_multi_table_insert.rs b/src/query/service/src/physical_plans/physical_multi_table_insert.rs index d9959e5b95a11..97177e4c03e75 100644 --- a/src/query/service/src/physical_plans/physical_multi_table_insert.rs +++ b/src/query/service/src/physical_plans/physical_multi_table_insert.rs @@ -59,7 +59,6 @@ pub struct Duplicate { pub n: usize, } -#[typetag::serde] impl IPhysicalPlan for Duplicate { fn as_any(&self) -> &dyn Any { self @@ -108,7 +107,6 @@ pub struct Shuffle { pub strategy: ShuffleStrategy, } -#[typetag::serde] impl IPhysicalPlan for Shuffle { fn as_any(&self) -> &dyn Any { self @@ -191,7 +189,6 @@ pub struct ChunkFilter { pub predicates: Vec>, } -#[typetag::serde] impl IPhysicalPlan for ChunkFilter { fn as_any(&self) -> &dyn Any { self @@ -256,7 +253,6 @@ pub struct ChunkEvalScalar { pub eval_scalars: Vec>, } -#[typetag::serde] impl IPhysicalPlan for ChunkEvalScalar { fn as_any(&self) -> &dyn Any { self @@ -328,7 +324,6 @@ pub struct ChunkCastSchema { pub cast_schemas: Vec>, } -#[typetag::serde] impl IPhysicalPlan for ChunkCastSchema { fn as_any(&self) -> &dyn Any { self @@ -401,7 +396,6 @@ pub struct ChunkFillAndReorder { pub fill_and_reorders: Vec>, } -#[typetag::serde] impl IPhysicalPlan for ChunkFillAndReorder { fn as_any(&self) -> &dyn Any { self @@ -478,7 +472,6 @@ pub struct ChunkAppendData { pub target_tables: Vec, } -#[typetag::serde] impl IPhysicalPlan for ChunkAppendData { fn as_any(&self) -> &dyn Any { self @@ -637,7 +630,6 @@ pub struct ChunkMerge { pub group_ids: Vec, } -#[typetag::serde] impl IPhysicalPlan for ChunkMerge { fn as_any(&self) -> &dyn Any { self @@ -709,7 +701,6 @@ pub struct ChunkCommitInsert { pub targets: Vec, } -#[typetag::serde] impl IPhysicalPlan for ChunkCommitInsert { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_mutation.rs b/src/query/service/src/physical_plans/physical_mutation.rs index 8ce678a6d1c5a..44233c54749ce 100644 --- a/src/query/service/src/physical_plans/physical_mutation.rs +++ b/src/query/service/src/physical_plans/physical_mutation.rs @@ -108,7 +108,6 @@ pub struct Mutation { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for Mutation { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs index b5770451d56bf..109008955e1b3 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs @@ -31,7 +31,6 @@ pub struct MutationOrganize { pub strategy: MutationStrategy, } -#[typetag::serde] impl IPhysicalPlan for MutationOrganize { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_mutation_into_split.rs b/src/query/service/src/physical_plans/physical_mutation_into_split.rs index e86c70641ab64..ae1386499e434 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_split.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_split.rs @@ -33,7 +33,6 @@ pub struct MutationSplit { pub split_index: IndexType, } -#[typetag::serde] impl IPhysicalPlan for MutationSplit { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs index cad8392e9133a..097be7b288812 100644 --- a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs +++ b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs @@ -54,7 +54,6 @@ pub struct MutationManipulate { pub target_table_index: usize, } -#[typetag::serde] impl IPhysicalPlan for MutationManipulate { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_mutation_source.rs b/src/query/service/src/physical_plans/physical_mutation_source.rs index 68ab0c632f610..44f725a28654a 100644 --- a/src/query/service/src/physical_plans/physical_mutation_source.rs +++ b/src/query/service/src/physical_plans/physical_mutation_source.rs @@ -74,7 +74,6 @@ pub struct MutationSource { pub statistics: PartStatistics, } -#[typetag::serde] impl IPhysicalPlan for MutationSource { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 27cc04c134d07..12a8ee0a76b64 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -16,8 +16,6 @@ use std::any::Any; use std::collections::HashMap; use std::fmt::Debug; use std::fmt::Formatter; -use std::ops::Deref; -use std::ops::DerefMut; use std::sync::Arc; use databend_common_ast::ast::FormatTreeNode; @@ -31,8 +29,10 @@ use databend_common_pipeline::core::PlanProfile; use databend_common_pipeline::core::PlanScope; use databend_common_sql::Metadata; use dyn_clone::DynClone; +use serde::de::Error as DeError; use serde::Deserializer; use serde::Serializer; +use serde_json::Value as JsonValue; use crate::physical_plans::ExchangeSink; use crate::physical_plans::MutationSource; @@ -70,8 +70,7 @@ pub trait DeriveHandle: Send + Sync + 'static { ) -> std::result::Result>; } -#[typetag::serde] -pub trait IPhysicalPlan: DynClone + Debug + Send + Sync + 'static { +pub(crate) trait IPhysicalPlan: DynClone + Debug + Send + Sync + 'static { fn as_any(&self) -> &dyn Any; fn get_meta(&self) -> &PhysicalPlanMeta; @@ -269,8 +268,252 @@ impl PhysicalPlanCast for T { } } +macro_rules! define_physical_plan_impl { + ( $( $variant:ident => $path:path ),+ $(,)? ) => { + #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] + pub(crate) enum PhysicalPlanImpl { + $( $variant($path), )+ + #[cfg(test)] + StackDepthPlan(crate::physical_plans::physical_plan::tests::StackDepthPlan), + } + + $( impl From<$path> for PhysicalPlanImpl { + fn from(v: $path) -> Self { + PhysicalPlanImpl::$variant(v) + } + })+ + + impl PhysicalPlanImpl { + fn try_from_typetag_value( + type_name: &str, + value: JsonValue, + ) -> std::result::Result, E> { + $({ + if type_name == std::any::type_name::<$path>() + || type_name == stringify!($variant) + { + let value = serde_json::from_value::<$path>(value).map_err(E::custom)?; + return Ok(Some(PhysicalPlanImpl::$variant(value))); + } + })+ + + #[cfg(test)] + if type_name + == std::any::type_name::() + || type_name == stringify!(StackDepthPlan) + { + let value = serde_json::from_value::(value) + .map_err(E::custom)?; + return Ok(Some(PhysicalPlanImpl::StackDepthPlan(value))); + } + + Ok(None) + } + } + }; +} + +define_physical_plan_impl!( + AddStreamColumn => crate::physical_plans::physical_add_stream_column::AddStreamColumn, + AggregateExpand => crate::physical_plans::physical_aggregate_expand::AggregateExpand, + AggregateFinal => crate::physical_plans::physical_aggregate_final::AggregateFinal, + AggregatePartial => crate::physical_plans::physical_aggregate_partial::AggregatePartial, + AsyncFunction => crate::physical_plans::physical_async_func::AsyncFunction, + BroadcastSink => crate::physical_plans::physical_broadcast::BroadcastSink, + BroadcastSource => crate::physical_plans::physical_broadcast::BroadcastSource, + CacheScan => crate::physical_plans::physical_cache_scan::CacheScan, + ChunkAppendData => crate::physical_plans::physical_multi_table_insert::ChunkAppendData, + ChunkCastSchema => crate::physical_plans::physical_multi_table_insert::ChunkCastSchema, + ChunkCommitInsert => crate::physical_plans::physical_multi_table_insert::ChunkCommitInsert, + ChunkEvalScalar => crate::physical_plans::physical_multi_table_insert::ChunkEvalScalar, + ChunkFillAndReorder => crate::physical_plans::physical_multi_table_insert::ChunkFillAndReorder, + ChunkFilter => crate::physical_plans::physical_multi_table_insert::ChunkFilter, + ChunkMerge => crate::physical_plans::physical_multi_table_insert::ChunkMerge, + ColumnMutation => crate::physical_plans::physical_column_mutation::ColumnMutation, + CommitSink => crate::physical_plans::physical_commit_sink::CommitSink, + CompactSource => crate::physical_plans::physical_compact_source::CompactSource, + ConstantTableScan => crate::physical_plans::physical_constant_table_scan::ConstantTableScan, + CopyIntoLocation => crate::physical_plans::physical_copy_into_location::CopyIntoLocation, + CopyIntoTable => crate::physical_plans::physical_copy_into_table::CopyIntoTable, + DistributedInsertSelect => crate::physical_plans::physical_distributed_insert_select::DistributedInsertSelect, + Duplicate => crate::physical_plans::physical_multi_table_insert::Duplicate, + EvalScalar => crate::physical_plans::physical_eval_scalar::EvalScalar, + Exchange => crate::physical_plans::physical_exchange::Exchange, + ExchangeSink => crate::physical_plans::physical_exchange_sink::ExchangeSink, + ExchangeSource => crate::physical_plans::physical_exchange_source::ExchangeSource, + ExpressionScan => crate::physical_plans::physical_expression_scan::ExpressionScan, + Filter => crate::physical_plans::physical_filter::Filter, + HashJoin => crate::physical_plans::physical_hash_join::HashJoin, + HilbertPartition => crate::physical_plans::physical_recluster::HilbertPartition, + Limit => crate::physical_plans::physical_limit::Limit, + MaterializeCTERef => crate::physical_plans::physical_cte_consumer::MaterializeCTERef, + MaterializedCTE => crate::physical_plans::physical_materialized_cte::MaterializedCTE, + Mutation => crate::physical_plans::physical_mutation::Mutation, + MutationManipulate => crate::physical_plans::physical_mutation_manipulate::MutationManipulate, + MutationOrganize => crate::physical_plans::physical_mutation_into_organize::MutationOrganize, + MutationSource => crate::physical_plans::physical_mutation_source::MutationSource, + MutationSplit => crate::physical_plans::physical_mutation_into_split::MutationSplit, + ProjectSet => crate::physical_plans::physical_project_set::ProjectSet, + RangeJoin => crate::physical_plans::physical_range_join::RangeJoin, + Recluster => crate::physical_plans::physical_recluster::Recluster, + RecursiveCteScan => crate::physical_plans::physical_r_cte_scan::RecursiveCteScan, + ReplaceAsyncSourcer => crate::physical_plans::physical_replace_async_source::ReplaceAsyncSourcer, + ReplaceDeduplicate => crate::physical_plans::physical_replace_deduplicate::ReplaceDeduplicate, + ReplaceInto => crate::physical_plans::physical_replace_into::ReplaceInto, + RowFetch => crate::physical_plans::physical_row_fetch::RowFetch, + SecureFilter => crate::physical_plans::physical_secure_filter::SecureFilter, + Sequence => crate::physical_plans::physical_sequence::Sequence, + SerializedPhysicalPlanRef => crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef, + Shuffle => crate::physical_plans::physical_multi_table_insert::Shuffle, + Sort => crate::physical_plans::physical_sort::Sort, + TableScan => crate::physical_plans::physical_table_scan::TableScan, + Udf => crate::physical_plans::physical_udf::Udf, + UnionAll => crate::physical_plans::physical_union_all::UnionAll, + Window => crate::physical_plans::physical_window::Window, + WindowPartition => crate::physical_plans::physical_window_partition::WindowPartition, +); + +macro_rules! dispatch_plan_ref { + ($s:expr, $plan:ident => $body:expr) => { + match $s.inner.as_ref() { + PhysicalPlanImpl::AddStreamColumn($plan) => $body, + PhysicalPlanImpl::AggregateExpand($plan) => $body, + PhysicalPlanImpl::AggregateFinal($plan) => $body, + PhysicalPlanImpl::AggregatePartial($plan) => $body, + PhysicalPlanImpl::AsyncFunction($plan) => $body, + PhysicalPlanImpl::BroadcastSink($plan) => $body, + PhysicalPlanImpl::BroadcastSource($plan) => $body, + PhysicalPlanImpl::CacheScan($plan) => $body, + PhysicalPlanImpl::ChunkAppendData($plan) => $body, + PhysicalPlanImpl::ChunkCastSchema($plan) => $body, + PhysicalPlanImpl::ChunkCommitInsert($plan) => $body, + PhysicalPlanImpl::ChunkEvalScalar($plan) => $body, + PhysicalPlanImpl::ChunkFillAndReorder($plan) => $body, + PhysicalPlanImpl::ChunkFilter($plan) => $body, + PhysicalPlanImpl::ChunkMerge($plan) => $body, + PhysicalPlanImpl::ColumnMutation($plan) => $body, + PhysicalPlanImpl::CommitSink($plan) => $body, + PhysicalPlanImpl::CompactSource($plan) => $body, + PhysicalPlanImpl::ConstantTableScan($plan) => $body, + PhysicalPlanImpl::CopyIntoLocation($plan) => $body, + PhysicalPlanImpl::CopyIntoTable($plan) => $body, + PhysicalPlanImpl::DistributedInsertSelect($plan) => $body, + PhysicalPlanImpl::Duplicate($plan) => $body, + PhysicalPlanImpl::EvalScalar($plan) => $body, + PhysicalPlanImpl::Exchange($plan) => $body, + PhysicalPlanImpl::ExchangeSink($plan) => $body, + PhysicalPlanImpl::ExchangeSource($plan) => $body, + PhysicalPlanImpl::ExpressionScan($plan) => $body, + PhysicalPlanImpl::Filter($plan) => $body, + PhysicalPlanImpl::HashJoin($plan) => $body, + PhysicalPlanImpl::HilbertPartition($plan) => $body, + PhysicalPlanImpl::Limit($plan) => $body, + PhysicalPlanImpl::MaterializeCTERef($plan) => $body, + PhysicalPlanImpl::MaterializedCTE($plan) => $body, + PhysicalPlanImpl::Mutation($plan) => $body, + PhysicalPlanImpl::MutationManipulate($plan) => $body, + PhysicalPlanImpl::MutationOrganize($plan) => $body, + PhysicalPlanImpl::MutationSource($plan) => $body, + PhysicalPlanImpl::MutationSplit($plan) => $body, + PhysicalPlanImpl::ProjectSet($plan) => $body, + PhysicalPlanImpl::RangeJoin($plan) => $body, + PhysicalPlanImpl::Recluster($plan) => $body, + PhysicalPlanImpl::RecursiveCteScan($plan) => $body, + PhysicalPlanImpl::ReplaceAsyncSourcer($plan) => $body, + PhysicalPlanImpl::ReplaceDeduplicate($plan) => $body, + PhysicalPlanImpl::ReplaceInto($plan) => $body, + PhysicalPlanImpl::RowFetch($plan) => $body, + PhysicalPlanImpl::SecureFilter($plan) => $body, + PhysicalPlanImpl::Sequence($plan) => $body, + PhysicalPlanImpl::SerializedPhysicalPlanRef($plan) => $body, + PhysicalPlanImpl::Shuffle($plan) => $body, + PhysicalPlanImpl::Sort($plan) => $body, + PhysicalPlanImpl::TableScan($plan) => $body, + PhysicalPlanImpl::Udf($plan) => $body, + PhysicalPlanImpl::UnionAll($plan) => $body, + PhysicalPlanImpl::Window($plan) => $body, + PhysicalPlanImpl::WindowPartition($plan) => $body, + #[cfg(test)] + PhysicalPlanImpl::StackDepthPlan($plan) => $body, + } + }; +} + +macro_rules! dispatch_plan_mut { + ($s:expr, $plan:ident => $body:expr) => { + match $s.inner.as_mut() { + PhysicalPlanImpl::AddStreamColumn($plan) => $body, + PhysicalPlanImpl::AggregateExpand($plan) => $body, + PhysicalPlanImpl::AggregateFinal($plan) => $body, + PhysicalPlanImpl::AggregatePartial($plan) => $body, + PhysicalPlanImpl::AsyncFunction($plan) => $body, + PhysicalPlanImpl::BroadcastSink($plan) => $body, + PhysicalPlanImpl::BroadcastSource($plan) => $body, + PhysicalPlanImpl::CacheScan($plan) => $body, + PhysicalPlanImpl::ChunkAppendData($plan) => $body, + PhysicalPlanImpl::ChunkCastSchema($plan) => $body, + PhysicalPlanImpl::ChunkCommitInsert($plan) => $body, + PhysicalPlanImpl::ChunkEvalScalar($plan) => $body, + PhysicalPlanImpl::ChunkFillAndReorder($plan) => $body, + PhysicalPlanImpl::ChunkFilter($plan) => $body, + PhysicalPlanImpl::ChunkMerge($plan) => $body, + PhysicalPlanImpl::ColumnMutation($plan) => $body, + PhysicalPlanImpl::CommitSink($plan) => $body, + PhysicalPlanImpl::CompactSource($plan) => $body, + PhysicalPlanImpl::ConstantTableScan($plan) => $body, + PhysicalPlanImpl::CopyIntoLocation($plan) => $body, + PhysicalPlanImpl::CopyIntoTable($plan) => $body, + PhysicalPlanImpl::DistributedInsertSelect($plan) => $body, + PhysicalPlanImpl::Duplicate($plan) => $body, + PhysicalPlanImpl::EvalScalar($plan) => $body, + PhysicalPlanImpl::Exchange($plan) => $body, + PhysicalPlanImpl::ExchangeSink($plan) => $body, + PhysicalPlanImpl::ExchangeSource($plan) => $body, + PhysicalPlanImpl::ExpressionScan($plan) => $body, + PhysicalPlanImpl::Filter($plan) => $body, + PhysicalPlanImpl::HashJoin($plan) => $body, + PhysicalPlanImpl::HilbertPartition($plan) => $body, + PhysicalPlanImpl::Limit($plan) => $body, + PhysicalPlanImpl::MaterializeCTERef($plan) => $body, + PhysicalPlanImpl::MaterializedCTE($plan) => $body, + PhysicalPlanImpl::Mutation($plan) => $body, + PhysicalPlanImpl::MutationManipulate($plan) => $body, + PhysicalPlanImpl::MutationOrganize($plan) => $body, + PhysicalPlanImpl::MutationSource($plan) => $body, + PhysicalPlanImpl::MutationSplit($plan) => $body, + PhysicalPlanImpl::ProjectSet($plan) => $body, + PhysicalPlanImpl::RangeJoin($plan) => $body, + PhysicalPlanImpl::Recluster($plan) => $body, + PhysicalPlanImpl::RecursiveCteScan($plan) => $body, + PhysicalPlanImpl::ReplaceAsyncSourcer($plan) => $body, + PhysicalPlanImpl::ReplaceDeduplicate($plan) => $body, + PhysicalPlanImpl::ReplaceInto($plan) => $body, + PhysicalPlanImpl::RowFetch($plan) => $body, + PhysicalPlanImpl::SecureFilter($plan) => $body, + PhysicalPlanImpl::Sequence($plan) => $body, + PhysicalPlanImpl::SerializedPhysicalPlanRef($plan) => $body, + PhysicalPlanImpl::Shuffle($plan) => $body, + PhysicalPlanImpl::Sort($plan) => $body, + PhysicalPlanImpl::TableScan($plan) => $body, + PhysicalPlanImpl::Udf($plan) => $body, + PhysicalPlanImpl::UnionAll($plan) => $body, + PhysicalPlanImpl::Window($plan) => $body, + PhysicalPlanImpl::WindowPartition($plan) => $body, + #[cfg(test)] + PhysicalPlanImpl::StackDepthPlan($plan) => $body, + } + }; +} + +#[cfg(test)] +impl From for PhysicalPlanImpl { + fn from(v: crate::physical_plans::physical_plan::tests::StackDepthPlan) -> Self { + PhysicalPlanImpl::StackDepthPlan(v) + } +} + pub struct PhysicalPlan { - inner: Box, + inner: Box, } dyn_clone::clone_trait_object!(IPhysicalPlan); @@ -291,43 +534,170 @@ impl Debug for PhysicalPlan { } } -impl Deref for PhysicalPlan { - type Target = dyn IPhysicalPlan; - - fn deref(&self) -> &Self::Target { - self.inner.deref() - } -} - -impl DerefMut for PhysicalPlan { - fn deref_mut(&mut self) -> &mut Self::Target { - self.inner.deref_mut() - } -} - impl serde::Serialize for PhysicalPlan { #[recursive::recursive] fn serialize(&self, serializer: S) -> std::result::Result { - self.inner.serialize(serializer) + PhysicalPlanEnvelopeRef::V2(self.inner.as_ref()).serialize(serializer) } } impl<'de> serde::Deserialize<'de> for PhysicalPlan { #[recursive::recursive] fn deserialize>(deserializer: D) -> std::result::Result { + let envelope = PhysicalPlanEnvelope::deserialize(deserializer)?; + + let inner = match envelope { + PhysicalPlanEnvelope::V2(plan) => plan, + PhysicalPlanEnvelope::V1(LegacyPhysicalPlanImpl(plan)) => plan, + }; + Ok(PhysicalPlan { - inner: Box::::deserialize(deserializer)?, + inner: Box::new(inner), }) } } +#[derive(serde::Serialize)] +#[serde(untagged)] +enum PhysicalPlanEnvelopeRef<'a> { + V2(&'a PhysicalPlanImpl), +} + +#[derive(serde::Deserialize)] +#[serde(untagged)] +enum PhysicalPlanEnvelope { + V2(PhysicalPlanImpl), + V1(LegacyPhysicalPlanImpl), +} + +struct LegacyPhysicalPlanImpl(PhysicalPlanImpl); + +impl<'de> serde::Deserialize<'de> for LegacyPhysicalPlanImpl { + fn deserialize>(deserializer: D) -> std::result::Result { + let value = JsonValue::deserialize(deserializer)?; + let Some((type_name, rest)) = extract_typetag_value(value) else { + return Err(DeError::custom("missing typetag 'type' field")); + }; + + let Some(plan) = PhysicalPlanImpl::try_from_typetag_value::(&type_name, rest)? + else { + return Err(DeError::custom(format!( + "unknown typetag type: {type_name}" + ))); + }; + + Ok(LegacyPhysicalPlanImpl(plan)) + } +} + +fn extract_typetag_value(value: JsonValue) -> Option<(String, JsonValue)> { + let JsonValue::Object(mut map) = value else { + return None; + }; + + let type_value = map.remove("type")?; + let type_name = type_value.as_str()?.to_string(); + + Some((type_name, JsonValue::Object(map))) +} + impl PhysicalPlan { - pub fn new(inner: T) -> PhysicalPlan { + #[allow(private_bounds)] + pub fn new(inner: T) -> PhysicalPlan + where PhysicalPlanImpl: From { PhysicalPlan { - inner: Box::new(inner), + inner: Box::new(inner.into()), } } + pub fn as_any(&self) -> &dyn Any { + dispatch_plan_ref!(self, v => v.as_any()) + } + + pub fn get_meta(&self) -> &PhysicalPlanMeta { + dispatch_plan_ref!(self, v => v.get_meta()) + } + + pub fn get_meta_mut(&mut self) -> &mut PhysicalPlanMeta { + dispatch_plan_mut!(self, v => v.get_meta_mut()) + } + + pub fn get_id(&self) -> u32 { + dispatch_plan_ref!(self, v => v.get_id()) + } + + pub fn get_name(&self) -> String { + dispatch_plan_ref!(self, v => v.get_name()) + } + + pub fn adjust_plan_id(&mut self, next_id: &mut u32) { + dispatch_plan_mut!(self, v => v.adjust_plan_id(next_id)) + } + + pub fn output_schema(&self) -> Result { + dispatch_plan_ref!(self, v => v.output_schema()) + } + + pub fn children(&self) -> Box + '_> { + dispatch_plan_ref!(self, v => v.children()) + } + + pub fn children_mut(&mut self) -> Box + '_> { + dispatch_plan_mut!(self, v => v.children_mut()) + } + + pub fn formatter(&self) -> Result> { + dispatch_plan_ref!(self, v => v.formatter()) + } + + pub fn try_find_single_data_source(&self) -> Option<&DataSourcePlan> { + dispatch_plan_ref!(self, v => v.try_find_single_data_source()) + } + + pub fn try_find_mutation_source(&self) -> Option { + dispatch_plan_ref!(self, v => v.try_find_mutation_source()) + } + + pub fn get_all_data_source(&self, sources: &mut Vec<(u32, Box)>) { + dispatch_plan_ref!(self, v => v.get_all_data_source(sources)) + } + + pub fn set_pruning_stats(&mut self, stats: &mut HashMap) { + dispatch_plan_mut!(self, v => v.set_pruning_stats(stats)) + } + + pub fn is_distributed_plan(&self) -> bool { + dispatch_plan_ref!(self, v => v.is_distributed_plan()) + } + + pub fn is_warehouse_distributed_plan(&self) -> bool { + dispatch_plan_ref!(self, v => v.is_warehouse_distributed_plan()) + } + + pub fn display_in_profile(&self) -> bool { + dispatch_plan_ref!(self, v => v.display_in_profile()) + } + + pub fn get_desc(&self) -> Result { + dispatch_plan_ref!(self, v => v.get_desc()) + } + + pub fn get_labels(&self) -> Result>> { + dispatch_plan_ref!(self, v => v.get_labels()) + } + + pub fn derive(&self, children: Vec) -> PhysicalPlan { + dispatch_plan_ref!(self, v => v.derive(children)) + } + + pub fn build_pipeline(&self, builder: &mut PipelineBuilder) -> Result<()> { + dispatch_plan_ref!(self, v => v.build_pipeline(builder)) + } + + pub fn build_pipeline2(&self, builder: &mut PipelineBuilder) -> Result<()> { + dispatch_plan_ref!(self, v => v.build_pipeline2(builder)) + } + #[recursive::recursive] pub fn derive_with(&self, handle: &mut Box) -> PhysicalPlan { let mut children = vec![]; @@ -365,3 +735,208 @@ impl PhysicalPlan { self.formatter()?.format(&mut context) } } + +#[cfg(test)] +mod tests { + use std::any::Any; + use std::backtrace::Backtrace; + use std::sync::atomic::AtomicUsize; + use std::sync::atomic::Ordering; + + use serde::ser::SerializeStruct; + use serde_json::json; + use serde_json::Value; + use serde_json::{self}; + + use super::*; + use crate::physical_plans::physical_limit::Limit; + use crate::physical_plans::physical_sequence::Sequence; + use crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef; + + static STACK_DEPTH: AtomicUsize = AtomicUsize::new(0); + static STACK_DELTA: AtomicUsize = AtomicUsize::new(0); + static BASELINE_DEPTH: AtomicUsize = AtomicUsize::new(0); + + #[derive(Clone, Debug, serde::Deserialize)] + pub(crate) struct StackDepthPlan { + meta: PhysicalPlanMeta, + } + + impl StackDepthPlan { + fn new(name: impl Into) -> Self { + StackDepthPlan { + meta: PhysicalPlanMeta::new(name), + } + } + } + + impl serde::Serialize for StackDepthPlan { + fn serialize(&self, serializer: S) -> std::result::Result + where S: serde::Serializer { + let depth = current_stack_depth(); + STACK_DEPTH.store(depth, Ordering::Relaxed); + let baseline = BASELINE_DEPTH.load(Ordering::Relaxed); + STACK_DELTA.store(depth.saturating_sub(baseline), Ordering::Relaxed); + + // Serialize in the same shape as a normal plan node. + let mut state = serializer.serialize_struct("StackDepthPlan", 1)?; + state.serialize_field("meta", &self.meta)?; + state.end() + } + } + + impl IPhysicalPlan for StackDepthPlan { + fn as_any(&self) -> &dyn Any { + self + } + + fn get_meta(&self) -> &PhysicalPlanMeta { + &self.meta + } + + fn get_meta_mut(&mut self) -> &mut PhysicalPlanMeta { + &mut self.meta + } + + fn derive(&self, _children: Vec) -> PhysicalPlan { + PhysicalPlan::new(self.clone()) + } + + fn build_pipeline2(&self, builder: &mut PipelineBuilder) -> Result<()> { + let _ = builder; + Ok(()) + } + } + + // Used to compare the serialization stack depth of different versions + #[test] + fn typetag_serialize_stack_depth_is_measured() { + STACK_DEPTH.store(0, Ordering::Relaxed); + STACK_DELTA.store(0, Ordering::Relaxed); + let baseline = current_stack_depth(); + BASELINE_DEPTH.store(baseline, Ordering::Relaxed); + + let plan = PhysicalPlan::new(StackDepthPlan::new("stack_depth_plan")); + serde_json::to_vec(&plan).expect("serialize typetag plan"); + + let depth = STACK_DEPTH.load(Ordering::Relaxed); + let delta = STACK_DELTA.load(Ordering::Relaxed); + + assert!(depth > 0, "backtrace depth was not captured"); + assert!( + delta > 0, + "delta between typetag serialize and baseline should be > 0" + ); + eprintln!( + "typetag serialize stack depth: {}, delta from baseline: {}", + depth, delta + ); + } + + fn current_stack_depth() -> usize { + Backtrace::force_capture() + .to_string() + .lines() + .filter(|line| { + line.trim_start() + .chars() + .next() + .map_or(false, |c| c.is_ascii_digit()) + }) + .count() + } + + #[test] + fn legacy_typetag_format_can_be_deserialized() { + let samples: Vec<(PhysicalPlan, &'static str, fn(&PhysicalPlan) -> bool)> = vec![ + (sample_serialized_ref(), "SerializedPhysicalPlanRef", |p| { + SerializedPhysicalPlanRef::from_physical_plan(p).is_some() + }), + (sample_limit(), "Limit", |p| { + Limit::from_physical_plan(p).is_some() + }), + (sample_sequence(), "Sequence", |p| { + Sequence::from_physical_plan(p).is_some() + }), + ]; + + for (plan, name, matcher) in samples { + let new_json = serde_json::to_value(&plan).expect("serialize new format"); + let legacy_json = convert_to_legacy(&new_json); + + let restored: PhysicalPlan = + serde_json::from_value(legacy_json).expect("legacy typetag deserialize"); + assert!( + matcher(&restored), + "legacy typetag should deserialize into {name}" + ); + } + } + + fn sample_serialized_ref() -> PhysicalPlan { + serde_json::from_value(serialized_ref_json()).expect("build SerializedPhysicalPlanRef") + } + + fn sample_limit() -> PhysicalPlan { + serde_json::from_value(limit_json()).expect("build Limit plan") + } + + fn sample_sequence() -> PhysicalPlan { + serde_json::from_value(sequence_json()).expect("build Sequence plan") + } + + fn serialized_ref_json() -> Value { + json!({ "SerializedPhysicalPlanRef": 1 }) + } + + fn limit_json() -> Value { + json!({ + "Limit": { + "meta": { "plan_id": 7, "name": "Limit" }, + "input": serialized_ref_json(), + "limit": 5, + "offset": 2, + "stat_info": null + } + }) + } + + fn sequence_json() -> Value { + json!({ + "Sequence": { + "plan_id": 99, + "stat_info": null, + "left": limit_json(), + "right": serialized_ref_json(), + "meta": { "plan_id": 8, "name": "Sequence" } + } + }) + } + + fn convert_to_legacy(value: &Value) -> Value { + match value { + Value::Object(map) => { + if map.len() == 1 { + if let Some((variant, inner)) = map.iter().next() { + if let Value::Object(inner_obj) = inner { + let mut legacy = serde_json::Map::new(); + legacy.insert("type".to_string(), Value::String(variant.clone())); + for (k, v) in inner_obj { + legacy.insert(k.clone(), convert_to_legacy(v)); + } + return Value::Object(legacy); + } + } + } + + let mut new_map = serde_json::Map::new(); + for (k, v) in map { + new_map.insert(k.clone(), convert_to_legacy(v)); + } + Value::Object(new_map) + } + Value::Array(arr) => Value::Array(arr.iter().map(convert_to_legacy).collect()), + _ => value.clone(), + } + } +} diff --git a/src/query/service/src/physical_plans/physical_project_set.rs b/src/query/service/src/physical_plans/physical_project_set.rs index 7b3caf514ea24..8b8809ed5a25d 100644 --- a/src/query/service/src/physical_plans/physical_project_set.rs +++ b/src/query/service/src/physical_plans/physical_project_set.rs @@ -50,7 +50,6 @@ pub struct ProjectSet { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for ProjectSet { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_r_cte_scan.rs b/src/query/service/src/physical_plans/physical_r_cte_scan.rs index 94d478dadb0c0..9e6792005714a 100644 --- a/src/query/service/src/physical_plans/physical_r_cte_scan.rs +++ b/src/query/service/src/physical_plans/physical_r_cte_scan.rs @@ -35,7 +35,6 @@ pub struct RecursiveCteScan { pub stat: PlanStatsInfo, } -#[typetag::serde] impl IPhysicalPlan for RecursiveCteScan { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_range_join.rs b/src/query/service/src/physical_plans/physical_range_join.rs index b96091b477d84..eb719459521b8 100644 --- a/src/query/service/src/physical_plans/physical_range_join.rs +++ b/src/query/service/src/physical_plans/physical_range_join.rs @@ -66,7 +66,6 @@ pub struct RangeJoin { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for RangeJoin { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_recluster.rs b/src/query/service/src/physical_plans/physical_recluster.rs index f86247763f24c..0a6c80bede960 100644 --- a/src/query/service/src/physical_plans/physical_recluster.rs +++ b/src/query/service/src/physical_plans/physical_recluster.rs @@ -67,7 +67,6 @@ pub struct Recluster { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for Recluster { fn as_any(&self) -> &dyn Any { self @@ -266,7 +265,6 @@ pub struct HilbertPartition { pub rows_per_block: usize, } -#[typetag::serde] impl IPhysicalPlan for HilbertPartition { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_replace_async_source.rs b/src/query/service/src/physical_plans/physical_replace_async_source.rs index e57f78f04fb6f..cc1379fc1f233 100644 --- a/src/query/service/src/physical_plans/physical_replace_async_source.rs +++ b/src/query/service/src/physical_plans/physical_replace_async_source.rs @@ -35,7 +35,6 @@ pub struct ReplaceAsyncSourcer { pub source: InsertValue, } -#[typetag::serde] impl IPhysicalPlan for ReplaceAsyncSourcer { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs index 29f1ce6d2ec89..b28712e83354b 100644 --- a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs +++ b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs @@ -57,7 +57,6 @@ pub struct ReplaceDeduplicate { pub delete_when: Option<(RemoteExpr, String)>, } -#[typetag::serde] impl IPhysicalPlan for ReplaceDeduplicate { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_replace_into.rs b/src/query/service/src/physical_plans/physical_replace_into.rs index 9e502fb467a81..09a75dd9847b8 100644 --- a/src/query/service/src/physical_plans/physical_replace_into.rs +++ b/src/query/service/src/physical_plans/physical_replace_into.rs @@ -57,7 +57,6 @@ pub struct ReplaceInto { pub table_meta_timestamps: TableMetaTimestamps, } -#[typetag::serde] impl IPhysicalPlan for ReplaceInto { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_row_fetch.rs b/src/query/service/src/physical_plans/physical_row_fetch.rs index 11fef083c340a..32eb1667e9a0b 100644 --- a/src/query/service/src/physical_plans/physical_row_fetch.rs +++ b/src/query/service/src/physical_plans/physical_row_fetch.rs @@ -54,7 +54,6 @@ pub struct RowFetch { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for RowFetch { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_secure_filter.rs b/src/query/service/src/physical_plans/physical_secure_filter.rs index 851952279b83f..1480ea2e5a6c4 100644 --- a/src/query/service/src/physical_plans/physical_secure_filter.rs +++ b/src/query/service/src/physical_plans/physical_secure_filter.rs @@ -48,7 +48,6 @@ pub struct SecureFilter { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for SecureFilter { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_sequence.rs b/src/query/service/src/physical_plans/physical_sequence.rs index 4642019c961f5..a0923d68cd655 100644 --- a/src/query/service/src/physical_plans/physical_sequence.rs +++ b/src/query/service/src/physical_plans/physical_sequence.rs @@ -39,7 +39,6 @@ pub struct Sequence { pub meta: PhysicalPlanMeta, } -#[typetag::serde] impl IPhysicalPlan for Sequence { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_sort.rs b/src/query/service/src/physical_plans/physical_sort.rs index 531e93b955b55..a4ade17b55d00 100644 --- a/src/query/service/src/physical_plans/physical_sort.rs +++ b/src/query/service/src/physical_plans/physical_sort.rs @@ -99,7 +99,6 @@ impl Display for SortStep { } } -#[typetag::serde] impl IPhysicalPlan for Sort { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_table_scan.rs b/src/query/service/src/physical_plans/physical_table_scan.rs index ecca1c5f005cf..7cd3896a26a7b 100644 --- a/src/query/service/src/physical_plans/physical_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_table_scan.rs @@ -97,7 +97,6 @@ pub struct TableScan { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for TableScan { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_udf.rs b/src/query/service/src/physical_plans/physical_udf.rs index 89f75767e8acb..0ec99673786db 100644 --- a/src/query/service/src/physical_plans/physical_udf.rs +++ b/src/query/service/src/physical_plans/physical_udf.rs @@ -52,7 +52,6 @@ pub struct Udf { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for Udf { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_union_all.rs b/src/query/service/src/physical_plans/physical_union_all.rs index c2f311951a588..dd669de1d18a8 100644 --- a/src/query/service/src/physical_plans/physical_union_all.rs +++ b/src/query/service/src/physical_plans/physical_union_all.rs @@ -55,7 +55,6 @@ pub struct UnionAll { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for UnionAll { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_window.rs b/src/query/service/src/physical_plans/physical_window.rs index e60934ab3acd2..daaaedcb2d725 100644 --- a/src/query/service/src/physical_plans/physical_window.rs +++ b/src/query/service/src/physical_plans/physical_window.rs @@ -71,7 +71,6 @@ pub struct Window { pub limit: Option, } -#[typetag::serde] impl IPhysicalPlan for Window { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/physical_plans/physical_window_partition.rs b/src/query/service/src/physical_plans/physical_window_partition.rs index e3c9f1f0228d4..e8c652a995d0b 100644 --- a/src/query/service/src/physical_plans/physical_window_partition.rs +++ b/src/query/service/src/physical_plans/physical_window_partition.rs @@ -54,7 +54,6 @@ pub struct WindowPartition { pub stat_info: Option, } -#[typetag::serde] impl IPhysicalPlan for WindowPartition { fn as_any(&self) -> &dyn Any { self diff --git a/src/query/service/src/servers/flight/v1/packets/mod.rs b/src/query/service/src/servers/flight/v1/packets/mod.rs index ca44d46afde5e..062a539857f8c 100644 --- a/src/query/service/src/servers/flight/v1/packets/mod.rs +++ b/src/query/service/src/servers/flight/v1/packets/mod.rs @@ -15,7 +15,7 @@ mod packet_data; mod packet_data_progressinfo; mod packet_executor; -mod packet_fragment; +pub mod packet_fragment; mod packet_publisher; pub use packet_data::DataPacket; diff --git a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs index 963363e7267d1..b4b51f5fb5de8 100644 --- a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs +++ b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs @@ -50,9 +50,8 @@ impl QueryFragment { } #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] -struct SerializedPhysicalPlanRef(u32); +pub struct SerializedPhysicalPlanRef(u32); -#[typetag::serde] impl IPhysicalPlan for SerializedPhysicalPlanRef { fn as_any(&self) -> &dyn Any { self From 3fa4c0aa54af6916514db494fe390a6f149a7975 Mon Sep 17 00:00:00 2001 From: kould Date: Wed, 17 Dec 2025 10:29:20 +0800 Subject: [PATCH 02/12] chore: codefmt --- .../src/physical_plans/physical_plan.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 12a8ee0a76b64..19f06a71fdb01 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -271,6 +271,9 @@ impl PhysicalPlanCast for T { macro_rules! define_physical_plan_impl { ( $( $variant:ident => $path:path ),+ $(,)? ) => { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] + /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth + /// + /// compatibility: [LegacyPhysicalPlanImpl](LegacyPhysicalPlanImpl) pub(crate) enum PhysicalPlanImpl { $( $variant($path), )+ #[cfg(test)] @@ -841,7 +844,7 @@ mod tests { line.trim_start() .chars() .next() - .map_or(false, |c| c.is_ascii_digit()) + .is_some_and(|c| c.is_ascii_digit()) }) .count() } @@ -917,15 +920,13 @@ mod tests { match value { Value::Object(map) => { if map.len() == 1 { - if let Some((variant, inner)) = map.iter().next() { - if let Value::Object(inner_obj) = inner { - let mut legacy = serde_json::Map::new(); - legacy.insert("type".to_string(), Value::String(variant.clone())); - for (k, v) in inner_obj { - legacy.insert(k.clone(), convert_to_legacy(v)); - } - return Value::Object(legacy); + if let Some((variant, Value::Object(inner_obj))) = map.iter().next() { + let mut legacy = serde_json::Map::new(); + legacy.insert("type".to_string(), Value::String(variant.clone())); + for (k, v) in inner_obj { + legacy.insert(k.clone(), convert_to_legacy(v)); } + return Value::Object(legacy); } } From b1996a5949b590430fa2718e919ccf614396ac11 Mon Sep 17 00:00:00 2001 From: kould Date: Wed, 17 Dec 2025 10:40:56 +0800 Subject: [PATCH 03/12] chore: codefmt --- src/query/service/src/physical_plans/physical_plan.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 19f06a71fdb01..5e4ccf200fb3d 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -850,6 +850,7 @@ mod tests { } #[test] + #[allow(clippy::type_complexity)] fn legacy_typetag_format_can_be_deserialized() { let samples: Vec<(PhysicalPlan, &'static str, fn(&PhysicalPlan) -> bool)> = vec![ (sample_serialized_ref(), "SerializedPhysicalPlanRef", |p| { From 4a5a4bfe50229b2258b59bf63800b6b67ca1d45a Mon Sep 17 00:00:00 2001 From: kould Date: Wed, 17 Dec 2025 16:48:54 +0800 Subject: [PATCH 04/12] refactor: This allows for declarations across different files, which are then aggregated into an enumeration at compile time to implement static dispatch of Serde without requiring centralized implementation. --- src/query/service/Cargo.toml | 1 + src/query/service/build.rs | 130 ++++++++++ src/query/service/src/physical_plans/mod.rs | 10 + .../physical_add_stream_column.rs | 2 + .../physical_aggregate_expand.rs | 2 + .../physical_aggregate_final.rs | 2 + .../physical_aggregate_partial.rs | 2 + .../src/physical_plans/physical_async_func.rs | 2 + .../src/physical_plans/physical_broadcast.rs | 4 + .../src/physical_plans/physical_cache_scan.rs | 2 + .../physical_column_mutation.rs | 2 + .../physical_plans/physical_commit_sink.rs | 2 + .../physical_plans/physical_compact_source.rs | 2 + .../physical_constant_table_scan.rs | 2 + .../physical_copy_into_location.rs | 2 + .../physical_copy_into_table.rs | 2 + .../physical_plans/physical_cte_consumer.rs | 2 + .../physical_distributed_insert_select.rs | 2 + .../physical_plans/physical_eval_scalar.rs | 2 + .../src/physical_plans/physical_exchange.rs | 2 + .../physical_plans/physical_exchange_sink.rs | 2 + .../physical_exchange_source.rs | 2 + .../physical_expression_scan.rs | 2 + .../src/physical_plans/physical_filter.rs | 2 + .../src/physical_plans/physical_hash_join.rs | 2 + .../src/physical_plans/physical_limit.rs | 2 + .../physical_materialized_cte.rs | 2 + .../physical_multi_table_insert.rs | 18 ++ .../src/physical_plans/physical_mutation.rs | 2 + .../physical_mutation_into_organize.rs | 2 + .../physical_mutation_into_split.rs | 2 + .../physical_mutation_manipulate.rs | 2 + .../physical_mutation_source.rs | 2 + .../src/physical_plans/physical_plan.rs | 222 +----------------- .../physical_plans/physical_project_set.rs | 2 + .../src/physical_plans/physical_r_cte_scan.rs | 2 + .../src/physical_plans/physical_range_join.rs | 2 + .../src/physical_plans/physical_recluster.rs | 4 + .../physical_replace_async_source.rs | 2 + .../physical_replace_deduplicate.rs | 2 + .../physical_plans/physical_replace_into.rs | 2 + .../src/physical_plans/physical_row_fetch.rs | 2 + .../physical_plans/physical_secure_filter.rs | 2 + .../src/physical_plans/physical_sequence.rs | 2 + .../src/physical_plans/physical_sort.rs | 2 + .../src/physical_plans/physical_table_scan.rs | 2 + .../src/physical_plans/physical_udf.rs | 2 + .../src/physical_plans/physical_union_all.rs | 2 + .../src/physical_plans/physical_window.rs | 2 + .../physical_window_partition.rs | 2 + .../flight/v1/packets/packet_fragment.rs | 2 + 51 files changed, 263 insertions(+), 214 deletions(-) diff --git a/src/query/service/Cargo.toml b/src/query/service/Cargo.toml index 33fb813df5289..25d515e1cfdce 100644 --- a/src/query/service/Cargo.toml +++ b/src/query/service/Cargo.toml @@ -201,6 +201,7 @@ wiremock = { workspace = true } [build-dependencies] databend-common-building = { workspace = true } +walkdir = { workspace = true } [lints] workspace = true diff --git a/src/query/service/build.rs b/src/query/service/build.rs index aaf4c53f857c6..5b6813e9cc26b 100644 --- a/src/query/service/build.rs +++ b/src/query/service/build.rs @@ -13,6 +13,9 @@ // limitations under the License. use std::env; +use std::fs; +use std::io::Write; +use std::path::Path; fn main() { // Keep build script rerun behavior explicit for the feature list we expose. @@ -49,4 +52,131 @@ fn main() { let features = features.join(","); println!("cargo:rustc-env=DATABEND_QUERY_CARGO_FEATURES={features}"); + + let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + let src_dir = Path::new(&manifest_dir).join("src"); + let out_dir = Path::new(&env::var("OUT_DIR").expect("OUT_DIR not set")).to_path_buf(); + + let mut entries = collect_registrations(&src_dir); + entries.sort_by(|a, b| a.1.cmp(&b.1)); + + let out_path = out_dir.join("physical_plan_impls.rs"); + write_impls(&out_path, &entries); + + let dispatch_out = out_dir.join("physical_plan_dispatch.rs"); + write_dispatch(&dispatch_out, &entries); + + println!("cargo:rerun-if-changed={}", src_dir.display()); +} + +fn collect_registrations(src_dir: &Path) -> Vec<(Option, String, String)> { + let mut entries = Vec::new(); + + for entry in walkdir::WalkDir::new(src_dir) + .into_iter() + .filter_map(Result::ok) + .filter(|e| e.file_type().is_file()) + { + if entry.path().extension().and_then(|s| s.to_str()) != Some("rs") { + continue; + } + + let content = fs::read_to_string(entry.path()) + .unwrap_or_else(|e| panic!("read {}: {e}", entry.path().display())); + + for line in content.lines() { + if let Some(pos) = line.find("register_physical_plan!") { + let rest = &line[pos..]; + if let Some((variant, path)) = parse_registration(rest) { + entries.push((None, variant, path)); + } + } + } + } + + // test-only plan variant + entries.push(( + Some("#[cfg(test)]".to_string()), + "StackDepthPlan".to_string(), + "crate::physical_plans::physical_plan::tests::StackDepthPlan".to_string(), + )); + + entries +} + +fn parse_registration(line: &str) -> Option<(String, String)> { + let start = line.find('(')? + 1; + let end = line.find(')')?; + let body = &line[start..end]; + let mut parts = body.split("=>").map(str::trim); + let variant = parts.next()?.trim_end_matches(','); + let path = parts.next()?.trim_end_matches(','); + + Some((variant.to_string(), path.to_string())) +} + +fn write_impls(out_path: &Path, entries: &[(Option, String, String)]) { + let mut out = String::new(); + out.push_str("define_physical_plan_impl!(\n"); + + for (meta, variant, path) in entries { + if let Some(meta) = meta { + out.push_str(" "); + out.push_str(meta); + out.push('\n'); + } + out.push_str(" "); + out.push_str(variant); + out.push_str(" => "); + out.push_str(path); + out.push_str(",\n"); + } + + out.push_str(");\n"); + + let mut file = fs::File::create(out_path).expect("create physical_plan_impls.rs"); + file.write_all(out.as_bytes()) + .expect("write physical_plan_impls.rs"); +} + +fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) { + let mut out = String::new(); + + out.push_str("macro_rules! dispatch_plan_ref {\n"); + out.push_str(" ($s:expr, $plan:ident => $body:expr) => {\n"); + out.push_str(" match $s.inner.as_ref() {\n"); + for (meta, variant, _) in entries { + if let Some(meta) = meta { + out.push_str(" "); + out.push_str(meta); + out.push('\n'); + } + out.push_str(" PhysicalPlanImpl::"); + out.push_str(variant); + out.push_str("($plan) => $body,\n"); + } + out.push_str(" }\n"); + out.push_str(" };\n"); + out.push_str("}\n\n"); + + out.push_str("macro_rules! dispatch_plan_mut {\n"); + out.push_str(" ($s:expr, $plan:ident => $body:expr) => {\n"); + out.push_str(" match $s.inner.as_mut() {\n"); + for (meta, variant, _) in entries { + if let Some(meta) = meta { + out.push_str(" "); + out.push_str(meta); + out.push('\n'); + } + out.push_str(" PhysicalPlanImpl::"); + out.push_str(variant); + out.push_str("($plan) => $body,\n"); + } + out.push_str(" }\n"); + out.push_str(" };\n"); + out.push_str("}\n"); + + let mut file = fs::File::create(out_path).expect("create physical_plan_dispatch.rs"); + file.write_all(out.as_bytes()) + .expect("write physical_plan_dispatch.rs"); } diff --git a/src/query/service/src/physical_plans/mod.rs b/src/query/service/src/physical_plans/mod.rs index d5780e1ec116f..40ec81a3db00c 100644 --- a/src/query/service/src/physical_plans/mod.rs +++ b/src/query/service/src/physical_plans/mod.rs @@ -109,6 +109,16 @@ pub use physical_window_partition::*; pub use runtime_filter::PhysicalRuntimeFilter; pub use runtime_filter::PhysicalRuntimeFilters; +// Marker macro: used by build.rs to collect physical plan variants for codegen. +// Expands to a no-op, so plan modules can call it without affecting runtime code. +#[macro_export] +macro_rules! register_physical_plan { + ($variant:ident => $path:path) => { + #[allow(dead_code)] + const _: () = (); + }; +} + pub mod explain; mod format; mod physical_cte_consumer; diff --git a/src/query/service/src/physical_plans/physical_add_stream_column.rs b/src/query/service/src/physical_plans/physical_add_stream_column.rs index be64e12bdb81e..6629e427d76b0 100644 --- a/src/query/service/src/physical_plans/physical_add_stream_column.rs +++ b/src/query/service/src/physical_plans/physical_add_stream_column.rs @@ -245,3 +245,5 @@ impl AddStreamColumn { })) } } + +crate::register_physical_plan!(AddStreamColumn => crate::physical_plans::physical_add_stream_column::AddStreamColumn); diff --git a/src/query/service/src/physical_plans/physical_aggregate_expand.rs b/src/query/service/src/physical_plans/physical_aggregate_expand.rs index bc89ea8d4a84f..a6da2a311b009 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_expand.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_expand.rs @@ -171,3 +171,5 @@ impl IPhysicalPlan for AggregateExpand { Ok(()) } } + +crate::register_physical_plan!(AggregateExpand => crate::physical_plans::physical_aggregate_expand::AggregateExpand); diff --git a/src/query/service/src/physical_plans/physical_aggregate_final.rs b/src/query/service/src/physical_plans/physical_aggregate_final.rs index ae2c7ed5d43aa..20cdaf0b1bddf 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_final.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_final.rs @@ -675,3 +675,5 @@ impl PhysicalPlanBuilder { Ok(result) } } + +crate::register_physical_plan!(AggregateFinal => crate::physical_plans::physical_aggregate_final::AggregateFinal); diff --git a/src/query/service/src/physical_plans/physical_aggregate_partial.rs b/src/query/service/src/physical_plans/physical_aggregate_partial.rs index e041e64ca2480..53d714f822100 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_partial.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_partial.rs @@ -304,3 +304,5 @@ impl AggregatePartial { Some((resolved.into(), *limit)) } } + +crate::register_physical_plan!(AggregatePartial => crate::physical_plans::physical_aggregate_partial::AggregatePartial); diff --git a/src/query/service/src/physical_plans/physical_async_func.rs b/src/query/service/src/physical_plans/physical_async_func.rs index fb2a49b4a41b9..deeebfdb70482 100644 --- a/src/query/service/src/physical_plans/physical_async_func.rs +++ b/src/query/service/src/physical_plans/physical_async_func.rs @@ -200,3 +200,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(AsyncFunction => crate::physical_plans::physical_async_func::AsyncFunction); diff --git a/src/query/service/src/physical_plans/physical_broadcast.rs b/src/query/service/src/physical_plans/physical_broadcast.rs index 369c2f66a16c3..23d045c3a8033 100644 --- a/src/query/service/src/physical_plans/physical_broadcast.rs +++ b/src/query/service/src/physical_plans/physical_broadcast.rs @@ -156,3 +156,7 @@ pub fn build_broadcast_plans(ctx: &dyn TableContext) -> Result } Ok(plans) } + +crate::register_physical_plan!(BroadcastSink => crate::physical_plans::physical_broadcast::BroadcastSink); + +crate::register_physical_plan!(BroadcastSource => crate::physical_plans::physical_broadcast::BroadcastSource); diff --git a/src/query/service/src/physical_plans/physical_cache_scan.rs b/src/query/service/src/physical_plans/physical_cache_scan.rs index 8ce47add85ef6..7cb8fd60c48c7 100644 --- a/src/query/service/src/physical_plans/physical_cache_scan.rs +++ b/src/query/service/src/physical_plans/physical_cache_scan.rs @@ -133,3 +133,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(CacheScan => crate::physical_plans::physical_cache_scan::CacheScan); diff --git a/src/query/service/src/physical_plans/physical_column_mutation.rs b/src/query/service/src/physical_plans/physical_column_mutation.rs index 791fb423920c1..deeec04f84669 100644 --- a/src/query/service/src/physical_plans/physical_column_mutation.rs +++ b/src/query/service/src/physical_plans/physical_column_mutation.rs @@ -214,3 +214,5 @@ impl IPhysicalPlan for ColumnMutation { }) } } + +crate::register_physical_plan!(ColumnMutation => crate::physical_plans::physical_column_mutation::ColumnMutation); diff --git a/src/query/service/src/physical_plans/physical_commit_sink.rs b/src/query/service/src/physical_plans/physical_commit_sink.rs index ac4928807af7e..a02443d73076d 100644 --- a/src/query/service/src/physical_plans/physical_commit_sink.rs +++ b/src/query/service/src/physical_plans/physical_commit_sink.rs @@ -225,3 +225,5 @@ pub enum CommitType { merge_meta: bool, }, } + +crate::register_physical_plan!(CommitSink => crate::physical_plans::physical_commit_sink::CommitSink); diff --git a/src/query/service/src/physical_plans/physical_compact_source.rs b/src/query/service/src/physical_plans/physical_compact_source.rs index 50c4723f28dac..b5a6e46e36488 100644 --- a/src/query/service/src/physical_plans/physical_compact_source.rs +++ b/src/query/service/src/physical_plans/physical_compact_source.rs @@ -294,3 +294,5 @@ impl PhysicalPlanBuilder { Ok(root) } } + +crate::register_physical_plan!(CompactSource => crate::physical_plans::physical_compact_source::CompactSource); diff --git a/src/query/service/src/physical_plans/physical_constant_table_scan.rs b/src/query/service/src/physical_plans/physical_constant_table_scan.rs index 86b18bc3254b6..fc86bed007c34 100644 --- a/src/query/service/src/physical_plans/physical_constant_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_constant_table_scan.rs @@ -133,3 +133,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(ConstantTableScan => crate::physical_plans::physical_constant_table_scan::ConstantTableScan); diff --git a/src/query/service/src/physical_plans/physical_copy_into_location.rs b/src/query/service/src/physical_plans/physical_copy_into_location.rs index ee4ed64edb7ad..47db76eaecddd 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_location.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_location.rs @@ -145,3 +145,5 @@ fn sink_create_by(version: &Version) -> String { } create_by } + +crate::register_physical_plan!(CopyIntoLocation => crate::physical_plans::physical_copy_into_location::CopyIntoLocation); diff --git a/src/query/service/src/physical_plans/physical_copy_into_table.rs b/src/query/service/src/physical_plans/physical_copy_into_table.rs index 8e45028be76d1..7dc255ab628ab 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_table.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_table.rs @@ -186,3 +186,5 @@ pub enum CopyIntoTableSource { Query(PhysicalPlan), Stage(PhysicalPlan), } + +crate::register_physical_plan!(CopyIntoTable => crate::physical_plans::physical_copy_into_table::CopyIntoTable); diff --git a/src/query/service/src/physical_plans/physical_cte_consumer.rs b/src/query/service/src/physical_plans/physical_cte_consumer.rs index 6304d2563db06..4ebfb2e77c605 100644 --- a/src/query/service/src/physical_plans/physical_cte_consumer.rs +++ b/src/query/service/src/physical_plans/physical_cte_consumer.rs @@ -110,3 +110,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(MaterializeCTERef => crate::physical_plans::physical_cte_consumer::MaterializeCTERef); diff --git a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs index 66a628e74a86a..8827df25b0cec 100644 --- a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs +++ b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs @@ -130,3 +130,5 @@ impl IPhysicalPlan for DistributedInsertSelect { Ok(()) } } + +crate::register_physical_plan!(DistributedInsertSelect => crate::physical_plans::physical_distributed_insert_select::DistributedInsertSelect); diff --git a/src/query/service/src/physical_plans/physical_eval_scalar.rs b/src/query/service/src/physical_plans/physical_eval_scalar.rs index 7dd418ee01e7a..e76382320c08b 100644 --- a/src/query/service/src/physical_plans/physical_eval_scalar.rs +++ b/src/query/service/src/physical_plans/physical_eval_scalar.rs @@ -409,3 +409,5 @@ impl<'a> Visitor<'a> for FlattenColumnsVisitor { Ok(()) } } + +crate::register_physical_plan!(EvalScalar => crate::physical_plans::physical_eval_scalar::EvalScalar); diff --git a/src/query/service/src/physical_plans/physical_exchange.rs b/src/query/service/src/physical_plans/physical_exchange.rs index 62ee27d393daa..a58de063142c7 100644 --- a/src/query/service/src/physical_plans/physical_exchange.rs +++ b/src/query/service/src/physical_plans/physical_exchange.rs @@ -138,3 +138,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Exchange => crate::physical_plans::physical_exchange::Exchange); diff --git a/src/query/service/src/physical_plans/physical_exchange_sink.rs b/src/query/service/src/physical_plans/physical_exchange_sink.rs index 5a30fb0bff35a..ee2c2df387307 100644 --- a/src/query/service/src/physical_plans/physical_exchange_sink.rs +++ b/src/query/service/src/physical_plans/physical_exchange_sink.rs @@ -108,3 +108,5 @@ impl IPhysicalPlan for ExchangeSink { self.input.build_pipeline(builder) } } + +crate::register_physical_plan!(ExchangeSink => crate::physical_plans::physical_exchange_sink::ExchangeSink); diff --git a/src/query/service/src/physical_plans/physical_exchange_source.rs b/src/query/service/src/physical_plans/physical_exchange_source.rs index 89421c7650d73..8389fd3353dec 100644 --- a/src/query/service/src/physical_plans/physical_exchange_source.rs +++ b/src/query/service/src/physical_plans/physical_exchange_source.rs @@ -99,3 +99,5 @@ impl IPhysicalPlan for ExchangeSource { Ok(()) } } + +crate::register_physical_plan!(ExchangeSource => crate::physical_plans::physical_exchange_source::ExchangeSource); diff --git a/src/query/service/src/physical_plans/physical_expression_scan.rs b/src/query/service/src/physical_plans/physical_expression_scan.rs index a92073ec66b74..cdab1633854c7 100644 --- a/src/query/service/src/physical_plans/physical_expression_scan.rs +++ b/src/query/service/src/physical_plans/physical_expression_scan.rs @@ -146,3 +146,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(ExpressionScan => crate::physical_plans::physical_expression_scan::ExpressionScan); diff --git a/src/query/service/src/physical_plans/physical_filter.rs b/src/query/service/src/physical_plans/physical_filter.rs index ca63475d6e1c5..91423548275fe 100644 --- a/src/query/service/src/physical_plans/physical_filter.rs +++ b/src/query/service/src/physical_plans/physical_filter.rs @@ -176,3 +176,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Filter => crate::physical_plans::physical_filter::Filter); diff --git a/src/query/service/src/physical_plans/physical_hash_join.rs b/src/query/service/src/physical_plans/physical_hash_join.rs index 979b594c47aa0..3d811a1d8388c 100644 --- a/src/query/service/src/physical_plans/physical_hash_join.rs +++ b/src/query/service/src/physical_plans/physical_hash_join.rs @@ -1362,3 +1362,5 @@ impl PhysicalPlanBuilder { ) } } + +crate::register_physical_plan!(HashJoin => crate::physical_plans::physical_hash_join::HashJoin); diff --git a/src/query/service/src/physical_plans/physical_limit.rs b/src/query/service/src/physical_plans/physical_limit.rs index b752fc2c5ebd5..d2b5c1a91f908 100644 --- a/src/query/service/src/physical_plans/physical_limit.rs +++ b/src/query/service/src/physical_plans/physical_limit.rs @@ -248,3 +248,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Limit => crate::physical_plans::physical_limit::Limit); diff --git a/src/query/service/src/physical_plans/physical_materialized_cte.rs b/src/query/service/src/physical_plans/physical_materialized_cte.rs index 85aa1591ef68a..f02e067faf82f 100644 --- a/src/query/service/src/physical_plans/physical_materialized_cte.rs +++ b/src/query/service/src/physical_plans/physical_materialized_cte.rs @@ -142,3 +142,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(MaterializedCTE => crate::physical_plans::physical_materialized_cte::MaterializedCTE); diff --git a/src/query/service/src/physical_plans/physical_multi_table_insert.rs b/src/query/service/src/physical_plans/physical_multi_table_insert.rs index 97177e4c03e75..fd1c3f1f89077 100644 --- a/src/query/service/src/physical_plans/physical_multi_table_insert.rs +++ b/src/query/service/src/physical_plans/physical_multi_table_insert.rs @@ -796,3 +796,21 @@ impl IPhysicalPlan for ChunkCommitInsert { }) } } + +crate::register_physical_plan!(ChunkAppendData => crate::physical_plans::physical_multi_table_insert::ChunkAppendData); + +crate::register_physical_plan!(ChunkCastSchema => crate::physical_plans::physical_multi_table_insert::ChunkCastSchema); + +crate::register_physical_plan!(ChunkCommitInsert => crate::physical_plans::physical_multi_table_insert::ChunkCommitInsert); + +crate::register_physical_plan!(ChunkEvalScalar => crate::physical_plans::physical_multi_table_insert::ChunkEvalScalar); + +crate::register_physical_plan!(ChunkFillAndReorder => crate::physical_plans::physical_multi_table_insert::ChunkFillAndReorder); + +crate::register_physical_plan!(ChunkFilter => crate::physical_plans::physical_multi_table_insert::ChunkFilter); + +crate::register_physical_plan!(ChunkMerge => crate::physical_plans::physical_multi_table_insert::ChunkMerge); + +crate::register_physical_plan!(Duplicate => crate::physical_plans::physical_multi_table_insert::Duplicate); + +crate::register_physical_plan!(Shuffle => crate::physical_plans::physical_multi_table_insert::Shuffle); diff --git a/src/query/service/src/physical_plans/physical_mutation.rs b/src/query/service/src/physical_plans/physical_mutation.rs index 44233c54749ce..ef5cdd7a78223 100644 --- a/src/query/service/src/physical_plans/physical_mutation.rs +++ b/src/query/service/src/physical_plans/physical_mutation.rs @@ -1069,3 +1069,5 @@ fn build_field_id_to_schema_index( } } } + +crate::register_physical_plan!(Mutation => crate::physical_plans::physical_mutation::Mutation); diff --git a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs index 109008955e1b3..14fa59b21da2e 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs @@ -137,3 +137,5 @@ impl MutationOrganize { builder.main_pipeline.resize_partial_one(ranges.clone()) } } + +crate::register_physical_plan!(MutationOrganize => crate::physical_plans::physical_mutation_into_organize::MutationOrganize); diff --git a/src/query/service/src/physical_plans/physical_mutation_into_split.rs b/src/query/service/src/physical_plans/physical_mutation_into_split.rs index ae1386499e434..b7386f7e5ea75 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_split.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_split.rs @@ -89,3 +89,5 @@ impl IPhysicalPlan for MutationSplit { Ok(()) } } + +crate::register_physical_plan!(MutationSplit => crate::physical_plans::physical_mutation_into_split::MutationSplit); diff --git a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs index 097be7b288812..38b84b75e0e05 100644 --- a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs +++ b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs @@ -168,3 +168,5 @@ impl IPhysicalPlan for MutationManipulate { Ok(()) } } + +crate::register_physical_plan!(MutationManipulate => crate::physical_plans::physical_mutation_manipulate::MutationManipulate); diff --git a/src/query/service/src/physical_plans/physical_mutation_source.rs b/src/query/service/src/physical_plans/physical_mutation_source.rs index 44f725a28654a..f31e327caee70 100644 --- a/src/query/service/src/physical_plans/physical_mutation_source.rs +++ b/src/query/service/src/physical_plans/physical_mutation_source.rs @@ -310,3 +310,5 @@ pub fn create_push_down_filters( inverted_filter: remote_inverted_filter, }) } + +crate::register_physical_plan!(MutationSource => crate::physical_plans::physical_mutation_source::MutationSource); diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 5e4ccf200fb3d..89a16e724aedc 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -269,18 +269,16 @@ impl PhysicalPlanCast for T { } macro_rules! define_physical_plan_impl { - ( $( $variant:ident => $path:path ),+ $(,)? ) => { + ( $( $(#[$meta:meta])? $variant:ident => $path:path ),+ $(,)? ) => { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth /// /// compatibility: [LegacyPhysicalPlanImpl](LegacyPhysicalPlanImpl) pub(crate) enum PhysicalPlanImpl { - $( $variant($path), )+ - #[cfg(test)] - StackDepthPlan(crate::physical_plans::physical_plan::tests::StackDepthPlan), + $( $(#[$meta])? $variant($path), )+ } - $( impl From<$path> for PhysicalPlanImpl { + $( $(#[$meta])? impl From<$path> for PhysicalPlanImpl { fn from(v: $path) -> Self { PhysicalPlanImpl::$variant(v) } @@ -291,24 +289,15 @@ macro_rules! define_physical_plan_impl { type_name: &str, value: JsonValue, ) -> std::result::Result, E> { - $({ + $( + $(#[$meta])? if type_name == std::any::type_name::<$path>() || type_name == stringify!($variant) { let value = serde_json::from_value::<$path>(value).map_err(E::custom)?; return Ok(Some(PhysicalPlanImpl::$variant(value))); } - })+ - - #[cfg(test)] - if type_name - == std::any::type_name::() - || type_name == stringify!(StackDepthPlan) - { - let value = serde_json::from_value::(value) - .map_err(E::custom)?; - return Ok(Some(PhysicalPlanImpl::StackDepthPlan(value))); - } + )+ Ok(None) } @@ -316,204 +305,9 @@ macro_rules! define_physical_plan_impl { }; } -define_physical_plan_impl!( - AddStreamColumn => crate::physical_plans::physical_add_stream_column::AddStreamColumn, - AggregateExpand => crate::physical_plans::physical_aggregate_expand::AggregateExpand, - AggregateFinal => crate::physical_plans::physical_aggregate_final::AggregateFinal, - AggregatePartial => crate::physical_plans::physical_aggregate_partial::AggregatePartial, - AsyncFunction => crate::physical_plans::physical_async_func::AsyncFunction, - BroadcastSink => crate::physical_plans::physical_broadcast::BroadcastSink, - BroadcastSource => crate::physical_plans::physical_broadcast::BroadcastSource, - CacheScan => crate::physical_plans::physical_cache_scan::CacheScan, - ChunkAppendData => crate::physical_plans::physical_multi_table_insert::ChunkAppendData, - ChunkCastSchema => crate::physical_plans::physical_multi_table_insert::ChunkCastSchema, - ChunkCommitInsert => crate::physical_plans::physical_multi_table_insert::ChunkCommitInsert, - ChunkEvalScalar => crate::physical_plans::physical_multi_table_insert::ChunkEvalScalar, - ChunkFillAndReorder => crate::physical_plans::physical_multi_table_insert::ChunkFillAndReorder, - ChunkFilter => crate::physical_plans::physical_multi_table_insert::ChunkFilter, - ChunkMerge => crate::physical_plans::physical_multi_table_insert::ChunkMerge, - ColumnMutation => crate::physical_plans::physical_column_mutation::ColumnMutation, - CommitSink => crate::physical_plans::physical_commit_sink::CommitSink, - CompactSource => crate::physical_plans::physical_compact_source::CompactSource, - ConstantTableScan => crate::physical_plans::physical_constant_table_scan::ConstantTableScan, - CopyIntoLocation => crate::physical_plans::physical_copy_into_location::CopyIntoLocation, - CopyIntoTable => crate::physical_plans::physical_copy_into_table::CopyIntoTable, - DistributedInsertSelect => crate::physical_plans::physical_distributed_insert_select::DistributedInsertSelect, - Duplicate => crate::physical_plans::physical_multi_table_insert::Duplicate, - EvalScalar => crate::physical_plans::physical_eval_scalar::EvalScalar, - Exchange => crate::physical_plans::physical_exchange::Exchange, - ExchangeSink => crate::physical_plans::physical_exchange_sink::ExchangeSink, - ExchangeSource => crate::physical_plans::physical_exchange_source::ExchangeSource, - ExpressionScan => crate::physical_plans::physical_expression_scan::ExpressionScan, - Filter => crate::physical_plans::physical_filter::Filter, - HashJoin => crate::physical_plans::physical_hash_join::HashJoin, - HilbertPartition => crate::physical_plans::physical_recluster::HilbertPartition, - Limit => crate::physical_plans::physical_limit::Limit, - MaterializeCTERef => crate::physical_plans::physical_cte_consumer::MaterializeCTERef, - MaterializedCTE => crate::physical_plans::physical_materialized_cte::MaterializedCTE, - Mutation => crate::physical_plans::physical_mutation::Mutation, - MutationManipulate => crate::physical_plans::physical_mutation_manipulate::MutationManipulate, - MutationOrganize => crate::physical_plans::physical_mutation_into_organize::MutationOrganize, - MutationSource => crate::physical_plans::physical_mutation_source::MutationSource, - MutationSplit => crate::physical_plans::physical_mutation_into_split::MutationSplit, - ProjectSet => crate::physical_plans::physical_project_set::ProjectSet, - RangeJoin => crate::physical_plans::physical_range_join::RangeJoin, - Recluster => crate::physical_plans::physical_recluster::Recluster, - RecursiveCteScan => crate::physical_plans::physical_r_cte_scan::RecursiveCteScan, - ReplaceAsyncSourcer => crate::physical_plans::physical_replace_async_source::ReplaceAsyncSourcer, - ReplaceDeduplicate => crate::physical_plans::physical_replace_deduplicate::ReplaceDeduplicate, - ReplaceInto => crate::physical_plans::physical_replace_into::ReplaceInto, - RowFetch => crate::physical_plans::physical_row_fetch::RowFetch, - SecureFilter => crate::physical_plans::physical_secure_filter::SecureFilter, - Sequence => crate::physical_plans::physical_sequence::Sequence, - SerializedPhysicalPlanRef => crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef, - Shuffle => crate::physical_plans::physical_multi_table_insert::Shuffle, - Sort => crate::physical_plans::physical_sort::Sort, - TableScan => crate::physical_plans::physical_table_scan::TableScan, - Udf => crate::physical_plans::physical_udf::Udf, - UnionAll => crate::physical_plans::physical_union_all::UnionAll, - Window => crate::physical_plans::physical_window::Window, - WindowPartition => crate::physical_plans::physical_window_partition::WindowPartition, -); - -macro_rules! dispatch_plan_ref { - ($s:expr, $plan:ident => $body:expr) => { - match $s.inner.as_ref() { - PhysicalPlanImpl::AddStreamColumn($plan) => $body, - PhysicalPlanImpl::AggregateExpand($plan) => $body, - PhysicalPlanImpl::AggregateFinal($plan) => $body, - PhysicalPlanImpl::AggregatePartial($plan) => $body, - PhysicalPlanImpl::AsyncFunction($plan) => $body, - PhysicalPlanImpl::BroadcastSink($plan) => $body, - PhysicalPlanImpl::BroadcastSource($plan) => $body, - PhysicalPlanImpl::CacheScan($plan) => $body, - PhysicalPlanImpl::ChunkAppendData($plan) => $body, - PhysicalPlanImpl::ChunkCastSchema($plan) => $body, - PhysicalPlanImpl::ChunkCommitInsert($plan) => $body, - PhysicalPlanImpl::ChunkEvalScalar($plan) => $body, - PhysicalPlanImpl::ChunkFillAndReorder($plan) => $body, - PhysicalPlanImpl::ChunkFilter($plan) => $body, - PhysicalPlanImpl::ChunkMerge($plan) => $body, - PhysicalPlanImpl::ColumnMutation($plan) => $body, - PhysicalPlanImpl::CommitSink($plan) => $body, - PhysicalPlanImpl::CompactSource($plan) => $body, - PhysicalPlanImpl::ConstantTableScan($plan) => $body, - PhysicalPlanImpl::CopyIntoLocation($plan) => $body, - PhysicalPlanImpl::CopyIntoTable($plan) => $body, - PhysicalPlanImpl::DistributedInsertSelect($plan) => $body, - PhysicalPlanImpl::Duplicate($plan) => $body, - PhysicalPlanImpl::EvalScalar($plan) => $body, - PhysicalPlanImpl::Exchange($plan) => $body, - PhysicalPlanImpl::ExchangeSink($plan) => $body, - PhysicalPlanImpl::ExchangeSource($plan) => $body, - PhysicalPlanImpl::ExpressionScan($plan) => $body, - PhysicalPlanImpl::Filter($plan) => $body, - PhysicalPlanImpl::HashJoin($plan) => $body, - PhysicalPlanImpl::HilbertPartition($plan) => $body, - PhysicalPlanImpl::Limit($plan) => $body, - PhysicalPlanImpl::MaterializeCTERef($plan) => $body, - PhysicalPlanImpl::MaterializedCTE($plan) => $body, - PhysicalPlanImpl::Mutation($plan) => $body, - PhysicalPlanImpl::MutationManipulate($plan) => $body, - PhysicalPlanImpl::MutationOrganize($plan) => $body, - PhysicalPlanImpl::MutationSource($plan) => $body, - PhysicalPlanImpl::MutationSplit($plan) => $body, - PhysicalPlanImpl::ProjectSet($plan) => $body, - PhysicalPlanImpl::RangeJoin($plan) => $body, - PhysicalPlanImpl::Recluster($plan) => $body, - PhysicalPlanImpl::RecursiveCteScan($plan) => $body, - PhysicalPlanImpl::ReplaceAsyncSourcer($plan) => $body, - PhysicalPlanImpl::ReplaceDeduplicate($plan) => $body, - PhysicalPlanImpl::ReplaceInto($plan) => $body, - PhysicalPlanImpl::RowFetch($plan) => $body, - PhysicalPlanImpl::SecureFilter($plan) => $body, - PhysicalPlanImpl::Sequence($plan) => $body, - PhysicalPlanImpl::SerializedPhysicalPlanRef($plan) => $body, - PhysicalPlanImpl::Shuffle($plan) => $body, - PhysicalPlanImpl::Sort($plan) => $body, - PhysicalPlanImpl::TableScan($plan) => $body, - PhysicalPlanImpl::Udf($plan) => $body, - PhysicalPlanImpl::UnionAll($plan) => $body, - PhysicalPlanImpl::Window($plan) => $body, - PhysicalPlanImpl::WindowPartition($plan) => $body, - #[cfg(test)] - PhysicalPlanImpl::StackDepthPlan($plan) => $body, - } - }; -} +include!(concat!(env!("OUT_DIR"), "/physical_plan_impls.rs")); -macro_rules! dispatch_plan_mut { - ($s:expr, $plan:ident => $body:expr) => { - match $s.inner.as_mut() { - PhysicalPlanImpl::AddStreamColumn($plan) => $body, - PhysicalPlanImpl::AggregateExpand($plan) => $body, - PhysicalPlanImpl::AggregateFinal($plan) => $body, - PhysicalPlanImpl::AggregatePartial($plan) => $body, - PhysicalPlanImpl::AsyncFunction($plan) => $body, - PhysicalPlanImpl::BroadcastSink($plan) => $body, - PhysicalPlanImpl::BroadcastSource($plan) => $body, - PhysicalPlanImpl::CacheScan($plan) => $body, - PhysicalPlanImpl::ChunkAppendData($plan) => $body, - PhysicalPlanImpl::ChunkCastSchema($plan) => $body, - PhysicalPlanImpl::ChunkCommitInsert($plan) => $body, - PhysicalPlanImpl::ChunkEvalScalar($plan) => $body, - PhysicalPlanImpl::ChunkFillAndReorder($plan) => $body, - PhysicalPlanImpl::ChunkFilter($plan) => $body, - PhysicalPlanImpl::ChunkMerge($plan) => $body, - PhysicalPlanImpl::ColumnMutation($plan) => $body, - PhysicalPlanImpl::CommitSink($plan) => $body, - PhysicalPlanImpl::CompactSource($plan) => $body, - PhysicalPlanImpl::ConstantTableScan($plan) => $body, - PhysicalPlanImpl::CopyIntoLocation($plan) => $body, - PhysicalPlanImpl::CopyIntoTable($plan) => $body, - PhysicalPlanImpl::DistributedInsertSelect($plan) => $body, - PhysicalPlanImpl::Duplicate($plan) => $body, - PhysicalPlanImpl::EvalScalar($plan) => $body, - PhysicalPlanImpl::Exchange($plan) => $body, - PhysicalPlanImpl::ExchangeSink($plan) => $body, - PhysicalPlanImpl::ExchangeSource($plan) => $body, - PhysicalPlanImpl::ExpressionScan($plan) => $body, - PhysicalPlanImpl::Filter($plan) => $body, - PhysicalPlanImpl::HashJoin($plan) => $body, - PhysicalPlanImpl::HilbertPartition($plan) => $body, - PhysicalPlanImpl::Limit($plan) => $body, - PhysicalPlanImpl::MaterializeCTERef($plan) => $body, - PhysicalPlanImpl::MaterializedCTE($plan) => $body, - PhysicalPlanImpl::Mutation($plan) => $body, - PhysicalPlanImpl::MutationManipulate($plan) => $body, - PhysicalPlanImpl::MutationOrganize($plan) => $body, - PhysicalPlanImpl::MutationSource($plan) => $body, - PhysicalPlanImpl::MutationSplit($plan) => $body, - PhysicalPlanImpl::ProjectSet($plan) => $body, - PhysicalPlanImpl::RangeJoin($plan) => $body, - PhysicalPlanImpl::Recluster($plan) => $body, - PhysicalPlanImpl::RecursiveCteScan($plan) => $body, - PhysicalPlanImpl::ReplaceAsyncSourcer($plan) => $body, - PhysicalPlanImpl::ReplaceDeduplicate($plan) => $body, - PhysicalPlanImpl::ReplaceInto($plan) => $body, - PhysicalPlanImpl::RowFetch($plan) => $body, - PhysicalPlanImpl::SecureFilter($plan) => $body, - PhysicalPlanImpl::Sequence($plan) => $body, - PhysicalPlanImpl::SerializedPhysicalPlanRef($plan) => $body, - PhysicalPlanImpl::Shuffle($plan) => $body, - PhysicalPlanImpl::Sort($plan) => $body, - PhysicalPlanImpl::TableScan($plan) => $body, - PhysicalPlanImpl::Udf($plan) => $body, - PhysicalPlanImpl::UnionAll($plan) => $body, - PhysicalPlanImpl::Window($plan) => $body, - PhysicalPlanImpl::WindowPartition($plan) => $body, - #[cfg(test)] - PhysicalPlanImpl::StackDepthPlan($plan) => $body, - } - }; -} - -#[cfg(test)] -impl From for PhysicalPlanImpl { - fn from(v: crate::physical_plans::physical_plan::tests::StackDepthPlan) -> Self { - PhysicalPlanImpl::StackDepthPlan(v) - } -} +include!(concat!(env!("OUT_DIR"), "/physical_plan_dispatch.rs")); pub struct PhysicalPlan { inner: Box, diff --git a/src/query/service/src/physical_plans/physical_project_set.rs b/src/query/service/src/physical_plans/physical_project_set.rs index 8b8809ed5a25d..9bf267dbe01dd 100644 --- a/src/query/service/src/physical_plans/physical_project_set.rs +++ b/src/query/service/src/physical_plans/physical_project_set.rs @@ -188,3 +188,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(ProjectSet => crate::physical_plans::physical_project_set::ProjectSet); diff --git a/src/query/service/src/physical_plans/physical_r_cte_scan.rs b/src/query/service/src/physical_plans/physical_r_cte_scan.rs index 9e6792005714a..643f2edc2d227 100644 --- a/src/query/service/src/physical_plans/physical_r_cte_scan.rs +++ b/src/query/service/src/physical_plans/physical_r_cte_scan.rs @@ -98,3 +98,5 @@ impl Display for RecursiveCteScan { write!(f, "RecursiveCTEScan") } } + +crate::register_physical_plan!(RecursiveCteScan => crate::physical_plans::physical_r_cte_scan::RecursiveCteScan); diff --git a/src/query/service/src/physical_plans/physical_range_join.rs b/src/query/service/src/physical_plans/physical_range_join.rs index eb719459521b8..f5a786cfb8575 100644 --- a/src/query/service/src/physical_plans/physical_range_join.rs +++ b/src/query/service/src/physical_plans/physical_range_join.rs @@ -348,3 +348,5 @@ fn resolve_scalar(scalar: &ScalarExpr, schema: &DataSchemaRef) -> Result crate::physical_plans::physical_range_join::RangeJoin); diff --git a/src/query/service/src/physical_plans/physical_recluster.rs b/src/query/service/src/physical_plans/physical_recluster.rs index 0a6c80bede960..6e41997f254c6 100644 --- a/src/query/service/src/physical_plans/physical_recluster.rs +++ b/src/query/service/src/physical_plans/physical_recluster.rs @@ -372,3 +372,7 @@ impl IPhysicalPlan for HilbertPartition { }) } } + +crate::register_physical_plan!(HilbertPartition => crate::physical_plans::physical_recluster::HilbertPartition); + +crate::register_physical_plan!(Recluster => crate::physical_plans::physical_recluster::Recluster); diff --git a/src/query/service/src/physical_plans/physical_replace_async_source.rs b/src/query/service/src/physical_plans/physical_replace_async_source.rs index cc1379fc1f233..bf40123e2b203 100644 --- a/src/query/service/src/physical_plans/physical_replace_async_source.rs +++ b/src/query/service/src/physical_plans/physical_replace_async_source.rs @@ -82,3 +82,5 @@ impl IPhysicalPlan for ReplaceAsyncSourcer { ) } } + +crate::register_physical_plan!(ReplaceAsyncSourcer => crate::physical_plans::physical_replace_async_source::ReplaceAsyncSourcer); diff --git a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs index b28712e83354b..448d5d0845301 100644 --- a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs +++ b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs @@ -229,3 +229,5 @@ pub struct ReplaceSelectCtx { pub select_column_bindings: Vec, pub select_schema: DataSchemaRef, } + +crate::register_physical_plan!(ReplaceDeduplicate => crate::physical_plans::physical_replace_deduplicate::ReplaceDeduplicate); diff --git a/src/query/service/src/physical_plans/physical_replace_into.rs b/src/query/service/src/physical_plans/physical_replace_into.rs index 09a75dd9847b8..37eae23e1a082 100644 --- a/src/query/service/src/physical_plans/physical_replace_into.rs +++ b/src/query/service/src/physical_plans/physical_replace_into.rs @@ -250,3 +250,5 @@ impl IPhysicalPlan for ReplaceInto { Ok(()) } } + +crate::register_physical_plan!(ReplaceInto => crate::physical_plans::physical_replace_into::ReplaceInto); diff --git a/src/query/service/src/physical_plans/physical_row_fetch.rs b/src/query/service/src/physical_plans/physical_row_fetch.rs index 32eb1667e9a0b..3f404bdb7c764 100644 --- a/src/query/service/src/physical_plans/physical_row_fetch.rs +++ b/src/query/service/src/physical_plans/physical_row_fetch.rs @@ -145,3 +145,5 @@ impl IPhysicalPlan for RowFetch { Ok(()) } } + +crate::register_physical_plan!(RowFetch => crate::physical_plans::physical_row_fetch::RowFetch); diff --git a/src/query/service/src/physical_plans/physical_secure_filter.rs b/src/query/service/src/physical_plans/physical_secure_filter.rs index 1480ea2e5a6c4..7c6f15b2ad203 100644 --- a/src/query/service/src/physical_plans/physical_secure_filter.rs +++ b/src/query/service/src/physical_plans/physical_secure_filter.rs @@ -185,3 +185,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(SecureFilter => crate::physical_plans::physical_secure_filter::SecureFilter); diff --git a/src/query/service/src/physical_plans/physical_sequence.rs b/src/query/service/src/physical_plans/physical_sequence.rs index a0923d68cd655..ec925a1f2d792 100644 --- a/src/query/service/src/physical_plans/physical_sequence.rs +++ b/src/query/service/src/physical_plans/physical_sequence.rs @@ -118,3 +118,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Sequence => crate::physical_plans::physical_sequence::Sequence); diff --git a/src/query/service/src/physical_plans/physical_sort.rs b/src/query/service/src/physical_plans/physical_sort.rs index a4ade17b55d00..b92a005ac50d3 100644 --- a/src/query/service/src/physical_plans/physical_sort.rs +++ b/src/query/service/src/physical_plans/physical_sort.rs @@ -535,3 +535,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Sort => crate::physical_plans::physical_sort::Sort); diff --git a/src/query/service/src/physical_plans/physical_table_scan.rs b/src/query/service/src/physical_plans/physical_table_scan.rs index 7cd3896a26a7b..d47d1ab8777d5 100644 --- a/src/query/service/src/physical_plans/physical_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_table_scan.rs @@ -994,3 +994,5 @@ impl PhysicalPlanBuilder { } } } + +crate::register_physical_plan!(TableScan => crate::physical_plans::physical_table_scan::TableScan); diff --git a/src/query/service/src/physical_plans/physical_udf.rs b/src/query/service/src/physical_plans/physical_udf.rs index 0ec99673786db..85689011a7956 100644 --- a/src/query/service/src/physical_plans/physical_udf.rs +++ b/src/query/service/src/physical_plans/physical_udf.rs @@ -241,3 +241,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Udf => crate::physical_plans::physical_udf::Udf); diff --git a/src/query/service/src/physical_plans/physical_union_all.rs b/src/query/service/src/physical_plans/physical_union_all.rs index dd669de1d18a8..390163d9dd481 100644 --- a/src/query/service/src/physical_plans/physical_union_all.rs +++ b/src/query/service/src/physical_plans/physical_union_all.rs @@ -314,3 +314,5 @@ fn process_outputs( } Ok(results) } + +crate::register_physical_plan!(UnionAll => crate::physical_plans::physical_union_all::UnionAll); diff --git a/src/query/service/src/physical_plans/physical_window.rs b/src/query/service/src/physical_plans/physical_window.rs index daaaedcb2d725..62b8c2f41f989 100644 --- a/src/query/service/src/physical_plans/physical_window.rs +++ b/src/query/service/src/physical_plans/physical_window.rs @@ -576,3 +576,5 @@ impl PhysicalPlanBuilder { })) } } + +crate::register_physical_plan!(Window => crate::physical_plans::physical_window::Window); diff --git a/src/query/service/src/physical_plans/physical_window_partition.rs b/src/query/service/src/physical_plans/physical_window_partition.rs index e8c652a995d0b..40494737fa3d3 100644 --- a/src/query/service/src/physical_plans/physical_window_partition.rs +++ b/src/query/service/src/physical_plans/physical_window_partition.rs @@ -202,3 +202,5 @@ pub enum WindowPartitionTopNFunc { Rank, DenseRank, } + +crate::register_physical_plan!(WindowPartition => crate::physical_plans::physical_window_partition::WindowPartition); diff --git a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs index b4b51f5fb5de8..3b164676a896c 100644 --- a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs +++ b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs @@ -143,3 +143,5 @@ impl Debug for QueryFragment { .finish() } } + +crate::register_physical_plan!(SerializedPhysicalPlanRef => crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef); From d8da122cf00504b7f90e5b16369e6a6280b35d00 Mon Sep 17 00:00:00 2001 From: kould Date: Wed, 17 Dec 2025 17:49:47 +0800 Subject: [PATCH 05/12] chore: remove register_physical_plan! --- src/query/service/build.rs | 85 +++++++++++++------ src/query/service/src/physical_plans/mod.rs | 10 --- .../physical_add_stream_column.rs | 2 - .../physical_aggregate_expand.rs | 2 - .../physical_aggregate_final.rs | 2 - .../physical_aggregate_partial.rs | 2 - .../src/physical_plans/physical_async_func.rs | 2 - .../src/physical_plans/physical_broadcast.rs | 4 - .../src/physical_plans/physical_cache_scan.rs | 2 - .../physical_column_mutation.rs | 2 - .../physical_plans/physical_commit_sink.rs | 2 - .../physical_plans/physical_compact_source.rs | 2 - .../physical_constant_table_scan.rs | 2 - .../physical_copy_into_location.rs | 2 - .../physical_copy_into_table.rs | 2 - .../physical_plans/physical_cte_consumer.rs | 2 - .../physical_distributed_insert_select.rs | 2 - .../physical_plans/physical_eval_scalar.rs | 2 - .../src/physical_plans/physical_exchange.rs | 2 - .../physical_plans/physical_exchange_sink.rs | 2 - .../physical_exchange_source.rs | 2 - .../physical_expression_scan.rs | 2 - .../src/physical_plans/physical_filter.rs | 2 - .../src/physical_plans/physical_hash_join.rs | 2 - .../src/physical_plans/physical_limit.rs | 2 - .../physical_materialized_cte.rs | 2 - .../physical_multi_table_insert.rs | 18 ---- .../src/physical_plans/physical_mutation.rs | 2 - .../physical_mutation_into_organize.rs | 2 - .../physical_mutation_into_split.rs | 2 - .../physical_mutation_manipulate.rs | 2 - .../physical_mutation_source.rs | 2 - .../physical_plans/physical_project_set.rs | 2 - .../src/physical_plans/physical_r_cte_scan.rs | 2 - .../src/physical_plans/physical_range_join.rs | 2 - .../src/physical_plans/physical_recluster.rs | 4 - .../physical_replace_async_source.rs | 2 - .../physical_replace_deduplicate.rs | 2 - .../physical_plans/physical_replace_into.rs | 2 - .../src/physical_plans/physical_row_fetch.rs | 2 - .../physical_plans/physical_secure_filter.rs | 2 - .../src/physical_plans/physical_sequence.rs | 2 - .../src/physical_plans/physical_sort.rs | 2 - .../src/physical_plans/physical_table_scan.rs | 2 - .../src/physical_plans/physical_udf.rs | 2 - .../src/physical_plans/physical_union_all.rs | 2 - .../src/physical_plans/physical_window.rs | 2 - .../physical_window_partition.rs | 2 - .../flight/v1/packets/packet_fragment.rs | 2 - 49 files changed, 60 insertions(+), 149 deletions(-) diff --git a/src/query/service/build.rs b/src/query/service/build.rs index 5b6813e9cc26b..1e934f5ad31f2 100644 --- a/src/query/service/build.rs +++ b/src/query/service/build.rs @@ -16,6 +16,7 @@ use std::env; use std::fs; use std::io::Write; use std::path::Path; +use std::path::PathBuf; fn main() { // Keep build script rerun behavior explicit for the feature list we expose. @@ -55,13 +56,13 @@ fn main() { let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); let src_dir = Path::new(&manifest_dir).join("src"); - let out_dir = Path::new(&env::var("OUT_DIR").expect("OUT_DIR not set")).to_path_buf(); + let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set")); - let mut entries = collect_registrations(&src_dir); + let mut entries = collect_impls(&src_dir); entries.sort_by(|a, b| a.1.cmp(&b.1)); - let out_path = out_dir.join("physical_plan_impls.rs"); - write_impls(&out_path, &entries); + let impls_out = out_dir.join("physical_plan_impls.rs"); + write_impls(&impls_out, &entries); let dispatch_out = out_dir.join("physical_plan_dispatch.rs"); write_dispatch(&dispatch_out, &entries); @@ -69,7 +70,7 @@ fn main() { println!("cargo:rerun-if-changed={}", src_dir.display()); } -fn collect_registrations(src_dir: &Path) -> Vec<(Option, String, String)> { +fn collect_impls(src_dir: &Path) -> Vec<(Option, String, String)> { let mut entries = Vec::new(); for entry in walkdir::WalkDir::new(src_dir) @@ -85,34 +86,68 @@ fn collect_registrations(src_dir: &Path) -> Vec<(Option, String, String) .unwrap_or_else(|e| panic!("read {}: {e}", entry.path().display())); for line in content.lines() { - if let Some(pos) = line.find("register_physical_plan!") { - let rest = &line[pos..]; - if let Some((variant, path)) = parse_registration(rest) { - entries.push((None, variant, path)); - } + if let Some(e) = parse_impl_line(src_dir, entry.path(), line) { + entries.push(e); } } } - // test-only plan variant - entries.push(( - Some("#[cfg(test)]".to_string()), - "StackDepthPlan".to_string(), - "crate::physical_plans::physical_plan::tests::StackDepthPlan".to_string(), - )); - entries } -fn parse_registration(line: &str) -> Option<(String, String)> { - let start = line.find('(')? + 1; - let end = line.find(')')?; - let body = &line[start..end]; - let mut parts = body.split("=>").map(str::trim); - let variant = parts.next()?.trim_end_matches(','); - let path = parts.next()?.trim_end_matches(','); +fn parse_impl_line( + src_root: &Path, + path: &Path, + line: &str, +) -> Option<(Option, String, String)> { + // match `impl ... IPhysicalPlan for Type ... {` + let marker = "IPhysicalPlan for"; + let idx = line.find(marker)?; + let after = &line[idx + marker.len()..]; + let type_part = after + .split_whitespace() + .next() + .unwrap_or("") + .trim_end_matches('{') + .trim_end_matches(';'); + if type_part.is_empty() { + return None; + } + + let type_name = type_part + .split("::") + .last() + .unwrap_or(type_part) + .split('<') + .next() + .unwrap_or(type_part) + .to_string(); + + let mut module_path = module_path_from_file(src_root, path); + let mut meta = None; + + if type_name == "StackDepthPlan" && path.ends_with("physical_plan.rs") { + module_path.push_str("::tests"); + meta = Some("#[cfg(test)]".to_string()); + } + + let full_path = format!("{module_path}::{type_part}"); + + Some((meta, type_name, full_path)) +} - Some((variant.to_string(), path.to_string())) +fn module_path_from_file(src_root: &Path, path: &Path) -> String { + let mut module_path = String::from("crate"); + let rel = path + .strip_prefix(src_root) + .unwrap_or(path) + .with_extension(""); + for comp in rel.components() { + let c = comp.as_os_str().to_string_lossy(); + module_path.push_str("::"); + module_path.push_str(&c); + } + module_path } fn write_impls(out_path: &Path, entries: &[(Option, String, String)]) { diff --git a/src/query/service/src/physical_plans/mod.rs b/src/query/service/src/physical_plans/mod.rs index 40ec81a3db00c..d5780e1ec116f 100644 --- a/src/query/service/src/physical_plans/mod.rs +++ b/src/query/service/src/physical_plans/mod.rs @@ -109,16 +109,6 @@ pub use physical_window_partition::*; pub use runtime_filter::PhysicalRuntimeFilter; pub use runtime_filter::PhysicalRuntimeFilters; -// Marker macro: used by build.rs to collect physical plan variants for codegen. -// Expands to a no-op, so plan modules can call it without affecting runtime code. -#[macro_export] -macro_rules! register_physical_plan { - ($variant:ident => $path:path) => { - #[allow(dead_code)] - const _: () = (); - }; -} - pub mod explain; mod format; mod physical_cte_consumer; diff --git a/src/query/service/src/physical_plans/physical_add_stream_column.rs b/src/query/service/src/physical_plans/physical_add_stream_column.rs index 6629e427d76b0..be64e12bdb81e 100644 --- a/src/query/service/src/physical_plans/physical_add_stream_column.rs +++ b/src/query/service/src/physical_plans/physical_add_stream_column.rs @@ -245,5 +245,3 @@ impl AddStreamColumn { })) } } - -crate::register_physical_plan!(AddStreamColumn => crate::physical_plans::physical_add_stream_column::AddStreamColumn); diff --git a/src/query/service/src/physical_plans/physical_aggregate_expand.rs b/src/query/service/src/physical_plans/physical_aggregate_expand.rs index a6da2a311b009..bc89ea8d4a84f 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_expand.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_expand.rs @@ -171,5 +171,3 @@ impl IPhysicalPlan for AggregateExpand { Ok(()) } } - -crate::register_physical_plan!(AggregateExpand => crate::physical_plans::physical_aggregate_expand::AggregateExpand); diff --git a/src/query/service/src/physical_plans/physical_aggregate_final.rs b/src/query/service/src/physical_plans/physical_aggregate_final.rs index 20cdaf0b1bddf..ae2c7ed5d43aa 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_final.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_final.rs @@ -675,5 +675,3 @@ impl PhysicalPlanBuilder { Ok(result) } } - -crate::register_physical_plan!(AggregateFinal => crate::physical_plans::physical_aggregate_final::AggregateFinal); diff --git a/src/query/service/src/physical_plans/physical_aggregate_partial.rs b/src/query/service/src/physical_plans/physical_aggregate_partial.rs index 53d714f822100..e041e64ca2480 100644 --- a/src/query/service/src/physical_plans/physical_aggregate_partial.rs +++ b/src/query/service/src/physical_plans/physical_aggregate_partial.rs @@ -304,5 +304,3 @@ impl AggregatePartial { Some((resolved.into(), *limit)) } } - -crate::register_physical_plan!(AggregatePartial => crate::physical_plans::physical_aggregate_partial::AggregatePartial); diff --git a/src/query/service/src/physical_plans/physical_async_func.rs b/src/query/service/src/physical_plans/physical_async_func.rs index deeebfdb70482..fb2a49b4a41b9 100644 --- a/src/query/service/src/physical_plans/physical_async_func.rs +++ b/src/query/service/src/physical_plans/physical_async_func.rs @@ -200,5 +200,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(AsyncFunction => crate::physical_plans::physical_async_func::AsyncFunction); diff --git a/src/query/service/src/physical_plans/physical_broadcast.rs b/src/query/service/src/physical_plans/physical_broadcast.rs index 23d045c3a8033..369c2f66a16c3 100644 --- a/src/query/service/src/physical_plans/physical_broadcast.rs +++ b/src/query/service/src/physical_plans/physical_broadcast.rs @@ -156,7 +156,3 @@ pub fn build_broadcast_plans(ctx: &dyn TableContext) -> Result } Ok(plans) } - -crate::register_physical_plan!(BroadcastSink => crate::physical_plans::physical_broadcast::BroadcastSink); - -crate::register_physical_plan!(BroadcastSource => crate::physical_plans::physical_broadcast::BroadcastSource); diff --git a/src/query/service/src/physical_plans/physical_cache_scan.rs b/src/query/service/src/physical_plans/physical_cache_scan.rs index 7cb8fd60c48c7..8ce47add85ef6 100644 --- a/src/query/service/src/physical_plans/physical_cache_scan.rs +++ b/src/query/service/src/physical_plans/physical_cache_scan.rs @@ -133,5 +133,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(CacheScan => crate::physical_plans::physical_cache_scan::CacheScan); diff --git a/src/query/service/src/physical_plans/physical_column_mutation.rs b/src/query/service/src/physical_plans/physical_column_mutation.rs index deeec04f84669..791fb423920c1 100644 --- a/src/query/service/src/physical_plans/physical_column_mutation.rs +++ b/src/query/service/src/physical_plans/physical_column_mutation.rs @@ -214,5 +214,3 @@ impl IPhysicalPlan for ColumnMutation { }) } } - -crate::register_physical_plan!(ColumnMutation => crate::physical_plans::physical_column_mutation::ColumnMutation); diff --git a/src/query/service/src/physical_plans/physical_commit_sink.rs b/src/query/service/src/physical_plans/physical_commit_sink.rs index a02443d73076d..ac4928807af7e 100644 --- a/src/query/service/src/physical_plans/physical_commit_sink.rs +++ b/src/query/service/src/physical_plans/physical_commit_sink.rs @@ -225,5 +225,3 @@ pub enum CommitType { merge_meta: bool, }, } - -crate::register_physical_plan!(CommitSink => crate::physical_plans::physical_commit_sink::CommitSink); diff --git a/src/query/service/src/physical_plans/physical_compact_source.rs b/src/query/service/src/physical_plans/physical_compact_source.rs index b5a6e46e36488..50c4723f28dac 100644 --- a/src/query/service/src/physical_plans/physical_compact_source.rs +++ b/src/query/service/src/physical_plans/physical_compact_source.rs @@ -294,5 +294,3 @@ impl PhysicalPlanBuilder { Ok(root) } } - -crate::register_physical_plan!(CompactSource => crate::physical_plans::physical_compact_source::CompactSource); diff --git a/src/query/service/src/physical_plans/physical_constant_table_scan.rs b/src/query/service/src/physical_plans/physical_constant_table_scan.rs index fc86bed007c34..86b18bc3254b6 100644 --- a/src/query/service/src/physical_plans/physical_constant_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_constant_table_scan.rs @@ -133,5 +133,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(ConstantTableScan => crate::physical_plans::physical_constant_table_scan::ConstantTableScan); diff --git a/src/query/service/src/physical_plans/physical_copy_into_location.rs b/src/query/service/src/physical_plans/physical_copy_into_location.rs index 47db76eaecddd..ee4ed64edb7ad 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_location.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_location.rs @@ -145,5 +145,3 @@ fn sink_create_by(version: &Version) -> String { } create_by } - -crate::register_physical_plan!(CopyIntoLocation => crate::physical_plans::physical_copy_into_location::CopyIntoLocation); diff --git a/src/query/service/src/physical_plans/physical_copy_into_table.rs b/src/query/service/src/physical_plans/physical_copy_into_table.rs index 7dc255ab628ab..8e45028be76d1 100644 --- a/src/query/service/src/physical_plans/physical_copy_into_table.rs +++ b/src/query/service/src/physical_plans/physical_copy_into_table.rs @@ -186,5 +186,3 @@ pub enum CopyIntoTableSource { Query(PhysicalPlan), Stage(PhysicalPlan), } - -crate::register_physical_plan!(CopyIntoTable => crate::physical_plans::physical_copy_into_table::CopyIntoTable); diff --git a/src/query/service/src/physical_plans/physical_cte_consumer.rs b/src/query/service/src/physical_plans/physical_cte_consumer.rs index 4ebfb2e77c605..6304d2563db06 100644 --- a/src/query/service/src/physical_plans/physical_cte_consumer.rs +++ b/src/query/service/src/physical_plans/physical_cte_consumer.rs @@ -110,5 +110,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(MaterializeCTERef => crate::physical_plans::physical_cte_consumer::MaterializeCTERef); diff --git a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs index 8827df25b0cec..66a628e74a86a 100644 --- a/src/query/service/src/physical_plans/physical_distributed_insert_select.rs +++ b/src/query/service/src/physical_plans/physical_distributed_insert_select.rs @@ -130,5 +130,3 @@ impl IPhysicalPlan for DistributedInsertSelect { Ok(()) } } - -crate::register_physical_plan!(DistributedInsertSelect => crate::physical_plans::physical_distributed_insert_select::DistributedInsertSelect); diff --git a/src/query/service/src/physical_plans/physical_eval_scalar.rs b/src/query/service/src/physical_plans/physical_eval_scalar.rs index e76382320c08b..7dd418ee01e7a 100644 --- a/src/query/service/src/physical_plans/physical_eval_scalar.rs +++ b/src/query/service/src/physical_plans/physical_eval_scalar.rs @@ -409,5 +409,3 @@ impl<'a> Visitor<'a> for FlattenColumnsVisitor { Ok(()) } } - -crate::register_physical_plan!(EvalScalar => crate::physical_plans::physical_eval_scalar::EvalScalar); diff --git a/src/query/service/src/physical_plans/physical_exchange.rs b/src/query/service/src/physical_plans/physical_exchange.rs index a58de063142c7..62ee27d393daa 100644 --- a/src/query/service/src/physical_plans/physical_exchange.rs +++ b/src/query/service/src/physical_plans/physical_exchange.rs @@ -138,5 +138,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Exchange => crate::physical_plans::physical_exchange::Exchange); diff --git a/src/query/service/src/physical_plans/physical_exchange_sink.rs b/src/query/service/src/physical_plans/physical_exchange_sink.rs index ee2c2df387307..5a30fb0bff35a 100644 --- a/src/query/service/src/physical_plans/physical_exchange_sink.rs +++ b/src/query/service/src/physical_plans/physical_exchange_sink.rs @@ -108,5 +108,3 @@ impl IPhysicalPlan for ExchangeSink { self.input.build_pipeline(builder) } } - -crate::register_physical_plan!(ExchangeSink => crate::physical_plans::physical_exchange_sink::ExchangeSink); diff --git a/src/query/service/src/physical_plans/physical_exchange_source.rs b/src/query/service/src/physical_plans/physical_exchange_source.rs index 8389fd3353dec..89421c7650d73 100644 --- a/src/query/service/src/physical_plans/physical_exchange_source.rs +++ b/src/query/service/src/physical_plans/physical_exchange_source.rs @@ -99,5 +99,3 @@ impl IPhysicalPlan for ExchangeSource { Ok(()) } } - -crate::register_physical_plan!(ExchangeSource => crate::physical_plans::physical_exchange_source::ExchangeSource); diff --git a/src/query/service/src/physical_plans/physical_expression_scan.rs b/src/query/service/src/physical_plans/physical_expression_scan.rs index cdab1633854c7..a92073ec66b74 100644 --- a/src/query/service/src/physical_plans/physical_expression_scan.rs +++ b/src/query/service/src/physical_plans/physical_expression_scan.rs @@ -146,5 +146,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(ExpressionScan => crate::physical_plans::physical_expression_scan::ExpressionScan); diff --git a/src/query/service/src/physical_plans/physical_filter.rs b/src/query/service/src/physical_plans/physical_filter.rs index 91423548275fe..ca63475d6e1c5 100644 --- a/src/query/service/src/physical_plans/physical_filter.rs +++ b/src/query/service/src/physical_plans/physical_filter.rs @@ -176,5 +176,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Filter => crate::physical_plans::physical_filter::Filter); diff --git a/src/query/service/src/physical_plans/physical_hash_join.rs b/src/query/service/src/physical_plans/physical_hash_join.rs index 3d811a1d8388c..979b594c47aa0 100644 --- a/src/query/service/src/physical_plans/physical_hash_join.rs +++ b/src/query/service/src/physical_plans/physical_hash_join.rs @@ -1362,5 +1362,3 @@ impl PhysicalPlanBuilder { ) } } - -crate::register_physical_plan!(HashJoin => crate::physical_plans::physical_hash_join::HashJoin); diff --git a/src/query/service/src/physical_plans/physical_limit.rs b/src/query/service/src/physical_plans/physical_limit.rs index d2b5c1a91f908..b752fc2c5ebd5 100644 --- a/src/query/service/src/physical_plans/physical_limit.rs +++ b/src/query/service/src/physical_plans/physical_limit.rs @@ -248,5 +248,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Limit => crate::physical_plans::physical_limit::Limit); diff --git a/src/query/service/src/physical_plans/physical_materialized_cte.rs b/src/query/service/src/physical_plans/physical_materialized_cte.rs index f02e067faf82f..85aa1591ef68a 100644 --- a/src/query/service/src/physical_plans/physical_materialized_cte.rs +++ b/src/query/service/src/physical_plans/physical_materialized_cte.rs @@ -142,5 +142,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(MaterializedCTE => crate::physical_plans::physical_materialized_cte::MaterializedCTE); diff --git a/src/query/service/src/physical_plans/physical_multi_table_insert.rs b/src/query/service/src/physical_plans/physical_multi_table_insert.rs index fd1c3f1f89077..97177e4c03e75 100644 --- a/src/query/service/src/physical_plans/physical_multi_table_insert.rs +++ b/src/query/service/src/physical_plans/physical_multi_table_insert.rs @@ -796,21 +796,3 @@ impl IPhysicalPlan for ChunkCommitInsert { }) } } - -crate::register_physical_plan!(ChunkAppendData => crate::physical_plans::physical_multi_table_insert::ChunkAppendData); - -crate::register_physical_plan!(ChunkCastSchema => crate::physical_plans::physical_multi_table_insert::ChunkCastSchema); - -crate::register_physical_plan!(ChunkCommitInsert => crate::physical_plans::physical_multi_table_insert::ChunkCommitInsert); - -crate::register_physical_plan!(ChunkEvalScalar => crate::physical_plans::physical_multi_table_insert::ChunkEvalScalar); - -crate::register_physical_plan!(ChunkFillAndReorder => crate::physical_plans::physical_multi_table_insert::ChunkFillAndReorder); - -crate::register_physical_plan!(ChunkFilter => crate::physical_plans::physical_multi_table_insert::ChunkFilter); - -crate::register_physical_plan!(ChunkMerge => crate::physical_plans::physical_multi_table_insert::ChunkMerge); - -crate::register_physical_plan!(Duplicate => crate::physical_plans::physical_multi_table_insert::Duplicate); - -crate::register_physical_plan!(Shuffle => crate::physical_plans::physical_multi_table_insert::Shuffle); diff --git a/src/query/service/src/physical_plans/physical_mutation.rs b/src/query/service/src/physical_plans/physical_mutation.rs index ef5cdd7a78223..44233c54749ce 100644 --- a/src/query/service/src/physical_plans/physical_mutation.rs +++ b/src/query/service/src/physical_plans/physical_mutation.rs @@ -1069,5 +1069,3 @@ fn build_field_id_to_schema_index( } } } - -crate::register_physical_plan!(Mutation => crate::physical_plans::physical_mutation::Mutation); diff --git a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs index 14fa59b21da2e..109008955e1b3 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_organize.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_organize.rs @@ -137,5 +137,3 @@ impl MutationOrganize { builder.main_pipeline.resize_partial_one(ranges.clone()) } } - -crate::register_physical_plan!(MutationOrganize => crate::physical_plans::physical_mutation_into_organize::MutationOrganize); diff --git a/src/query/service/src/physical_plans/physical_mutation_into_split.rs b/src/query/service/src/physical_plans/physical_mutation_into_split.rs index b7386f7e5ea75..ae1386499e434 100644 --- a/src/query/service/src/physical_plans/physical_mutation_into_split.rs +++ b/src/query/service/src/physical_plans/physical_mutation_into_split.rs @@ -89,5 +89,3 @@ impl IPhysicalPlan for MutationSplit { Ok(()) } } - -crate::register_physical_plan!(MutationSplit => crate::physical_plans::physical_mutation_into_split::MutationSplit); diff --git a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs index 38b84b75e0e05..097be7b288812 100644 --- a/src/query/service/src/physical_plans/physical_mutation_manipulate.rs +++ b/src/query/service/src/physical_plans/physical_mutation_manipulate.rs @@ -168,5 +168,3 @@ impl IPhysicalPlan for MutationManipulate { Ok(()) } } - -crate::register_physical_plan!(MutationManipulate => crate::physical_plans::physical_mutation_manipulate::MutationManipulate); diff --git a/src/query/service/src/physical_plans/physical_mutation_source.rs b/src/query/service/src/physical_plans/physical_mutation_source.rs index f31e327caee70..44f725a28654a 100644 --- a/src/query/service/src/physical_plans/physical_mutation_source.rs +++ b/src/query/service/src/physical_plans/physical_mutation_source.rs @@ -310,5 +310,3 @@ pub fn create_push_down_filters( inverted_filter: remote_inverted_filter, }) } - -crate::register_physical_plan!(MutationSource => crate::physical_plans::physical_mutation_source::MutationSource); diff --git a/src/query/service/src/physical_plans/physical_project_set.rs b/src/query/service/src/physical_plans/physical_project_set.rs index 9bf267dbe01dd..8b8809ed5a25d 100644 --- a/src/query/service/src/physical_plans/physical_project_set.rs +++ b/src/query/service/src/physical_plans/physical_project_set.rs @@ -188,5 +188,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(ProjectSet => crate::physical_plans::physical_project_set::ProjectSet); diff --git a/src/query/service/src/physical_plans/physical_r_cte_scan.rs b/src/query/service/src/physical_plans/physical_r_cte_scan.rs index 643f2edc2d227..9e6792005714a 100644 --- a/src/query/service/src/physical_plans/physical_r_cte_scan.rs +++ b/src/query/service/src/physical_plans/physical_r_cte_scan.rs @@ -98,5 +98,3 @@ impl Display for RecursiveCteScan { write!(f, "RecursiveCTEScan") } } - -crate::register_physical_plan!(RecursiveCteScan => crate::physical_plans::physical_r_cte_scan::RecursiveCteScan); diff --git a/src/query/service/src/physical_plans/physical_range_join.rs b/src/query/service/src/physical_plans/physical_range_join.rs index f5a786cfb8575..eb719459521b8 100644 --- a/src/query/service/src/physical_plans/physical_range_join.rs +++ b/src/query/service/src/physical_plans/physical_range_join.rs @@ -348,5 +348,3 @@ fn resolve_scalar(scalar: &ScalarExpr, schema: &DataSchemaRef) -> Result crate::physical_plans::physical_range_join::RangeJoin); diff --git a/src/query/service/src/physical_plans/physical_recluster.rs b/src/query/service/src/physical_plans/physical_recluster.rs index 6e41997f254c6..0a6c80bede960 100644 --- a/src/query/service/src/physical_plans/physical_recluster.rs +++ b/src/query/service/src/physical_plans/physical_recluster.rs @@ -372,7 +372,3 @@ impl IPhysicalPlan for HilbertPartition { }) } } - -crate::register_physical_plan!(HilbertPartition => crate::physical_plans::physical_recluster::HilbertPartition); - -crate::register_physical_plan!(Recluster => crate::physical_plans::physical_recluster::Recluster); diff --git a/src/query/service/src/physical_plans/physical_replace_async_source.rs b/src/query/service/src/physical_plans/physical_replace_async_source.rs index bf40123e2b203..cc1379fc1f233 100644 --- a/src/query/service/src/physical_plans/physical_replace_async_source.rs +++ b/src/query/service/src/physical_plans/physical_replace_async_source.rs @@ -82,5 +82,3 @@ impl IPhysicalPlan for ReplaceAsyncSourcer { ) } } - -crate::register_physical_plan!(ReplaceAsyncSourcer => crate::physical_plans::physical_replace_async_source::ReplaceAsyncSourcer); diff --git a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs index 448d5d0845301..b28712e83354b 100644 --- a/src/query/service/src/physical_plans/physical_replace_deduplicate.rs +++ b/src/query/service/src/physical_plans/physical_replace_deduplicate.rs @@ -229,5 +229,3 @@ pub struct ReplaceSelectCtx { pub select_column_bindings: Vec, pub select_schema: DataSchemaRef, } - -crate::register_physical_plan!(ReplaceDeduplicate => crate::physical_plans::physical_replace_deduplicate::ReplaceDeduplicate); diff --git a/src/query/service/src/physical_plans/physical_replace_into.rs b/src/query/service/src/physical_plans/physical_replace_into.rs index 37eae23e1a082..09a75dd9847b8 100644 --- a/src/query/service/src/physical_plans/physical_replace_into.rs +++ b/src/query/service/src/physical_plans/physical_replace_into.rs @@ -250,5 +250,3 @@ impl IPhysicalPlan for ReplaceInto { Ok(()) } } - -crate::register_physical_plan!(ReplaceInto => crate::physical_plans::physical_replace_into::ReplaceInto); diff --git a/src/query/service/src/physical_plans/physical_row_fetch.rs b/src/query/service/src/physical_plans/physical_row_fetch.rs index 3f404bdb7c764..32eb1667e9a0b 100644 --- a/src/query/service/src/physical_plans/physical_row_fetch.rs +++ b/src/query/service/src/physical_plans/physical_row_fetch.rs @@ -145,5 +145,3 @@ impl IPhysicalPlan for RowFetch { Ok(()) } } - -crate::register_physical_plan!(RowFetch => crate::physical_plans::physical_row_fetch::RowFetch); diff --git a/src/query/service/src/physical_plans/physical_secure_filter.rs b/src/query/service/src/physical_plans/physical_secure_filter.rs index 7c6f15b2ad203..1480ea2e5a6c4 100644 --- a/src/query/service/src/physical_plans/physical_secure_filter.rs +++ b/src/query/service/src/physical_plans/physical_secure_filter.rs @@ -185,5 +185,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(SecureFilter => crate::physical_plans::physical_secure_filter::SecureFilter); diff --git a/src/query/service/src/physical_plans/physical_sequence.rs b/src/query/service/src/physical_plans/physical_sequence.rs index ec925a1f2d792..a0923d68cd655 100644 --- a/src/query/service/src/physical_plans/physical_sequence.rs +++ b/src/query/service/src/physical_plans/physical_sequence.rs @@ -118,5 +118,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Sequence => crate::physical_plans::physical_sequence::Sequence); diff --git a/src/query/service/src/physical_plans/physical_sort.rs b/src/query/service/src/physical_plans/physical_sort.rs index b92a005ac50d3..a4ade17b55d00 100644 --- a/src/query/service/src/physical_plans/physical_sort.rs +++ b/src/query/service/src/physical_plans/physical_sort.rs @@ -535,5 +535,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Sort => crate::physical_plans::physical_sort::Sort); diff --git a/src/query/service/src/physical_plans/physical_table_scan.rs b/src/query/service/src/physical_plans/physical_table_scan.rs index d47d1ab8777d5..7cd3896a26a7b 100644 --- a/src/query/service/src/physical_plans/physical_table_scan.rs +++ b/src/query/service/src/physical_plans/physical_table_scan.rs @@ -994,5 +994,3 @@ impl PhysicalPlanBuilder { } } } - -crate::register_physical_plan!(TableScan => crate::physical_plans::physical_table_scan::TableScan); diff --git a/src/query/service/src/physical_plans/physical_udf.rs b/src/query/service/src/physical_plans/physical_udf.rs index 85689011a7956..0ec99673786db 100644 --- a/src/query/service/src/physical_plans/physical_udf.rs +++ b/src/query/service/src/physical_plans/physical_udf.rs @@ -241,5 +241,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Udf => crate::physical_plans::physical_udf::Udf); diff --git a/src/query/service/src/physical_plans/physical_union_all.rs b/src/query/service/src/physical_plans/physical_union_all.rs index 390163d9dd481..dd669de1d18a8 100644 --- a/src/query/service/src/physical_plans/physical_union_all.rs +++ b/src/query/service/src/physical_plans/physical_union_all.rs @@ -314,5 +314,3 @@ fn process_outputs( } Ok(results) } - -crate::register_physical_plan!(UnionAll => crate::physical_plans::physical_union_all::UnionAll); diff --git a/src/query/service/src/physical_plans/physical_window.rs b/src/query/service/src/physical_plans/physical_window.rs index 62b8c2f41f989..daaaedcb2d725 100644 --- a/src/query/service/src/physical_plans/physical_window.rs +++ b/src/query/service/src/physical_plans/physical_window.rs @@ -576,5 +576,3 @@ impl PhysicalPlanBuilder { })) } } - -crate::register_physical_plan!(Window => crate::physical_plans::physical_window::Window); diff --git a/src/query/service/src/physical_plans/physical_window_partition.rs b/src/query/service/src/physical_plans/physical_window_partition.rs index 40494737fa3d3..e8c652a995d0b 100644 --- a/src/query/service/src/physical_plans/physical_window_partition.rs +++ b/src/query/service/src/physical_plans/physical_window_partition.rs @@ -202,5 +202,3 @@ pub enum WindowPartitionTopNFunc { Rank, DenseRank, } - -crate::register_physical_plan!(WindowPartition => crate::physical_plans::physical_window_partition::WindowPartition); diff --git a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs index 3b164676a896c..b4b51f5fb5de8 100644 --- a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs +++ b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs @@ -143,5 +143,3 @@ impl Debug for QueryFragment { .finish() } } - -crate::register_physical_plan!(SerializedPhysicalPlanRef => crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef); From 6591e3c375a7c268b35979e5be1cc6e3d705c49d Mon Sep 17 00:00:00 2001 From: kould Date: Thu, 18 Dec 2025 14:25:14 +0800 Subject: [PATCH 06/12] chore: fix untagged on cluster --- .../src/physical_plans/physical_plan.rs | 26 ++++++++++++++++--- .../flight/v1/packets/packet_fragment.rs | 26 +++++++++++++++++-- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 89a16e724aedc..af2add5848b2b 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -341,11 +341,27 @@ impl serde::Serialize for PhysicalPlan { impl<'de> serde::Deserialize<'de> for PhysicalPlan { #[recursive::recursive] fn deserialize>(deserializer: D) -> std::result::Result { - let envelope = PhysicalPlanEnvelope::deserialize(deserializer)?; + // Deserialize to JSON first to avoid the untagged enum backtracking failure + // that happens in stacked/streaming deserializers. + let value = JsonValue::deserialize(deserializer)?; - let inner = match envelope { - PhysicalPlanEnvelope::V2(plan) => plan, - PhysicalPlanEnvelope::V1(LegacyPhysicalPlanImpl(plan)) => plan, + let try_v2: std::result::Result = + serde_json::from_value(value.clone()); + let inner = match try_v2 { + Ok(plan) => plan, + Err(v2_err) => { + let try_v1: std::result::Result = + serde_json::from_value(value); + + match try_v1 { + Ok(LegacyPhysicalPlanImpl(plan)) => plan, + Err(v1_err) => { + return Err(DeError::custom(format!( + "cannot deserialize PhysicalPlan, v2: {v2_err}, v1: {v1_err}" + ))) + } + } + } }; Ok(PhysicalPlan { @@ -355,12 +371,14 @@ impl<'de> serde::Deserialize<'de> for PhysicalPlan { } #[derive(serde::Serialize)] +#[allow(dead_code, unused)] #[serde(untagged)] enum PhysicalPlanEnvelopeRef<'a> { V2(&'a PhysicalPlanImpl), } #[derive(serde::Deserialize)] +#[allow(dead_code, unused)] #[serde(untagged)] enum PhysicalPlanEnvelope { V2(PhysicalPlanImpl), diff --git a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs index b4b51f5fb5de8..07f5dd4a7b0e2 100644 --- a/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs +++ b/src/query/service/src/servers/flight/v1/packets/packet_fragment.rs @@ -70,13 +70,20 @@ impl IPhysicalPlan for SerializedPhysicalPlanRef { } } -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, serde::Serialize)] struct SerializeQueryFragment { pub fragment_id: usize, pub data_exchange: Option, pub flatten_plan: VecDeque, } +#[derive(Clone, Debug, serde::Deserialize)] +struct SerializeQueryFragmentJson { + pub fragment_id: usize, + pub data_exchange: Option, + pub flatten_plan: VecDeque, +} + impl serde::Serialize for QueryFragment { #[recursive::recursive] fn serialize(&self, serializer: S) -> Result { @@ -107,7 +114,22 @@ impl serde::Serialize for QueryFragment { impl<'de> serde::Deserialize<'de> for QueryFragment { #[recursive::recursive] fn deserialize>(deserializer: D) -> Result { - let mut fragment = SerializeQueryFragment::deserialize(deserializer)?; + let fragment = SerializeQueryFragmentJson::deserialize(deserializer)?; + + // Deserialize PhysicalPlan node-by-node using Value to avoid streaming issues. + let flatten_plan: VecDeque = fragment + .flatten_plan + .into_iter() + .map(|plan| { + serde_json::from_value(plan) + .map_err(|e| D::Error::custom(format!("deserialize physical plan: {e}"))) + }) + .collect::>()?; + let mut fragment = SerializeQueryFragment { + fragment_id: fragment.fragment_id, + data_exchange: fragment.data_exchange, + flatten_plan, + }; let mut flatten_storage = HashMap::new(); From d20b047c8d4edbfc69cbf8dcead7db7953303882 Mon Sep 17 00:00:00 2001 From: kould Date: Thu, 18 Dec 2025 16:12:53 +0800 Subject: [PATCH 07/12] chore: Remove physical plan serialization compatibility --- .../src/physical_plans/physical_plan.rs | 190 +----------------- 1 file changed, 3 insertions(+), 187 deletions(-) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index af2add5848b2b..95b87b7d5e6d4 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -272,8 +272,6 @@ macro_rules! define_physical_plan_impl { ( $( $(#[$meta:meta])? $variant:ident => $path:path ),+ $(,)? ) => { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth - /// - /// compatibility: [LegacyPhysicalPlanImpl](LegacyPhysicalPlanImpl) pub(crate) enum PhysicalPlanImpl { $( $(#[$meta])? $variant($path), )+ } @@ -283,25 +281,6 @@ macro_rules! define_physical_plan_impl { PhysicalPlanImpl::$variant(v) } })+ - - impl PhysicalPlanImpl { - fn try_from_typetag_value( - type_name: &str, - value: JsonValue, - ) -> std::result::Result, E> { - $( - $(#[$meta])? - if type_name == std::any::type_name::<$path>() - || type_name == stringify!($variant) - { - let value = serde_json::from_value::<$path>(value).map_err(E::custom)?; - return Ok(Some(PhysicalPlanImpl::$variant(value))); - } - )+ - - Ok(None) - } - } }; } @@ -334,35 +313,16 @@ impl Debug for PhysicalPlan { impl serde::Serialize for PhysicalPlan { #[recursive::recursive] fn serialize(&self, serializer: S) -> std::result::Result { - PhysicalPlanEnvelopeRef::V2(self.inner.as_ref()).serialize(serializer) + self.inner.serialize(serializer) } } impl<'de> serde::Deserialize<'de> for PhysicalPlan { #[recursive::recursive] fn deserialize>(deserializer: D) -> std::result::Result { - // Deserialize to JSON first to avoid the untagged enum backtracking failure - // that happens in stacked/streaming deserializers. + // Deserialize to JSON first to avoid backtracking failures in streaming deserializers. let value = JsonValue::deserialize(deserializer)?; - - let try_v2: std::result::Result = - serde_json::from_value(value.clone()); - let inner = match try_v2 { - Ok(plan) => plan, - Err(v2_err) => { - let try_v1: std::result::Result = - serde_json::from_value(value); - - match try_v1 { - Ok(LegacyPhysicalPlanImpl(plan)) => plan, - Err(v1_err) => { - return Err(DeError::custom(format!( - "cannot deserialize PhysicalPlan, v2: {v2_err}, v1: {v1_err}" - ))) - } - } - } - }; + let inner: PhysicalPlanImpl = serde_json::from_value(value).map_err(DeError::custom)?; Ok(PhysicalPlan { inner: Box::new(inner), @@ -370,52 +330,6 @@ impl<'de> serde::Deserialize<'de> for PhysicalPlan { } } -#[derive(serde::Serialize)] -#[allow(dead_code, unused)] -#[serde(untagged)] -enum PhysicalPlanEnvelopeRef<'a> { - V2(&'a PhysicalPlanImpl), -} - -#[derive(serde::Deserialize)] -#[allow(dead_code, unused)] -#[serde(untagged)] -enum PhysicalPlanEnvelope { - V2(PhysicalPlanImpl), - V1(LegacyPhysicalPlanImpl), -} - -struct LegacyPhysicalPlanImpl(PhysicalPlanImpl); - -impl<'de> serde::Deserialize<'de> for LegacyPhysicalPlanImpl { - fn deserialize>(deserializer: D) -> std::result::Result { - let value = JsonValue::deserialize(deserializer)?; - let Some((type_name, rest)) = extract_typetag_value(value) else { - return Err(DeError::custom("missing typetag 'type' field")); - }; - - let Some(plan) = PhysicalPlanImpl::try_from_typetag_value::(&type_name, rest)? - else { - return Err(DeError::custom(format!( - "unknown typetag type: {type_name}" - ))); - }; - - Ok(LegacyPhysicalPlanImpl(plan)) - } -} - -fn extract_typetag_value(value: JsonValue) -> Option<(String, JsonValue)> { - let JsonValue::Object(mut map) = value else { - return None; - }; - - let type_value = map.remove("type")?; - let type_name = type_value.as_str()?.to_string(); - - Some((type_name, JsonValue::Object(map))) -} - impl PhysicalPlan { #[allow(private_bounds)] pub fn new(inner: T) -> PhysicalPlan @@ -559,14 +473,9 @@ mod tests { use std::sync::atomic::Ordering; use serde::ser::SerializeStruct; - use serde_json::json; - use serde_json::Value; use serde_json::{self}; use super::*; - use crate::physical_plans::physical_limit::Limit; - use crate::physical_plans::physical_sequence::Sequence; - use crate::servers::flight::v1::packets::packet_fragment::SerializedPhysicalPlanRef; static STACK_DEPTH: AtomicUsize = AtomicUsize::new(0); static STACK_DELTA: AtomicUsize = AtomicUsize::new(0); @@ -660,97 +569,4 @@ mod tests { }) .count() } - - #[test] - #[allow(clippy::type_complexity)] - fn legacy_typetag_format_can_be_deserialized() { - let samples: Vec<(PhysicalPlan, &'static str, fn(&PhysicalPlan) -> bool)> = vec![ - (sample_serialized_ref(), "SerializedPhysicalPlanRef", |p| { - SerializedPhysicalPlanRef::from_physical_plan(p).is_some() - }), - (sample_limit(), "Limit", |p| { - Limit::from_physical_plan(p).is_some() - }), - (sample_sequence(), "Sequence", |p| { - Sequence::from_physical_plan(p).is_some() - }), - ]; - - for (plan, name, matcher) in samples { - let new_json = serde_json::to_value(&plan).expect("serialize new format"); - let legacy_json = convert_to_legacy(&new_json); - - let restored: PhysicalPlan = - serde_json::from_value(legacy_json).expect("legacy typetag deserialize"); - assert!( - matcher(&restored), - "legacy typetag should deserialize into {name}" - ); - } - } - - fn sample_serialized_ref() -> PhysicalPlan { - serde_json::from_value(serialized_ref_json()).expect("build SerializedPhysicalPlanRef") - } - - fn sample_limit() -> PhysicalPlan { - serde_json::from_value(limit_json()).expect("build Limit plan") - } - - fn sample_sequence() -> PhysicalPlan { - serde_json::from_value(sequence_json()).expect("build Sequence plan") - } - - fn serialized_ref_json() -> Value { - json!({ "SerializedPhysicalPlanRef": 1 }) - } - - fn limit_json() -> Value { - json!({ - "Limit": { - "meta": { "plan_id": 7, "name": "Limit" }, - "input": serialized_ref_json(), - "limit": 5, - "offset": 2, - "stat_info": null - } - }) - } - - fn sequence_json() -> Value { - json!({ - "Sequence": { - "plan_id": 99, - "stat_info": null, - "left": limit_json(), - "right": serialized_ref_json(), - "meta": { "plan_id": 8, "name": "Sequence" } - } - }) - } - - fn convert_to_legacy(value: &Value) -> Value { - match value { - Value::Object(map) => { - if map.len() == 1 { - if let Some((variant, Value::Object(inner_obj))) = map.iter().next() { - let mut legacy = serde_json::Map::new(); - legacy.insert("type".to_string(), Value::String(variant.clone())); - for (k, v) in inner_obj { - legacy.insert(k.clone(), convert_to_legacy(v)); - } - return Value::Object(legacy); - } - } - - let mut new_map = serde_json::Map::new(); - for (k, v) in map { - new_map.insert(k.clone(), convert_to_legacy(v)); - } - Value::Object(new_map) - } - Value::Array(arr) => Value::Array(arr.iter().map(convert_to_legacy).collect()), - _ => value.clone(), - } - } } From d45ae4e38184e11a7c99e6d0285ea04228d88efc Mon Sep 17 00:00:00 2001 From: kould Date: Mon, 22 Dec 2025 05:42:23 +0800 Subject: [PATCH 08/12] chore: rename PhysicalPlanImpl -> PhysicalPlanSerde --- src/query/service/build.rs | 4 ++-- .../service/src/physical_plans/physical_plan.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/query/service/build.rs b/src/query/service/build.rs index 1e934f5ad31f2..84269e1721eee 100644 --- a/src/query/service/build.rs +++ b/src/query/service/build.rs @@ -186,7 +186,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str(meta); out.push('\n'); } - out.push_str(" PhysicalPlanImpl::"); + out.push_str(" PhysicalPlanSerde::"); out.push_str(variant); out.push_str("($plan) => $body,\n"); } @@ -203,7 +203,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str(meta); out.push('\n'); } - out.push_str(" PhysicalPlanImpl::"); + out.push_str(" PhysicalPlanSerde::"); out.push_str(variant); out.push_str("($plan) => $body,\n"); } diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 95b87b7d5e6d4..fcff15701d96d 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -272,13 +272,13 @@ macro_rules! define_physical_plan_impl { ( $( $(#[$meta:meta])? $variant:ident => $path:path ),+ $(,)? ) => { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth - pub(crate) enum PhysicalPlanImpl { + pub(crate) enum PhysicalPlanSerde { $( $(#[$meta])? $variant($path), )+ } - $( $(#[$meta])? impl From<$path> for PhysicalPlanImpl { + $( $(#[$meta])? impl From<$path> for PhysicalPlanSerde { fn from(v: $path) -> Self { - PhysicalPlanImpl::$variant(v) + PhysicalPlanSerde::$variant(v) } })+ }; @@ -289,7 +289,7 @@ include!(concat!(env!("OUT_DIR"), "/physical_plan_impls.rs")); include!(concat!(env!("OUT_DIR"), "/physical_plan_dispatch.rs")); pub struct PhysicalPlan { - inner: Box, + inner: Box, } dyn_clone::clone_trait_object!(IPhysicalPlan); @@ -322,7 +322,7 @@ impl<'de> serde::Deserialize<'de> for PhysicalPlan { fn deserialize>(deserializer: D) -> std::result::Result { // Deserialize to JSON first to avoid backtracking failures in streaming deserializers. let value = JsonValue::deserialize(deserializer)?; - let inner: PhysicalPlanImpl = serde_json::from_value(value).map_err(DeError::custom)?; + let inner: PhysicalPlanSerde = serde_json::from_value(value).map_err(DeError::custom)?; Ok(PhysicalPlan { inner: Box::new(inner), @@ -333,7 +333,7 @@ impl<'de> serde::Deserialize<'de> for PhysicalPlan { impl PhysicalPlan { #[allow(private_bounds)] pub fn new(inner: T) -> PhysicalPlan - where PhysicalPlanImpl: From { + where PhysicalPlanSerde: From { PhysicalPlan { inner: Box::new(inner.into()), } From 4d0a3ef01b8f3753648f93d1887515003f2f6892 Mon Sep 17 00:00:00 2001 From: kould Date: Mon, 22 Dec 2025 06:17:24 +0800 Subject: [PATCH 09/12] chore: codefmt --- src/query/service/src/physical_plans/physical_plan.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index fcff15701d96d..718f41191b018 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -29,9 +29,9 @@ use databend_common_pipeline::core::PlanProfile; use databend_common_pipeline::core::PlanScope; use databend_common_sql::Metadata; use dyn_clone::DynClone; -use serde::de::Error as DeError; use serde::Deserializer; use serde::Serializer; +use serde::de::Error as DeError; use serde_json::Value as JsonValue; use crate::physical_plans::ExchangeSink; From 96a57fe28b725ca58b416de90157e4a851b3e2fa Mon Sep 17 00:00:00 2001 From: kould Date: Mon, 22 Dec 2025 10:40:12 +0800 Subject: [PATCH 10/12] chore: impl IPhysicalPlan for PhysicalPlanSerde --- src/query/service/build.rs | 10 +- .../src/physical_plans/physical_plan.rs | 165 +++++++++++++++--- 2 files changed, 146 insertions(+), 29 deletions(-) diff --git a/src/query/service/build.rs b/src/query/service/build.rs index 84269e1721eee..a78065943689e 100644 --- a/src/query/service/build.rs +++ b/src/query/service/build.rs @@ -123,6 +123,10 @@ fn parse_impl_line( .unwrap_or(type_part) .to_string(); + if type_name == "PhysicalPlanSerde" { + return None; + } + let mut module_path = module_path_from_file(src_root, path); let mut meta = None; @@ -152,7 +156,7 @@ fn module_path_from_file(src_root: &Path, path: &Path) -> String { fn write_impls(out_path: &Path, entries: &[(Option, String, String)]) { let mut out = String::new(); - out.push_str("define_physical_plan_impl!(\n"); + out.push_str("define_physical_plan_serde!(\n"); for (meta, variant, path) in entries { if let Some(meta) = meta { @@ -179,7 +183,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str("macro_rules! dispatch_plan_ref {\n"); out.push_str(" ($s:expr, $plan:ident => $body:expr) => {\n"); - out.push_str(" match $s.inner.as_ref() {\n"); + out.push_str(" match $s {\n"); for (meta, variant, _) in entries { if let Some(meta) = meta { out.push_str(" "); @@ -196,7 +200,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str("macro_rules! dispatch_plan_mut {\n"); out.push_str(" ($s:expr, $plan:ident => $body:expr) => {\n"); - out.push_str(" match $s.inner.as_mut() {\n"); + out.push_str(" match $s {\n"); for (meta, variant, _) in entries { if let Some(meta) = meta { out.push_str(" "); diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index 718f41191b018..f55dd4c2409cd 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -16,6 +16,8 @@ use std::any::Any; use std::collections::HashMap; use std::fmt::Debug; use std::fmt::Formatter; +use std::ops::Deref; +use std::ops::DerefMut; use std::sync::Arc; use databend_common_ast::ast::FormatTreeNode; @@ -29,9 +31,10 @@ use databend_common_pipeline::core::PlanProfile; use databend_common_pipeline::core::PlanScope; use databend_common_sql::Metadata; use dyn_clone::DynClone; +use serde::de::Error as DeError; +use serde::ser::Error as SerError; use serde::Deserializer; use serde::Serializer; -use serde::de::Error as DeError; use serde_json::Value as JsonValue; use crate::physical_plans::ExchangeSink; @@ -268,7 +271,7 @@ impl PhysicalPlanCast for T { } } -macro_rules! define_physical_plan_impl { +macro_rules! define_physical_plan_serde { ( $( $(#[$meta:meta])? $variant:ident => $path:path ),+ $(,)? ) => { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth @@ -288,8 +291,98 @@ include!(concat!(env!("OUT_DIR"), "/physical_plan_impls.rs")); include!(concat!(env!("OUT_DIR"), "/physical_plan_dispatch.rs")); +impl IPhysicalPlan for PhysicalPlanSerde { + fn as_any(&self) -> &dyn Any { + dispatch_plan_ref!(self, v => v.as_any()) + } + + fn get_meta(&self) -> &PhysicalPlanMeta { + dispatch_plan_ref!(self, v => v.get_meta()) + } + + fn get_meta_mut(&mut self) -> &mut PhysicalPlanMeta { + dispatch_plan_mut!(self, v => v.get_meta_mut()) + } + + fn get_id(&self) -> u32 { + dispatch_plan_ref!(self, v => v.get_id()) + } + + fn get_name(&self) -> String { + dispatch_plan_ref!(self, v => v.get_name()) + } + + fn adjust_plan_id(&mut self, next_id: &mut u32) { + dispatch_plan_mut!(self, v => v.adjust_plan_id(next_id)) + } + + fn output_schema(&self) -> Result { + dispatch_plan_ref!(self, v => v.output_schema()) + } + + fn children(&self) -> Box + '_> { + dispatch_plan_ref!(self, v => v.children()) + } + + fn children_mut(&mut self) -> Box + '_> { + dispatch_plan_mut!(self, v => v.children_mut()) + } + + fn formatter(&self) -> Result> { + dispatch_plan_ref!(self, v => v.formatter()) + } + + fn try_find_single_data_source(&self) -> Option<&DataSourcePlan> { + dispatch_plan_ref!(self, v => v.try_find_single_data_source()) + } + + fn try_find_mutation_source(&self) -> Option { + dispatch_plan_ref!(self, v => v.try_find_mutation_source()) + } + + fn get_all_data_source(&self, sources: &mut Vec<(u32, Box)>) { + dispatch_plan_ref!(self, v => v.get_all_data_source(sources)) + } + + fn set_pruning_stats(&mut self, stats: &mut HashMap) { + dispatch_plan_mut!(self, v => v.set_pruning_stats(stats)) + } + + fn is_distributed_plan(&self) -> bool { + dispatch_plan_ref!(self, v => v.is_distributed_plan()) + } + + fn is_warehouse_distributed_plan(&self) -> bool { + dispatch_plan_ref!(self, v => v.is_warehouse_distributed_plan()) + } + + fn display_in_profile(&self) -> bool { + dispatch_plan_ref!(self, v => v.display_in_profile()) + } + + fn get_desc(&self) -> Result { + dispatch_plan_ref!(self, v => v.get_desc()) + } + + fn get_labels(&self) -> Result>> { + dispatch_plan_ref!(self, v => v.get_labels()) + } + + fn derive(&self, children: Vec) -> PhysicalPlan { + dispatch_plan_ref!(self, v => v.derive(children)) + } + + fn build_pipeline(&self, builder: &mut PipelineBuilder) -> Result<()> { + dispatch_plan_ref!(self, v => v.build_pipeline(builder)) + } + + fn build_pipeline2(&self, builder: &mut PipelineBuilder) -> Result<()> { + dispatch_plan_ref!(self, v => v.build_pipeline2(builder)) + } +} + pub struct PhysicalPlan { - inner: Box, + inner: Box, } dyn_clone::clone_trait_object!(IPhysicalPlan); @@ -310,10 +403,30 @@ impl Debug for PhysicalPlan { } } +impl Deref for PhysicalPlan { + type Target = dyn IPhysicalPlan; + + fn deref(&self) -> &Self::Target { + self.inner.as_ref() + } +} + +impl DerefMut for PhysicalPlan { + fn deref_mut(&mut self) -> &mut Self::Target { + self.inner.as_mut() + } +} + impl serde::Serialize for PhysicalPlan { #[recursive::recursive] fn serialize(&self, serializer: S) -> std::result::Result { - self.inner.serialize(serializer) + if let Some(v) = self.inner.as_any().downcast_ref::() { + v.serialize(serializer) + } else { + Err(S::Error::custom( + "serialize PhysicalPlan: unexpected plan type", + )) + } } } @@ -340,91 +453,91 @@ impl PhysicalPlan { } pub fn as_any(&self) -> &dyn Any { - dispatch_plan_ref!(self, v => v.as_any()) + self.inner.as_any() } pub fn get_meta(&self) -> &PhysicalPlanMeta { - dispatch_plan_ref!(self, v => v.get_meta()) + self.inner.get_meta() } pub fn get_meta_mut(&mut self) -> &mut PhysicalPlanMeta { - dispatch_plan_mut!(self, v => v.get_meta_mut()) + self.inner.get_meta_mut() } pub fn get_id(&self) -> u32 { - dispatch_plan_ref!(self, v => v.get_id()) + self.inner.get_id() } pub fn get_name(&self) -> String { - dispatch_plan_ref!(self, v => v.get_name()) + self.inner.get_name() } pub fn adjust_plan_id(&mut self, next_id: &mut u32) { - dispatch_plan_mut!(self, v => v.adjust_plan_id(next_id)) + self.inner.adjust_plan_id(next_id) } pub fn output_schema(&self) -> Result { - dispatch_plan_ref!(self, v => v.output_schema()) + self.inner.output_schema() } pub fn children(&self) -> Box + '_> { - dispatch_plan_ref!(self, v => v.children()) + self.inner.children() } pub fn children_mut(&mut self) -> Box + '_> { - dispatch_plan_mut!(self, v => v.children_mut()) + self.inner.children_mut() } pub fn formatter(&self) -> Result> { - dispatch_plan_ref!(self, v => v.formatter()) + self.inner.formatter() } pub fn try_find_single_data_source(&self) -> Option<&DataSourcePlan> { - dispatch_plan_ref!(self, v => v.try_find_single_data_source()) + self.inner.try_find_single_data_source() } pub fn try_find_mutation_source(&self) -> Option { - dispatch_plan_ref!(self, v => v.try_find_mutation_source()) + self.inner.try_find_mutation_source() } pub fn get_all_data_source(&self, sources: &mut Vec<(u32, Box)>) { - dispatch_plan_ref!(self, v => v.get_all_data_source(sources)) + self.inner.get_all_data_source(sources) } pub fn set_pruning_stats(&mut self, stats: &mut HashMap) { - dispatch_plan_mut!(self, v => v.set_pruning_stats(stats)) + self.inner.set_pruning_stats(stats) } pub fn is_distributed_plan(&self) -> bool { - dispatch_plan_ref!(self, v => v.is_distributed_plan()) + self.inner.is_distributed_plan() } pub fn is_warehouse_distributed_plan(&self) -> bool { - dispatch_plan_ref!(self, v => v.is_warehouse_distributed_plan()) + self.inner.is_warehouse_distributed_plan() } pub fn display_in_profile(&self) -> bool { - dispatch_plan_ref!(self, v => v.display_in_profile()) + self.inner.display_in_profile() } pub fn get_desc(&self) -> Result { - dispatch_plan_ref!(self, v => v.get_desc()) + self.inner.get_desc() } pub fn get_labels(&self) -> Result>> { - dispatch_plan_ref!(self, v => v.get_labels()) + self.inner.get_labels() } pub fn derive(&self, children: Vec) -> PhysicalPlan { - dispatch_plan_ref!(self, v => v.derive(children)) + self.inner.derive(children) } pub fn build_pipeline(&self, builder: &mut PipelineBuilder) -> Result<()> { - dispatch_plan_ref!(self, v => v.build_pipeline(builder)) + self.inner.build_pipeline(builder) } pub fn build_pipeline2(&self, builder: &mut PipelineBuilder) -> Result<()> { - dispatch_plan_ref!(self, v => v.build_pipeline2(builder)) + self.inner.build_pipeline2(builder) } #[recursive::recursive] From 83a67fe73dc13a4a008f05baa39cb1b4d3ee5949 Mon Sep 17 00:00:00 2001 From: kould Date: Mon, 22 Dec 2025 11:20:16 +0800 Subject: [PATCH 11/12] chore: codefmt --- .../src/physical_plans/physical_plan.rs | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index f55dd4c2409cd..b979ec094f6f0 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -16,8 +16,6 @@ use std::any::Any; use std::collections::HashMap; use std::fmt::Debug; use std::fmt::Formatter; -use std::ops::Deref; -use std::ops::DerefMut; use std::sync::Arc; use databend_common_ast::ast::FormatTreeNode; @@ -31,10 +29,10 @@ use databend_common_pipeline::core::PlanProfile; use databend_common_pipeline::core::PlanScope; use databend_common_sql::Metadata; use dyn_clone::DynClone; -use serde::de::Error as DeError; -use serde::ser::Error as SerError; use serde::Deserializer; use serde::Serializer; +use serde::de::Error as DeError; +use serde::ser::Error as SerError; use serde_json::Value as JsonValue; use crate::physical_plans::ExchangeSink; @@ -403,20 +401,6 @@ impl Debug for PhysicalPlan { } } -impl Deref for PhysicalPlan { - type Target = dyn IPhysicalPlan; - - fn deref(&self) -> &Self::Target { - self.inner.as_ref() - } -} - -impl DerefMut for PhysicalPlan { - fn deref_mut(&mut self) -> &mut Self::Target { - self.inner.as_mut() - } -} - impl serde::Serialize for PhysicalPlan { #[recursive::recursive] fn serialize(&self, serializer: S) -> std::result::Result { @@ -448,7 +432,7 @@ impl PhysicalPlan { pub fn new(inner: T) -> PhysicalPlan where PhysicalPlanSerde: From { PhysicalPlan { - inner: Box::new(inner.into()), + inner: Box::::new(inner.into()), } } From 64350572cf6f86ceb0cbc5e9bae3a3ab2088b599 Mon Sep 17 00:00:00 2001 From: kould Date: Mon, 22 Dec 2025 16:40:00 +0800 Subject: [PATCH 12/12] chore: PhysicalPlanSerdeSerialize and PhysicalPlanDeserialize are only used in Serialize and Deserialize --- src/query/service/build.rs | 6 +- .../src/physical_plans/physical_plan.rs | 81 ++++++++++++++----- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/query/service/build.rs b/src/query/service/build.rs index a78065943689e..7a2890be45739 100644 --- a/src/query/service/build.rs +++ b/src/query/service/build.rs @@ -123,7 +123,7 @@ fn parse_impl_line( .unwrap_or(type_part) .to_string(); - if type_name == "PhysicalPlanSerde" { + if type_name == "PhysicalPlanDeserialize" { return None; } @@ -190,7 +190,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str(meta); out.push('\n'); } - out.push_str(" PhysicalPlanSerde::"); + out.push_str(" PhysicalPlanDeserialize::"); out.push_str(variant); out.push_str("($plan) => $body,\n"); } @@ -207,7 +207,7 @@ fn write_dispatch(out_path: &Path, entries: &[(Option, String, String)]) out.push_str(meta); out.push('\n'); } - out.push_str(" PhysicalPlanSerde::"); + out.push_str(" PhysicalPlanDeserialize::"); out.push_str(variant); out.push_str("($plan) => $body,\n"); } diff --git a/src/query/service/src/physical_plans/physical_plan.rs b/src/query/service/src/physical_plans/physical_plan.rs index b979ec094f6f0..d5df2445057f0 100644 --- a/src/query/service/src/physical_plans/physical_plan.rs +++ b/src/query/service/src/physical_plans/physical_plan.rs @@ -32,7 +32,6 @@ use dyn_clone::DynClone; use serde::Deserializer; use serde::Serializer; use serde::de::Error as DeError; -use serde::ser::Error as SerError; use serde_json::Value as JsonValue; use crate::physical_plans::ExchangeSink; @@ -71,7 +70,23 @@ pub trait DeriveHandle: Send + Sync + 'static { ) -> std::result::Result>; } -pub(crate) trait IPhysicalPlan: DynClone + Debug + Send + Sync + 'static { +pub(crate) trait PhysicalPlanSerdeSerialization { + fn to_physical_plan_serde_serialize(&self) -> PhysicalPlanSerdeSerialize<'_>; +} + +pub(crate) trait PhysicalPlanSerdeDeserialization { + fn from_physical_plan_deserialize(v: PhysicalPlanDeserialize) -> Self; +} + +pub(crate) trait IPhysicalPlan: + PhysicalPlanSerdeSerialization + + PhysicalPlanSerdeSerialization + + DynClone + + Debug + + Send + + Sync + + 'static +{ fn as_any(&self) -> &dyn Any; fn get_meta(&self) -> &PhysicalPlanMeta; @@ -271,15 +286,32 @@ impl PhysicalPlanCast for T { macro_rules! define_physical_plan_serde { ( $( $(#[$meta:meta])? $variant:ident => $path:path ),+ $(,)? ) => { - #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] - /// static dispatch replacement for typetag-based dynamic dispatch, performance improvement via reduced stack depth - pub(crate) enum PhysicalPlanSerde { + #[derive(Clone, Debug, serde::Deserialize)] + /// owned enum for deserialization; serialization uses PhysicalPlanSerdeRef to avoid cloning + pub(crate) enum PhysicalPlanDeserialize { $( $(#[$meta])? $variant($path), )+ } - $( $(#[$meta])? impl From<$path> for PhysicalPlanSerde { + #[derive(Debug, serde::Serialize)] + pub(crate) enum PhysicalPlanSerdeSerialize<'a> { + $( $(#[$meta])? $variant(&'a $path), )+ + } + + $( $(#[$meta])? impl From<$path> for PhysicalPlanDeserialize { fn from(v: $path) -> Self { - PhysicalPlanSerde::$variant(v) + PhysicalPlanDeserialize::$variant(v) + } + })+ + + $( $(#[$meta])? impl<'a> From<&'a $path> for PhysicalPlanSerdeSerialize<'a> { + fn from(v: &'a $path) -> Self { + PhysicalPlanSerdeSerialize::$variant(v) + } + })+ + + $( $(#[$meta])? impl PhysicalPlanSerdeSerialization for $path { + fn to_physical_plan_serde_serialize(&self) -> PhysicalPlanSerdeSerialize<'_> { + PhysicalPlanSerdeSerialize::from(self) } })+ }; @@ -289,7 +321,19 @@ include!(concat!(env!("OUT_DIR"), "/physical_plan_impls.rs")); include!(concat!(env!("OUT_DIR"), "/physical_plan_dispatch.rs")); -impl IPhysicalPlan for PhysicalPlanSerde { +impl PhysicalPlanSerdeSerialization for PhysicalPlanDeserialize { + fn to_physical_plan_serde_serialize(&self) -> PhysicalPlanSerdeSerialize<'_> { + dispatch_plan_ref!(self, v => PhysicalPlanSerdeSerialize::from(v)) + } +} + +impl PhysicalPlanSerdeDeserialization for PhysicalPlan { + fn from_physical_plan_deserialize(v: PhysicalPlanDeserialize) -> Self { + PhysicalPlan { inner: Box::new(v) } + } +} + +impl IPhysicalPlan for PhysicalPlanDeserialize { fn as_any(&self) -> &dyn Any { dispatch_plan_ref!(self, v => v.as_any()) } @@ -404,13 +448,9 @@ impl Debug for PhysicalPlan { impl serde::Serialize for PhysicalPlan { #[recursive::recursive] fn serialize(&self, serializer: S) -> std::result::Result { - if let Some(v) = self.inner.as_any().downcast_ref::() { - v.serialize(serializer) - } else { - Err(S::Error::custom( - "serialize PhysicalPlan: unexpected plan type", - )) - } + self.inner + .to_physical_plan_serde_serialize() + .serialize(serializer) } } @@ -419,20 +459,19 @@ impl<'de> serde::Deserialize<'de> for PhysicalPlan { fn deserialize>(deserializer: D) -> std::result::Result { // Deserialize to JSON first to avoid backtracking failures in streaming deserializers. let value = JsonValue::deserialize(deserializer)?; - let inner: PhysicalPlanSerde = serde_json::from_value(value).map_err(DeError::custom)?; + let inner: PhysicalPlanDeserialize = + serde_json::from_value(value).map_err(DeError::custom)?; - Ok(PhysicalPlan { - inner: Box::new(inner), - }) + Ok(PhysicalPlan::from_physical_plan_deserialize(inner)) } } impl PhysicalPlan { #[allow(private_bounds)] pub fn new(inner: T) -> PhysicalPlan - where PhysicalPlanSerde: From { + where PhysicalPlanDeserialize: From { PhysicalPlan { - inner: Box::::new(inner.into()), + inner: Box::::new(inner.into()), } }