bool InjectJoinFilters::findExactMinMaxValuesForAttributeHelper(
    const physical::PhysicalPtr &physical_plan,
    const expressions::AttributeReferencePtr &attribute,
    std::int64_t *min_cpp_value,
    std::int64_t *max_cpp_value) const {
  bool min_value_is_exact;
  bool max_value_is_exact;

  const TypedValue min_value =
      cost_model_->findMinValueStat(physical_plan, attribute, &min_value_is_exact);
  const TypedValue max_value =
      cost_model_->findMaxValueStat(physical_plan, attribute, &max_value_is_exact);
  if (min_value.isNull() || max_value.isNull() ||
      (!min_value_is_exact) || (!max_value_is_exact)) {
    return false;
  }

  switch (attribute->getValueType().getTypeID()) {
    case TypeID::kInt: {
      *min_cpp_value = min_value.getLiteral<int>();
      *max_cpp_value = max_value.getLiteral<int>();
      return true;
    }
    case TypeID::kLong: {
      *min_cpp_value = min_value.getLiteral<std::int64_t>();
      *max_cpp_value = max_value.getLiteral<std::int64_t>();
      return true;
    }
    default:
      return false;
  }
}
 /**
  * @brief Overwrite the value at the specified position with the supplied
  *        TypedValue.
  * @warning You must call prepareForPositionalWrites() BEFORE calling this
  *          method.
  * @warning Do NOT use positional writes in combination with appends.
  * @warning It is intended that this and other positional write methods
  *          should be called exactly once for each position (if this is
  *          violated, NULLs may not be tracked properly).
  *
  * @param position The position of the value in this NativeColumnVector to
  *        overwrite.
  * @param value A TypedValue to write into this NativeColumnVector.
  **/
 inline void positionalWriteTypedValue(const std::size_t position,
                                       const TypedValue &value) {
   DCHECK_LT(position, actual_length_);
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   if (null_bitmap_ && value.isNull()) {
     null_bitmap_->setBit(position, true);
   } else {
     DCHECK(!value.isNull());
     value.copyInto(static_cast<char*>(values_) + (position * type_length_));
   }
 }
 /**
  * @brief Append a TypedValue to this NativeColumnVector.
  *
  * @param value A value to append to this NativeColumnVector.
  **/
 inline void appendTypedValue(const TypedValue &value) {
   DCHECK_LT(actual_length_, reserved_length_);
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   if (null_bitmap_ && value.isNull()) {
     null_bitmap_->setBit(actual_length_, true);
   } else {
     DCHECK(!value.isNull());
     value.copyInto(static_cast<char*>(values_) + (actual_length_ * type_length_));
   }
   ++actual_length_;
 }
  TypedValue applyToTypedValue(const TypedValue &argument) const override {
    if (source_nullability && argument.isNull()) {
      return TypedValue(TargetType::kStaticTypeID);
    }

    return TypedValue(static_cast<typename TargetType::cpptype>(
        argument.getLiteral<typename SourceType::cpptype>()));
  }
  inline void iterateUnaryInl(AggregationStateSum *state, const TypedValue &value) const {
    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
    if (value.isNull()) return;

    SpinMutexLock lock(state->mutex_);
    state->sum_ = fast_operator_->applyToTypedValues(state->sum_, value);
    state->null_ = false;
  }
 /**
  * @brief Find the first code which is greater than the specified typed
  *        value, similar to std::upper_bound().
  * @warning value must not be NULL.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The first code whose corresponding uncompressed value is greater
  *         than value. May return numberOfCodes() if every value in the
  *         dictionary is less than or equal to value.
  **/
 std::uint32_t getUpperBoundCodeForTypedValue(const TypedValue &value,
                                              const Type &value_type) const {
   DCHECK(!value.isNull());
   if (value_type.isSubsumedBy(type_)) {
     return getUpperBoundCodeForUntypedValue(value.getDataPtr());
   } else {
     return getUpperBoundCodeForDifferentTypedValue(value, value_type);
   }
 }
 /**
  * @brief Find the first code which is not less than the specified typed
  *        value, similar to std::lower_bound().
  * @warning value must not be NULL.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The first code whose corresponding uncompressed value is not less
  *         than value. May return numberOfCodes() if every value in the
  *         dictionary is less than value.
  **/
 std::uint32_t getLowerBoundCodeForTypedValue(const TypedValue &value,
                                              const Type &value_type,
                                              const bool ignore_null_code = false) const {
   DCHECK(!value.isNull());
   if (value_type.isSubsumedBy(type_)) {
     return getLowerBoundCodeForUntypedValue(value.getDataPtr(), ignore_null_code);
   } else {
     return getLowerBoundCodeForDifferentTypedValue(value, value_type, ignore_null_code);
   }
 }
void LongType::printValueToFile(const TypedValue &value,
                                FILE *file,
                                const int padding) const {
  DCHECK(!value.isNull());

  std::fprintf(file,
               "%*" PRId64,
               static_cast<int>(padding),
               value.getLiteral<std::int64_t>());
}
void IntType::printValueToFile(const TypedValue &value,
                               FILE *file,
                               const int padding) const {
  DCHECK(!value.isNull());

  std::fprintf(file,
               "%*d",
               static_cast<int>(padding),
               value.getLiteral<int>());
}
 /**
  * @brief Get the compressed code that represents the specified typed value.
  * @note This uses a binary search to find the appropriate code. It runs in
  *       O(log(n)) time.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The code for value in this dictionary, or the value of
  *         numberOfCodes() (the maximum code plus one) if value is not
  *         contained in this dictionary.
  **/
 std::uint32_t getCodeForTypedValue(const TypedValue &value,
                                    const Type &value_type) const {
   if (value.isNull()) {
     return getNullCode() == std::numeric_limits<std::uint32_t>::max() ? number_of_codes_including_null_
                                                                       : getNullCode();
   } else if (value_type.isSubsumedBy(type_)) {
     return getCodeForUntypedValue(value.getDataPtr());
   } else {
     return getCodeForDifferentTypedValue(value, value_type);
   }
 }
 /**
  * @brief Determine the range of codes that match a specified comparison with
  *        a specified typed value.
  *
  * @param comp The comparison to evaluate.
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The limits of the range of codes which match the predicate
  *         "coded-value comp value". The range is [first, second) (i.e. it
  *         is inclusive of first but not second).
  **/
 std::pair<std::uint32_t, std::uint32_t> getLimitCodesForComparisonTyped(
     const ComparisonID comp,
     const TypedValue &value,
     const Type &value_type) const {
   if (value_type.isSubsumedBy(type_)) {
     return getLimitCodesForComparisonUntyped(comp,
                                              value.isNull() ? nullptr : value.getDataPtr());
   } else {
     return getLimitCodesForComparisonDifferentTyped(comp, value, value_type);
   }
 }
Beispiel #12
0
void CharType::printValueToFile(const TypedValue &value,
                                FILE *file,
                                const int padding) const {
  DCHECK(!value.isNull());
  DCHECK_EQ(length_, static_cast<decltype(length_)>(static_cast<int>(length_)))
      << "Can not convert CHAR Type's maximum length " << length_
      << " to int for fprintf()";

  std::fprintf(file,
               "%*.*s",
               padding,
               static_cast<int>(length_),
               static_cast<const char*>(value.getOutOfLineData()));
}
 /**
  * @brief Fill this entire ColumnVector with copies of value.
  *
  * @param value A value to fill this ColumnVector with.
  **/
 inline void fillWithValue(const TypedValue &value) {
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   if (value.isNull()) {
     fillWithNulls();
   } else {
     if (null_bitmap_) {
       null_bitmap_->clear();
     }
     for (std::size_t pos = 0;
          pos < reserved_length_;
          ++pos) {
       value.copyInto(static_cast<char*>(values_) + (pos * type_length_));
     }
     actual_length_ = reserved_length_;
   }
 }
Beispiel #14
0
TypedValue CharType::coerceValue(const TypedValue &original_value,
                                 const Type &original_type) const {
  DCHECK(isCoercibleFrom(original_type))
      << "Can't coerce value of Type " << original_type.getName()
      << " to Type " << getName();

  if (original_value.isNull()) {
    return makeNullValue();
  }

  const void *original_data = original_value.getOutOfLineData();
  const std::size_t original_data_size = original_value.getDataSize();

  // VARCHAR always has a null-terminator. CHAR(X) has a null-terminator when
  // string's length is less than X.
  const bool null_terminated
      = (original_type.getTypeID() == kVarChar)
        || (original_data_size < original_type.maximumByteLength())
        || (std::memchr(original_data, '\0', original_data_size) != nullptr);

  if (original_data_size <= length_) {
    if (null_terminated || (original_data_size == length_)) {
      TypedValue value_copy(original_value);
      value_copy.markType(kChar);
      return value_copy;
    } else {
      // Need to make a new NULL-terminated copy of the string.
      char *null_terminated_str = static_cast<char*>(std::malloc(original_data_size + 1));
      std::memcpy(null_terminated_str, original_data, original_data_size);
      null_terminated_str[original_data_size] = '\0';
      return TypedValue::CreateWithOwnedData(kChar,
                                             null_terminated_str,
                                             original_data_size + 1);
    }
  } else {
    // Need to truncate.
    if (original_value.ownsOutOfLineData()) {
      char *truncated_str = static_cast<char*>(std::malloc(length_));
      std::memcpy(truncated_str, original_data, length_);
      return TypedValue::CreateWithOwnedData(kChar, truncated_str, length_);
    } else {
      // Original is a reference, so we will just make a shorter reference.
      return TypedValue(kChar, original_data, length_);
    }
  }
}
Beispiel #15
0
TypedValue LongType::coerceValue(const TypedValue &original_value,
                                 const Type &original_type) const {
  DCHECK(isCoercibleFrom(original_type))
      << "Can't coerce value of Type " << original_type.getName()
      << " to Type " << getName();

  if (original_value.isNull()) {
    return makeNullValue();
  }

  switch (original_type.getTypeID()) {
    case kInt:
      return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<int>()));
    case kLong:
      return original_value;
    case kFloat:
      return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<float>()));
    case kDouble:
      return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<double>()));
    default:
      LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
                 << " (not recognized as a numeric Type) to " << getName();
  }
}
Beispiel #16
0
std::string LongType::printValueToString(const TypedValue &value) const {
  DCHECK(!value.isNull());

  return std::to_string(value.getLiteral<std::int64_t>());
}
Beispiel #17
0
std::string CharType::printValueToString(const TypedValue &value) const {
  DCHECK(!value.isNull());

  const char *cstr = static_cast<const char*>(value.getOutOfLineData());
  return std::string(cstr, strnlen(cstr, length_));
}
 /**
  * @brief Iterate with count aggregation state.
  */
 inline void iterateUnaryInl(AggregationStateCount *state, const TypedValue &value) const {
   if ((!nullable_type) || (!value.isNull())) {
     state->count_.fetch_add(1, std::memory_order_relaxed);
   }
 }
Beispiel #19
0
 inline TypedValue applyToTypedValueInl(const TypedValue &argument) const {
   if (argument_nullable && argument.isNull()) {
     return argument;
   }
   return TypedValue(-argument.getLiteral<typename ResultType::cpptype>());
 }