in velox/type/Filter.cpp [1053:1127]
std::unique_ptr<Filter> BytesValues::mergeWith(const Filter* other) const {
switch (other->kind()) {
case FilterKind::kAlwaysTrue:
case FilterKind::kAlwaysFalse:
case FilterKind::kIsNull:
case FilterKind::kMultiRange:
return other->mergeWith(this);
case FilterKind::kIsNotNull:
return this->clone(false);
case FilterKind::kBytesValues: {
bool bothNullAllowed = nullAllowed_ && other->testNull();
auto otherBytesValues = static_cast<const BytesValues*>(other);
if (this->upper_.compare(otherBytesValues->lower_) < 0 ||
otherBytesValues->upper_.compare(this->lower_) < 0) {
return nullOrFalse(bothNullAllowed);
}
const BytesValues* smallerFilter = this;
const BytesValues* largerFilter = otherBytesValues;
if (this->values().size() > otherBytesValues->values().size()) {
smallerFilter = otherBytesValues;
largerFilter = this;
}
std::vector<std::string> newValues;
newValues.reserve(smallerFilter->values().size());
for (const auto& value : smallerFilter->values()) {
if (largerFilter->values_.contains(value)) {
newValues.emplace_back(value);
}
}
if (newValues.empty()) {
return nullOrFalse(bothNullAllowed);
}
return std::make_unique<BytesValues>(
std::move(newValues), bothNullAllowed);
}
case FilterKind::kBytesRange: {
auto otherBytesRange = static_cast<const BytesRange*>(other);
bool bothNullAllowed = nullAllowed_ && other->testNull();
if (!testBytesRange(
otherBytesRange->isLowerUnbounded()
? std::nullopt
: std::optional(otherBytesRange->lower()),
otherBytesRange->isUpperUnbounded()
? std::nullopt
: std::optional(otherBytesRange->upper()),
bothNullAllowed)) {
return nullOrFalse(bothNullAllowed);
}
std::vector<std::string> newValues;
newValues.reserve(this->values().size());
for (const auto& value : this->values()) {
if (otherBytesRange->testBytes(value.data(), value.length())) {
newValues.emplace_back(value);
}
}
if (newValues.empty()) {
return nullOrFalse(bothNullAllowed);
}
return std::make_unique<BytesValues>(
std::move(newValues), bothNullAllowed);
}
default:
VELOX_UNREACHABLE();
}
}