pub trait UserDefinedLogicalNode: Debug + Send + Sync {
// Required methods
fn as_any(&self) -> &dyn Any;
fn name(&self) -> &str;
fn inputs(&self) -> Vec<&LogicalPlan>;
fn schema(&self) -> &DFSchemaRef;
fn expressions(&self) -> Vec<Expr>;
fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result;
fn from_template(
&self,
exprs: &[Expr],
inputs: &[LogicalPlan]
) -> Arc<dyn UserDefinedLogicalNode>;
fn dyn_hash(&self, state: &mut dyn Hasher);
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool;
// Provided method
fn prevent_predicate_push_down_columns(&self) -> HashSet<String> { ... }
}
Expand description
This defines the interface for LogicalPlan
nodes that can be
used to extend DataFusion with custom relational operators.
The UserDefinedLogicalNodeCore
trait is the recommended way to implement
this trait and avoids having implementing some required boiler plate code.
Required Methods§
sourcefn as_any(&self) -> &dyn Any
fn as_any(&self) -> &dyn Any
Return a reference to self as Any, to support dynamic downcasting
Typically this will look like:
// canonical boiler plate
fn as_any(&self) -> &dyn Any {
self
}
sourcefn inputs(&self) -> Vec<&LogicalPlan>
fn inputs(&self) -> Vec<&LogicalPlan>
Return the logical plan’s inputs.
sourcefn schema(&self) -> &DFSchemaRef
fn schema(&self) -> &DFSchemaRef
Return the output schema of this logical plan node.
sourcefn expressions(&self) -> Vec<Expr>
fn expressions(&self) -> Vec<Expr>
Returns all expressions in the current logical plan node. This should not include expressions of any inputs (aka non-recursively). These expressions are used for optimizer passes and rewrites.
sourcefn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result
fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result
Write a single line, human readable string to f
for use in explain plan.
For example: TopK: k=10
sourcefn from_template(
&self,
exprs: &[Expr],
inputs: &[LogicalPlan]
) -> Arc<dyn UserDefinedLogicalNode>
fn from_template( &self, exprs: &[Expr], inputs: &[LogicalPlan] ) -> Arc<dyn UserDefinedLogicalNode>
Create a new ExtensionPlanNode
with the specified children
and expressions. This function is used during optimization
when the plan is being rewritten and a new instance of the
ExtensionPlanNode
must be created.
Note that exprs and inputs are in the same order as the result of self.inputs and self.exprs.
So, `self.from_template(exprs, ..).expressions() == exprs
sourcefn dyn_hash(&self, state: &mut dyn Hasher)
fn dyn_hash(&self, state: &mut dyn Hasher)
Update the hash state
with this node requirements from
Hash
.
Note: consider using UserDefinedLogicalNodeCore
instead of
UserDefinedLogicalNode
directly.
This method is required to support hashing LogicalPlan
s. To
implement it, typically the type implementing
UserDefinedLogicalNode
typically implements Hash
and
then the following boiler plate is used:
Example:
// User defined node that derives Hash
#[derive(Hash, Debug, PartialEq, Eq)]
struct MyNode {
val: u64
}
// impl UserDefinedLogicalNode {
// ...
// Boiler plate to call the derived Hash impl
fn dyn_hash(&self, state: &mut dyn std::hash::Hasher) {
use std::hash::Hash;
let mut s = state;
self.hash(&mut s);
}
// }
Note: UserDefinedLogicalNode
is not constrained by Hash
directly because it must remain object safe.
sourcefn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool
Compare other
, respecting requirements from std::cmp::Eq.
Note: consider using UserDefinedLogicalNodeCore
instead of
UserDefinedLogicalNode
directly.
When other
has an another type than self
, then the values
are not equal.
This method is required to support Eq on LogicalPlan
s. To
implement it, typically the type implementing
UserDefinedLogicalNode
typically implements Eq
and
then the following boiler plate is used:
Example:
// User defined node that derives Eq
#[derive(Hash, Debug, PartialEq, Eq)]
struct MyNode {
val: u64
}
// impl UserDefinedLogicalNode {
// ...
// Boiler plate to call the derived Eq impl
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool {
match other.as_any().downcast_ref::<Self>() {
Some(o) => self == o,
None => false,
}
}
// }
Note: UserDefinedLogicalNode
is not constrained by Eq
directly because it must remain object safe.
Provided Methods§
sourcefn prevent_predicate_push_down_columns(&self) -> HashSet<String>
fn prevent_predicate_push_down_columns(&self) -> HashSet<String>
A list of output columns (e.g. the names of columns in self.schema()) for which predicates can not be pushed below this node without changing the output.
By default, this returns all columns and thus prevents any predicates from being pushed below this node.
Trait Implementations§
source§impl Hash for dyn UserDefinedLogicalNode
impl Hash for dyn UserDefinedLogicalNode
source§impl PartialEq<dyn UserDefinedLogicalNode> for dyn UserDefinedLogicalNode
impl PartialEq<dyn UserDefinedLogicalNode> for dyn UserDefinedLogicalNode
impl Eq for dyn UserDefinedLogicalNode
Implementors§
impl<T: UserDefinedLogicalNodeCore> UserDefinedLogicalNode for T
Automatically derive UserDefinedLogicalNode to UserDefinedLogicalNode
to avoid boiler plate for implementing as_any
, Hash
and PartialEq