diff --git a/internal/core/src/exec/expression/UnaryExpr.cpp b/internal/core/src/exec/expression/UnaryExpr.cpp index 0a27080ad1..552583410d 100644 --- a/internal/core/src/exec/expression/UnaryExpr.cpp +++ b/internal/core/src/exec/expression/UnaryExpr.cpp @@ -854,7 +854,9 @@ PhyUnaryRangeFilterExpr::ExecRangeVisitorImplJson(EvalCtx& context) { offset = (offsets) ? offsets[i] : i; } if (valid_data != nullptr && !valid_data[offset]) { - res[i] = valid_res[i] = false; + // NULL values are not equal to anything + valid_res[i] = false; + res[i] = true; continue; } if (has_bitmap_input && @@ -986,7 +988,11 @@ PhyUnaryRangeFilterExpr::ExecRangeVisitorImplJsonByStats() { : std::stoi(pointerpair.second); ExprValueType val = GetValueFromProto(expr_->val_); - auto op_type = expr_->op_type_; + // for NotEqual: compute Equal and flip the result + // this avoids handling NULL values differently in multiple places + auto op_type = (expr_->op_type_ == proto::plan::OpType::NotEqual) + ? proto::plan::OpType::Equal + : expr_->op_type_; auto segment = static_cast(segment_); auto field_id = expr_->column_.field_id_; @@ -1259,6 +1265,10 @@ PhyUnaryRangeFilterExpr::ExecRangeVisitorImplJsonByStats() { } } + // for NotEqual: flip the result + if (expr_->op_type_ == proto::plan::OpType::NotEqual) { + cached_index_chunk_res_->flip(); + } cached_index_chunk_id_ = 0; }