@@ -34,7 +34,11 @@ namespace arrow {
3434
3535using internal::checked_cast;
3636
37+ using compute::and_;
38+ using compute::field_ref;
3739using compute::FilterOptions;
40+ using compute::is_null;
41+ using compute::not_;
3842
3943namespace acero {
4044namespace {
@@ -52,14 +56,34 @@ class FilterNode : public MapNode {
5256 auto schema = inputs[0 ]->output_schema ();
5357
5458 const auto & filter_options = checked_cast<const FilterNodeOptions&>(options);
59+ Expression filter_expression;
60+ if (!filter_options.filter_not_null .empty ()) {
61+ std::vector<Expression> operands = {filter_options.filter_expression };
62+ for (const auto & c : filter_options.filter_not_null ) {
63+ auto field_index = schema->GetFieldIndex (c);
64+ if (field_index == -1 ) {
65+ return Status::KeyError (" Column not found: " , c);
66+ }
67+ auto & field = schema->field (field_index);
68+ if (field->nullable ()) {
69+ ARROW_ASSIGN_OR_RAISE (
70+ schema, schema->SetField (field_index, field->WithNullable (false )));
71+ }
72+ operands.push_back (not_ (is_null (field_ref (c))));
73+ }
74+ filter_expression = and_ (operands);
75+ } else {
76+ filter_expression = filter_options.filter_expression ;
77+ }
5578
56- auto filter_expression = filter_options.filter_expression ;
5779 if (!filter_expression.IsBound ()) {
5880 ARROW_ASSIGN_OR_RAISE (
5981 filter_expression,
6082 filter_expression.Bind (*schema, plan->query_context ()->exec_context ()));
6183 }
6284
85+ std::vector<std::string> filter_not_null;
86+
6387 if (filter_expression.type ()->id () != Type::BOOL) {
6488 return Status::TypeError (" Filter expression must evaluate to bool, but " ,
6589 filter_expression.ToString (), " evaluates to " ,
0 commit comments