in c++/src/sargs/PredicateLeaf.cc [393:446]
static TruthValue evaluateBoolPredicate(const PredicateLeaf::Operator op,
const std::vector<Literal>& literals,
const proto::ColumnStatistics& stats) {
bool hasNull = stats.has_null();
if (!stats.has_bucket_statistics() || stats.bucket_statistics().count_size() == 0) {
// does not have bool stats
return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
}
auto trueCount = stats.bucket_statistics().count(0);
auto falseCount = stats.number_of_values() - trueCount;
switch (op) {
case PredicateLeaf::Operator::IS_NULL:
return hasNull ? TruthValue::YES_NO : TruthValue::NO;
case PredicateLeaf::Operator::NULL_SAFE_EQUALS: {
if (literals.at(0).getBool()) {
if (trueCount == 0) {
return TruthValue::NO;
} else if (falseCount == 0) {
return TruthValue::YES;
}
} else {
if (falseCount == 0) {
return TruthValue::NO;
} else if (trueCount == 0) {
return TruthValue::YES;
}
}
return TruthValue::YES_NO;
}
case PredicateLeaf::Operator::EQUALS: {
if (literals.at(0).getBool()) {
if (trueCount == 0) {
return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
} else if (falseCount == 0) {
return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
}
} else {
if (falseCount == 0) {
return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
} else if (trueCount == 0) {
return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
}
}
return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
}
case PredicateLeaf::Operator::LESS_THAN:
case PredicateLeaf::Operator::LESS_THAN_EQUALS:
case PredicateLeaf::Operator::IN:
case PredicateLeaf::Operator::BETWEEN:
default:
return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
}
}