Skip to content

Commit 0104822

Browse files
authored
Implement AsRef for Expr (#17819)
* Implement `AsRef` for `Expr` This allows writing a function that accepts `&[Expr]` or `&[&Expr]`, thus allowing less cloning when inspecting expression trees. * Avoid clones in push_down_join Clone lazily, only when needed * Revert "Avoid clones in push_down_join" This reverts commit d886be5. Revert per PR discussion. The change didn't buy much.
1 parent 935fb3e commit 0104822

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

datafusion/expr/src/expr.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,12 @@ impl Default for Expr {
401401
}
402402
}
403403

404+
impl AsRef<Expr> for Expr {
405+
fn as_ref(&self) -> &Expr {
406+
self
407+
}
408+
}
409+
404410
/// Create an [`Expr`] from a [`Column`]
405411
impl From<Column> for Expr {
406412
fn from(value: Column) -> Self {
@@ -4109,4 +4115,58 @@ mod test {
41094115
assert_eq!(size_of::<Vec<Expr>>(), 24);
41104116
assert_eq!(size_of::<Arc<Expr>>(), 8);
41114117
}
4118+
4119+
#[test]
4120+
fn test_accept_exprs() {
4121+
fn accept_exprs<E: AsRef<Expr>>(_: &[E]) {}
4122+
4123+
let expr = || -> Expr { lit(1) };
4124+
4125+
// Call accept_exprs with owned expressions
4126+
let owned_exprs = vec![expr(), expr()];
4127+
accept_exprs(&owned_exprs);
4128+
4129+
// Call accept_exprs with expressions from expr tree
4130+
let udf = Expr::ScalarFunction(ScalarFunction {
4131+
func: Arc::new(ScalarUDF::new_from_impl(TestUDF {})),
4132+
args: vec![expr(), expr()],
4133+
});
4134+
let Expr::ScalarFunction(scalar) = &udf else {
4135+
unreachable!()
4136+
};
4137+
accept_exprs(&scalar.args);
4138+
4139+
// Call accept_exprs with expressions collected from expr tree, without cloning
4140+
let mut collected_refs: Vec<&Expr> = scalar.args.iter().collect();
4141+
collected_refs.extend(&owned_exprs);
4142+
accept_exprs(&collected_refs);
4143+
4144+
// test helpers
4145+
#[derive(Debug, PartialEq, Eq, Hash)]
4146+
struct TestUDF {}
4147+
impl ScalarUDFImpl for TestUDF {
4148+
fn as_any(&self) -> &dyn Any {
4149+
unimplemented!()
4150+
}
4151+
4152+
fn name(&self) -> &str {
4153+
unimplemented!()
4154+
}
4155+
4156+
fn signature(&self) -> &Signature {
4157+
unimplemented!()
4158+
}
4159+
4160+
fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
4161+
unimplemented!()
4162+
}
4163+
4164+
fn invoke_with_args(
4165+
&self,
4166+
_args: ScalarFunctionArgs,
4167+
) -> Result<ColumnarValue> {
4168+
unimplemented!()
4169+
}
4170+
}
4171+
}
41124172
}

0 commit comments

Comments
 (0)