HappenLee commented on code in PR #66455:
URL: https://github.com/apache/doris/pull/66455#discussion_r3810960910
##########
be/src/exprs/expr_zonemap_filter.cpp:
##########
@@ -461,43 +445,57 @@ ZoneMapFilterResult eval_in_zonemap(const
ZoneMapEvalContext& ctx, const VExprSP
return unsupported_zonemap_filter(ctx);
}
+ // A non-empty set without ordered bounds contains only NaN values. Once
the reader proves the
+ // data has no hidden NaNs, such an IN cannot match while NOT IN remains
conservative.
+ if (values.min_value.is_null() || values.max_value.is_null()) {
+ DORIS_CHECK(values.contains_nan);
+ DORIS_CHECK(values.min_value.is_null());
+ DORIS_CHECK(values.max_value.is_null());
+ return is_not_in ? ZoneMapFilterResult::kMayMatch :
ZoneMapFilterResult::kNoMatch;
+ }
+
+ // The caller has precomputed the IN set's owning non-NaN min/max. They
must match the expression
+ // slot type before being compared with storage zone-map statistics.
+ DORIS_CHECK(
+ field_types_compatible(values.min_value.get_type(),
data_type->get_primitive_type()));
+ DORIS_CHECK(
+ field_types_compatible(values.max_value.get_type(),
data_type->get_primitive_type()));
+
if (is_not_in) {
// NOT IN can only prune when the whole zone contains exactly one
non-null value and that
// value is excluded by the set. Wider ranges may contain values that
are not filtered.
if (zone_map.min_value == zone_map.max_value) {
- const bool only_value_is_filtered = std::ranges::any_of(
- values, [&](const Field& value) { return value ==
zone_map.min_value; });
+ const bool only_value_is_filtered = set.find(zone_map.min_value);
return only_value_is_filtered ? ZoneMapFilterResult::kNoMatch
: ZoneMapFilterResult::kMayMatch;
}
return ZoneMapFilterResult::kMayMatch;
}
- // First use the materialized IN-set min/max to rule out disjoint zone-map
ranges.
- if (zone_map.max_value < min_value || zone_map.min_value > max_value) {
+ // First use the IN-set min/max to rule out disjoint zone-map ranges.
+ if (zone_map.max_value < values.min_value || zone_map.min_value >
values.max_value) {
return ZoneMapFilterResult::kNoMatch;
}
- // For large IN sets, avoid checking every point on the scan hot path. The
range overlap above
- // is only a coarse may-match signal.
- if (values.size() > kInZoneMapPointCheckThreshold) {
+ // For large IN sets and dense-domain containers, avoid exact checks on
the scan hot path. A
+ // BitSet iterator may inspect its entire value domain even when the set
itself is small.
+ if (!set.supports_fast_range_lookup() ||
Review Comment:
BitSet should can dispose zonemap in fast path
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]