From 1edcd207d4dcd42910cd1fc85639671ef66fae0f Mon Sep 17 00:00:00 2001 From: Fred Thomas Date: Tue, 16 Jun 2026 15:25:34 +0200 Subject: [PATCH] add downcast_delegate --- datafusion/datasource/src/source.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/datafusion/datasource/src/source.rs b/datafusion/datasource/src/source.rs index af4bc09504937..766aea0e5159f 100644 --- a/datafusion/datasource/src/source.rs +++ b/datafusion/datasource/src/source.rs @@ -123,6 +123,18 @@ use datafusion_physical_plan::filter_pushdown::{ /// └─────────────────────┘ /// ``` pub trait DataSource: Any + Send + Sync + Debug { + /// Optionally delegates downcast identity to an inner [`DataSource`]. + /// + /// Wrapper types (e.g. a partitioning adapter that wraps a [`FileScanConfig`]) + /// can implement this to make `is` and `downcast_ref` transparently see + /// through to the inner source, exactly as [`ExecutionPlan::downcast_delegate`] + /// does for execution plans. + /// + /// Implementations should return the inner source, not `self`. + fn downcast_delegate(&self) -> Option<&dyn DataSource> { + None + } + /// Open the specified output partition and return its stream of /// [`RecordBatch`]es. /// @@ -292,11 +304,17 @@ impl OpenArgs { impl dyn DataSource { pub fn is(&self) -> bool { - (self as &dyn Any).is::() + match self.downcast_delegate() { + Some(delegate) => delegate.is::(), + None => (self as &dyn Any).is::(), + } } pub fn downcast_ref(&self) -> Option<&T> { - (self as &dyn Any).downcast_ref() + match self.downcast_delegate() { + Some(delegate) => delegate.downcast_ref::(), + None => (self as &dyn Any).downcast_ref(), + } } }