Skip to content

Commit afef163

Browse files
committed
feat: implement manipulate and contains operators
1 parent bb7d94d commit afef163

File tree

4 files changed

+1524
-14
lines changed

4 files changed

+1524
-14
lines changed

datafusion/physical-expr/src/expressions/binary.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,15 @@
1717

1818
mod kernels;
1919

20-
use crate::expressions::binary::kernels::contains::collection_contains_dyn;
20+
use crate::expressions::binary::kernels::contains::{
21+
collection_contains_all_strings_dyn, collection_contains_all_strings_dyn_scalar,
22+
collection_contains_any_string_dyn, collection_contains_any_string_dyn_scalar,
23+
collection_contains_dyn, collection_contains_dyn_scalar,
24+
collection_contains_string_dyn, collection_contains_string_dyn_scalar,
25+
};
26+
use crate::expressions::binary::kernels::manipulate::{
27+
collection_concat_dyn, collection_delete_key_dyn_scalar,
28+
};
2129
use crate::expressions::binary::kernels::select::{
2230
cast_to_string_array, collection_select_dyn_scalar, collection_select_path_dyn_scalar,
2331
};
@@ -255,6 +263,7 @@ impl PhysicalExpr for BinaryExpr {
255263
let schema = batch.schema();
256264
let input_schema = schema.as_ref();
257265

266+
// TODO: remove this
258267
if left_data_type.is_nested() {
259268
if !left_data_type.equals_datatype(&right_data_type) {
260269
return internal_err!("Cannot evaluate binary expression because of type mismatch: left {}, right {} ", left_data_type, right_data_type);
@@ -265,6 +274,7 @@ impl PhysicalExpr for BinaryExpr {
265274
match self.op {
266275
Operator::Plus if self.fail_on_overflow => return apply(&lhs, &rhs, add),
267276
Operator::Plus => return apply(&lhs, &rhs, add_wrapping),
277+
// TODO: exclude nested types
268278
Operator::Minus if self.fail_on_overflow => return apply(&lhs, &rhs, sub),
269279
Operator::Minus => return apply(&lhs, &rhs, sub_wrapping),
270280
Operator::Multiply if self.fail_on_overflow => return apply(&lhs, &rhs, mul),
@@ -599,6 +609,12 @@ impl BinaryExpr {
599609
HashArrow => collection_select_path_dyn_scalar(array, scalar),
600610
HashLongArrow => collection_select_path_dyn_scalar(array, scalar)
601611
.map(|arr| arr.and_then(cast_to_string_array)),
612+
AtArrow => collection_contains_dyn_scalar(&array, scalar),
613+
// TODO: ArrowAt
614+
Question => collection_contains_string_dyn_scalar(&array, scalar),
615+
QuestionPipe => collection_contains_any_string_dyn_scalar(&array, scalar),
616+
QuestionAnd => collection_contains_all_strings_dyn_scalar(&array, scalar),
617+
Minus => collection_delete_key_dyn_scalar(&array, scalar),
602618
// if scalar operation is not supported - fallback to array implementation
603619
_ => None,
604620
};
@@ -633,6 +649,11 @@ impl BinaryExpr {
633649
Or => {
634650
if left_data_type == &DataType::Boolean {
635651
Ok(boolean_op(&left, &right, or_kleene)?)
652+
} else if matches!(
653+
left_data_type,
654+
DataType::List(_) | DataType::Struct(_)
655+
) {
656+
collection_concat_dyn(left, right)
636657
} else {
637658
internal_err!(
638659
"Cannot evaluate binary expression {:?} with types {:?} and {:?}",
@@ -654,8 +675,11 @@ impl BinaryExpr {
654675
StringConcat => concat_elements(left, right),
655676
AtArrow => collection_contains_dyn(left, right),
656677
ArrowAt => collection_contains_dyn(right, left),
678+
Question => collection_contains_string_dyn(left, right),
679+
QuestionPipe => collection_contains_any_string_dyn(left, right),
680+
QuestionAnd => collection_contains_all_strings_dyn(left, right),
657681
Arrow | LongArrow | HashArrow | HashLongArrow | AtAt | HashMinus
658-
| AtQuestion | Question | QuestionAnd | QuestionPipe | IntegerDivide => {
682+
| AtQuestion | IntegerDivide => {
659683
not_impl_err!(
660684
"Binary operator '{:?}' is not supported in the physical expr",
661685
self.op

datafusion/physical-expr/src/expressions/binary/kernels.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use datafusion_common::{Result, ScalarValue};
3333
use std::sync::Arc;
3434

3535
pub mod contains;
36+
pub mod manipulate;
3637
pub mod select;
3738

3839
/// Downcasts $LEFT and $RIGHT to $ARRAY_TYPE and then calls $KERNEL($LEFT, $RIGHT)

0 commit comments

Comments
 (0)