pub trait UserDefinedLogicalNode:
Debug
+ Send
+ Sync {
Show 14 methods
// 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 with_exprs_and_inputs(
&self,
exprs: Vec<Expr>,
inputs: Vec<LogicalPlan>,
) -> Result<Arc<dyn UserDefinedLogicalNode>>;
fn dyn_hash(&self, state: &mut dyn Hasher);
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool;
fn dyn_ord(&self, other: &dyn UserDefinedLogicalNode) -> Option<Ordering>;
// Provided methods
fn prevent_predicate_push_down_columns(&self) -> HashSet<String> { ... }
fn from_template(
&self,
exprs: &[Expr],
inputs: &[LogicalPlan],
) -> Arc<dyn UserDefinedLogicalNode> { ... }
fn necessary_children_exprs(
&self,
_output_columns: &[usize],
) -> Option<Vec<Vec<usize>>> { ... }
fn supports_limit_pushdown(&self) -> bool { ... }
}
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. See LogicalPlan::expressions
for more details.
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 with_exprs_and_inputs(
&self,
exprs: Vec<Expr>,
inputs: Vec<LogicalPlan>,
) -> Result<Arc<dyn UserDefinedLogicalNode>>
fn with_exprs_and_inputs( &self, exprs: Vec<Expr>, inputs: Vec<LogicalPlan>, ) -> Result<Arc<dyn UserDefinedLogicalNode>>
Create a new UserDefinedLogicalNode
with the specified children
and expressions. This function is used during optimization
when the plan is being rewritten and a new instance of the
UserDefinedLogicalNode
must be created.
Note that exprs and inputs are in the same order as the result of self.inputs and self.exprs.
So, `self.with_exprs_and_inputs(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.
fn dyn_ord(&self, other: &dyn UserDefinedLogicalNode) -> Option<Ordering>
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.
fn from_template( &self, exprs: &[Expr], inputs: &[LogicalPlan], ) -> Arc<dyn UserDefinedLogicalNode>
Sourcefn necessary_children_exprs(
&self,
_output_columns: &[usize],
) -> Option<Vec<Vec<usize>>>
fn necessary_children_exprs( &self, _output_columns: &[usize], ) -> Option<Vec<Vec<usize>>>
Returns the necessary input columns for this node required to compute the columns in the output schema
This is used for projection push-down when DataFusion has determined that only a subset of the output columns of this node are needed by its parents. This API is used to tell DataFusion which, if any, of the input columns are no longer needed.
Return None
, the default, if this information can not be determined.
Returns Some(_)
with the column indices for each child of this node that are
needed to compute output_columns
Sourcefn supports_limit_pushdown(&self) -> bool
fn supports_limit_pushdown(&self) -> bool
Returns true
if a limit can be safely pushed down through this
UserDefinedLogicalNode
node.
If this method returns true
, and the query plan contains a limit at
the output of this node, DataFusion will push the limit to the input
of this node.
Trait Implementations§
Source§impl Hash for dyn UserDefinedLogicalNode
impl Hash for dyn UserDefinedLogicalNode
Source§impl PartialEq for dyn UserDefinedLogicalNode
impl PartialEq for dyn UserDefinedLogicalNode
Source§impl PartialOrd for dyn UserDefinedLogicalNode
impl PartialOrd 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