TruthValue PredicateLeaf::evaluatePredicateMinMax()

in c++/src/sargs/PredicateLeaf.cc [508:605]


  TruthValue PredicateLeaf::evaluatePredicateMinMax(const proto::ColumnStatistics& colStats) const {
    TruthValue result = TruthValue::YES_NO_NULL;
    switch (type_) {
      case PredicateDataType::LONG: {
        if (colStats.has_int_statistics() && colStats.int_statistics().has_minimum() &&
            colStats.int_statistics().has_maximum()) {
          const auto& stats = colStats.int_statistics();
          result = evaluatePredicateRange(operator_, literal2Long(literals_), stats.minimum(),
                                          stats.maximum(), colStats.has_null());
        }
        break;
      }
      case PredicateDataType::FLOAT: {
        if (colStats.has_double_statistics() && colStats.double_statistics().has_minimum() &&
            colStats.double_statistics().has_maximum()) {
          const auto& stats = colStats.double_statistics();
          if (!std::isfinite(stats.sum())) {
            result = colStats.has_null() ? TruthValue::YES_NO_NULL : TruthValue::YES_NO;
          } else {
            result = evaluatePredicateRange(operator_, literal2Double(literals_), stats.minimum(),
                                            stats.maximum(), colStats.has_null());
          }
        }
        break;
      }
      case PredicateDataType::STRING: {
        /// TODO: check lowerBound and upperBound as well
        if (colStats.has_string_statistics() && colStats.string_statistics().has_minimum() &&
            colStats.string_statistics().has_maximum()) {
          const auto& stats = colStats.string_statistics();
          result = evaluatePredicateRange(operator_, literal2String(literals_), stats.minimum(),
                                          stats.maximum(), colStats.has_null());
        }
        break;
      }
      case PredicateDataType::DATE: {
        if (colStats.has_date_statistics() && colStats.date_statistics().has_minimum() &&
            colStats.date_statistics().has_maximum()) {
          const auto& stats = colStats.date_statistics();
          result = evaluatePredicateRange(operator_, literal2Date(literals_), stats.minimum(),
                                          stats.maximum(), colStats.has_null());
        }
        break;
      }
      case PredicateDataType::TIMESTAMP: {
        if (colStats.has_timestamp_statistics() &&
            colStats.timestamp_statistics().has_minimum_utc() &&
            colStats.timestamp_statistics().has_maximum_utc()) {
          const auto& stats = colStats.timestamp_statistics();
          constexpr int32_t DEFAULT_MIN_NANOS = 0;
          constexpr int32_t DEFAULT_MAX_NANOS = 999999;
          int32_t minNano =
              stats.has_minimum_nanos() ? stats.minimum_nanos() - 1 : DEFAULT_MIN_NANOS;
          int32_t maxNano =
              stats.has_maximum_nanos() ? stats.maximum_nanos() - 1 : DEFAULT_MAX_NANOS;
          Literal::Timestamp minTimestamp(
              stats.minimum_utc() / 1000,
              static_cast<int32_t>((stats.minimum_utc() % 1000) * 1000000) + minNano);
          Literal::Timestamp maxTimestamp(
              stats.maximum_utc() / 1000,
              static_cast<int32_t>((stats.maximum_utc() % 1000) * 1000000) + maxNano);
          result = evaluatePredicateRange(operator_, literal2Timestamp(literals_), minTimestamp,
                                          maxTimestamp, colStats.has_null());
        }
        break;
      }
      case PredicateDataType::DECIMAL: {
        if (colStats.has_decimal_statistics() && colStats.decimal_statistics().has_minimum() &&
            colStats.decimal_statistics().has_maximum()) {
          const auto& stats = colStats.decimal_statistics();
          result = evaluatePredicateRange(operator_, literal2Decimal(literals_),
                                          Decimal(stats.minimum()), Decimal(stats.maximum()),
                                          colStats.has_null());
        }
        break;
      }
      case PredicateDataType::BOOLEAN: {
        if (colStats.has_bucket_statistics()) {
          result = evaluateBoolPredicate(operator_, literals_, colStats);
        }
        break;
      }
      default:
        break;
    }

    // make sure null literal is respected for IN operator
    if (operator_ == Operator::IN && colStats.has_null()) {
      for (const auto& literal : literals_) {
        if (literal.isNull()) {
          result = TruthValue::YES_NO_NULL;
          break;
        }
      }
    }

    return result;
  }