datafusion icon indicating copy to clipboard operation
datafusion copied to clipboard

idea: add another `static_name()` method to `ExecutionPlan` trait

Open waynexia opened this issue 9 months ago • 4 comments

Is your feature request related to a problem or challenge?

Come across on reviewing #9793

Describe the solution you'd like

The newly added ExecutionPlan::name() method receives a &self as param. In some scenarios it might not be very easy to construct an instance of ExecutionPlan as it usually requires some verbose state. If one wants to just use the plan's name as a static string (like the replacement of static NAME: &'static str = "xxx";), they have to construct an instance first.

The ExecutionPlan::name() method can be a static method, i.e., without receiving a &self. However, removing the parameter seems not acceptable, or this method cannot be called via an instant but only from a type like MyPlan::name(). Thus this ticket proposes to add a new static one along with the member one. We can use one to implement another like this

pub trait ExecutionPlan: Debug + DisplayAs + Send + Sync {
    /// Short name for the ExecutionPlan, such as 'ParquetExec'.
    fn name(&self) -> &'static str
    where
        Self: Sized,
    {
        Self::static_name()
    }

    fn static_name() -> &'static str
    where
        Self: Sized,
    {
        let full_name = std::any::type_name::<Self>();
        let maybe_start_idx = full_name.rfind(':');
        match maybe_start_idx {
            Some(start_idx) => &full_name[start_idx + 1..],
            None => "UNKNOWN",
        }
    }
}

Describe alternatives you've considered

No response

Additional context

No response

waynexia avatar Apr 26 '24 06:04 waynexia

cc @matthewmturner and @comphead from #9793

waynexia avatar Apr 26 '24 06:04 waynexia

I have a similar pattern on implementing user defined logical plan:

https://github.com/GreptimeTeam/greptimedb/blob/4eadd9f8a88870fff72922d9c7515cf29bc790b3/src/promql/src/extension_plan/empty_metric.rs#L130-L133

where

impl UserDefinedLogicalNodeCore for EmptyMetric {
    fn name(&self) -> &str {
        Self::name()
    }
}

impl EmptyMetricExec {
    pub const fn name() -> &'static str {
        "EmptyMetric"
    }
}

waynexia avatar Apr 26 '24 06:04 waynexia

Thanks @waynexia could you please give an example how the static be called for different plan nodes to obtain different names?

comphead avatar Apr 26 '24 15:04 comphead

Thanks @waynexia could you please give an example how the static be called for different plan nodes to obtain different names?

This (old) test case can be an example: https://github.com/apache/datafusion/pull/10266/files#diff-9f1cf112a3f7c21baab307b9001331d287479e54e60b594712395052e0ad0690R935-R936

After #10266 the call to ExecutionPlan::name() is proxied to static_name() in default implementation.

waynexia avatar Apr 27 '24 14:04 waynexia