TruthValue evaluatePredicateRange()

in c++/src/sargs/PredicateLeaf.cc [305:389]


  TruthValue evaluatePredicateRange(const PredicateLeaf::Operator op, const std::vector<T>& values,
                                    const T& minValue, const T& maxValue, bool hasNull) {
    Location loc;
    switch (op) {
      case PredicateLeaf::Operator::NULL_SAFE_EQUALS:
        loc = compareToRange(values.at(0), minValue, maxValue);
        if (loc == Location::BEFORE || loc == Location::AFTER) {
          return TruthValue::NO;
        } else {
          return TruthValue::YES_NO;
        }
      case PredicateLeaf::Operator::EQUALS:
        loc = compareToRange(values.at(0), minValue, maxValue);
        if (minValue == maxValue && loc == Location::MIN) {
          return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
        } else if (loc == Location::BEFORE || loc == Location::AFTER) {
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        } else {
          return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
        }
      case PredicateLeaf::Operator::LESS_THAN:
        loc = compareToRange(values.at(0), minValue, maxValue);
        if (loc == Location::AFTER) {
          return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
        } else if (loc == Location::BEFORE || loc == Location::MIN) {
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        } else {
          return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
        }
      case PredicateLeaf::Operator::LESS_THAN_EQUALS:
        loc = compareToRange(values.at(0), minValue, maxValue);
        if (loc == Location::AFTER || loc == Location::MAX ||
            (loc == Location::MIN && minValue == maxValue)) {
          return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
        } else if (loc == Location::BEFORE) {
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        } else {
          return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
        }
      case PredicateLeaf::Operator::IN:
        if (minValue == maxValue) {
          // for a single value, look through to see if that value is in the set
          for (auto& value : values) {
            loc = compareToRange(value, minValue, maxValue);
            if (loc == Location::MIN) {
              return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
            }
          }
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        } else {
          // are all of the values outside of the range?
          for (auto& value : values) {
            loc = compareToRange(value, minValue, maxValue);
            if (loc == Location::MIN || loc == Location::MIDDLE || loc == Location::MAX) {
              return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
            }
          }
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        }
      case PredicateLeaf::Operator::BETWEEN:
        if (values.empty()) {
          return TruthValue::YES_NO;
        }
        loc = compareToRange(values.at(0), minValue, maxValue);
        if (loc == Location::BEFORE || loc == Location::MIN) {
          Location loc2 = compareToRange(values.at(1), minValue, maxValue);
          if (loc2 == Location::AFTER || loc2 == Location::MAX) {
            return hasNull ? TruthValue::YES_NULL : TruthValue::YES;
          } else if (loc2 == Location::BEFORE) {
            return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
          } else {
            return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
          }
        } else if (loc == Location::AFTER) {
          return hasNull ? TruthValue::NO_NULL : TruthValue::NO;
        } else {
          return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
        }
      case PredicateLeaf::Operator::IS_NULL:
        // min = null condition above handles the all-nulls YES case
        return hasNull ? TruthValue::YES_NO : TruthValue::NO;
      default:
        return hasNull ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
    }
  }