<commit_before>#pragma once

#include <algorithm>
#include <stdexcept>

#include "common/macros.h"

#include "type/boolean_type.h"
#include "type/decimal_type.h"
#include "type/numeric_type.h"
#include "type/serializer.h"
#include "type/timestamp_type.h"
#include "type/varlen_type.h"

namespace peloton {
namespace type {

//===--------------------------------------------------------------------===//
// Value Factory
//===--------------------------------------------------------------------===//

class ValueFactory {
 public:
  static inline Value Clone(const Value &src,
                            UNUSED_ATTRIBUTE VarlenPool *dataPool = nullptr) {
    return src.Copy();
  }

  static inline Value GetTinyIntValue(int8_t value) {
    return Value(Type::TINYINT, value);
  }

  static inline Value GetSmallIntValue(int16_t value) {
    return Value(Type::SMALLINT, value);
  }

  static inline Value GetIntegerValue(int32_t value) {
    return Value(Type::INTEGER, value);
  }

  static inline Value GetParameterOffsetValue(int32_t value) {
    return Value(Type::PARAMETER_OFFSET, value);
  }

  static inline Value GetBigIntValue(int64_t value) {
    return Value(Type::BIGINT, value);
  }

  static inline Value GetTimestampValue(int64_t value) {
    return Value(Type::TIMESTAMP, value);
  }

  static inline Value GetDoubleValue(double value) {
    return Value(Type::DECIMAL, value);
  }

  static inline Value GetBooleanValue(CmpBool value) {
    return Value(Type::BOOLEAN, value == CMP_NULL ? PELOTON_BOOLEAN_NULL : (int8_t) value);
  }

  static inline Value GetBooleanValue(bool value) {
    return Value(Type::BOOLEAN, value);
  }

  static inline Value GetBooleanValue(int8_t value) {
    return Value(Type::BOOLEAN, value);
  }

  static inline Value GetVarcharValue(
      const char *value, bool manage_data, UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARCHAR, value,
                 value == nullptr ? 0 : strlen(value) + 1 , manage_data);
  }

  static inline Value GetVarcharValue(
      const std::string &value, UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARCHAR, value);
  }

  static inline Value GetVarbinaryValue(
      const std::string &value, UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARBINARY, value);
  }

  static inline Value GetVarbinaryValue(
      const unsigned char *rawBuf, int32_t rawLength, bool manage_data,
      UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARBINARY, (const char *)rawBuf, rawLength, manage_data);
  }

  static inline Value GetNullValueByType(Type::TypeId type_id) {
    Value ret_value;
    switch (type_id) {
      case Type::BOOLEAN:
        ret_value = GetBooleanValue(PELOTON_BOOLEAN_NULL);
        break;
      case Type::TINYINT:
        ret_value = GetTinyIntValue(PELOTON_INT8_NULL);
        break;
      case Type::SMALLINT:
        ret_value = GetSmallIntValue(PELOTON_INT16_NULL);
        break;
      case Type::INTEGER:
        ret_value = GetIntegerValue(PELOTON_INT32_NULL);
        break;
      case Type::BIGINT:
        ret_value = GetBigIntValue(PELOTON_INT64_NULL);
        break;
      case Type::DECIMAL:
        ret_value = GetDoubleValue(PELOTON_DECIMAL_NULL);
        break;
      case Type::TIMESTAMP:
        ret_value = GetTimestampValue(PELOTON_TIMESTAMP_NULL);
        break;
      case Type::VARCHAR:
        ret_value = GetVarcharValue(nullptr, false, nullptr);
        break;
      case Type::VARBINARY:
        ret_value = GetVarbinaryValue(nullptr, 0, false, nullptr);
        break;
      default:
        throw Exception(EXCEPTION_TYPE_UNKNOWN_TYPE, "Unknown type.");
    }
    ret_value.size_.len = PELOTON_VALUE_NULL;
    return ret_value;
  }

  static inline Value GetZeroValueByType(Type::TypeId type_id) {
    std::string zero_string("0");

    switch (type_id) {
      case Type::BOOLEAN:
        return GetBooleanValue(false);
      case Type::TINYINT:
        return GetTinyIntValue(0);
      case Type::SMALLINT:
        return GetSmallIntValue(0);
      case Type::INTEGER:
        return GetIntegerValue(0);
      case Type::BIGINT:
        return GetBigIntValue(0);
      case Type::DECIMAL:
        return GetDoubleValue((double)0);
      case Type::TIMESTAMP:
        return GetTimestampValue(0);
      case Type::VARCHAR:
        return GetVarcharValue(zero_string);
      case Type::VARBINARY:
        return GetVarbinaryValue(zero_string);
      default:
        break;
    }
    throw Exception(EXCEPTION_TYPE_UNKNOWN_TYPE, "Unknown type.");
  }

  static inline Value CastAsBigInt(const Value &value) {
    if (Type::GetInstance(Type::BIGINT)->IsCoercableFrom(value.GetTypeId())) {
      if (value.IsNull())
        return ValueFactory::GetBigIntValue((int64_t)PELOTON_INT64_NULL);
      switch (value.GetTypeId()) {
        case Type::TINYINT:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int8_t>());
        case Type::SMALLINT:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int16_t>());
        case Type::INTEGER:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int32_t>());
        case Type::BIGINT:
          return ValueFactory::GetBigIntValue(value.GetAs<int64_t>());
        case Type::DECIMAL: {
          if (value.GetAs<double>() > (double)PELOTON_INT64_MAX ||
              value.GetAs<double>() < (double)PELOTON_INT64_MIN)
            throw Exception(EXCEPTION_TYPE_OUT_OF_RANGE,
                            "Numeric value out of range.");
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<double>());
        }
        case Type::VARCHAR: {
          std::string str = value.ToString();
          int64_t bigint = 0;
          try {
            bigint = stoll(str);<commit_msg>Improved exception error messages in ValueFactory to include the invalid TypeId. It's so easier now with StringUtil::Format<commit_after>#pragma once

#include <algorithm>
#include <stdexcept>

#include "common/macros.h"
#include "type/boolean_type.h"
#include "type/decimal_type.h"
#include "type/numeric_type.h"
#include "type/serializer.h"
#include "type/timestamp_type.h"
#include "type/varlen_type.h"
#include "util/string_util.h"

namespace peloton {
namespace type {

//===--------------------------------------------------------------------===//
// Value Factory
//===--------------------------------------------------------------------===//

class ValueFactory {
 public:
  static inline Value Clone(const Value &src,
                            UNUSED_ATTRIBUTE VarlenPool *dataPool = nullptr) {
    return src.Copy();
  }

  static inline Value GetTinyIntValue(int8_t value) {
    return Value(Type::TINYINT, value);
  }

  static inline Value GetSmallIntValue(int16_t value) {
    return Value(Type::SMALLINT, value);
  }

  static inline Value GetIntegerValue(int32_t value) {
    return Value(Type::INTEGER, value);
  }

  static inline Value GetParameterOffsetValue(int32_t value) {
    return Value(Type::PARAMETER_OFFSET, value);
  }

  static inline Value GetBigIntValue(int64_t value) {
    return Value(Type::BIGINT, value);
  }

  static inline Value GetTimestampValue(int64_t value) {
    return Value(Type::TIMESTAMP, value);
  }

  static inline Value GetDoubleValue(double value) {
    return Value(Type::DECIMAL, value);
  }

  static inline Value GetBooleanValue(CmpBool value) {
    return Value(Type::BOOLEAN,
                 value == CMP_NULL ? PELOTON_BOOLEAN_NULL : (int8_t)value);
  }

  static inline Value GetBooleanValue(bool value) {
    return Value(Type::BOOLEAN, value);
  }

  static inline Value GetBooleanValue(int8_t value) {
    return Value(Type::BOOLEAN, value);
  }

  static inline Value GetVarcharValue(
      const char *value, bool manage_data,
      UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARCHAR, value, value == nullptr ? 0 : strlen(value) + 1,
                 manage_data);
  }

  static inline Value GetVarcharValue(
      const std::string &value, UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARCHAR, value);
  }

  static inline Value GetVarbinaryValue(
      const std::string &value, UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARBINARY, value);
  }

  static inline Value GetVarbinaryValue(
      const unsigned char *rawBuf, int32_t rawLength, bool manage_data,
      UNUSED_ATTRIBUTE VarlenPool *pool = nullptr) {
    return Value(Type::VARBINARY, (const char *)rawBuf, rawLength, manage_data);
  }

  static inline Value GetNullValueByType(Type::TypeId type_id) {
    Value ret_value;
    switch (type_id) {
      case Type::BOOLEAN:
        ret_value = GetBooleanValue(PELOTON_BOOLEAN_NULL);
        break;
      case Type::TINYINT:
        ret_value = GetTinyIntValue(PELOTON_INT8_NULL);
        break;
      case Type::SMALLINT:
        ret_value = GetSmallIntValue(PELOTON_INT16_NULL);
        break;
      case Type::INTEGER:
        ret_value = GetIntegerValue(PELOTON_INT32_NULL);
        break;
      case Type::BIGINT:
        ret_value = GetBigIntValue(PELOTON_INT64_NULL);
        break;
      case Type::DECIMAL:
        ret_value = GetDoubleValue(PELOTON_DECIMAL_NULL);
        break;
      case Type::TIMESTAMP:
        ret_value = GetTimestampValue(PELOTON_TIMESTAMP_NULL);
        break;
      case Type::VARCHAR:
        ret_value = GetVarcharValue(nullptr, false, nullptr);
        break;
      case Type::VARBINARY:
        ret_value = GetVarbinaryValue(nullptr, 0, false, nullptr);
        break;
      default: {
        std::string msg =
            StringUtil::Format("Unknown Type '%d' for GetNullValueByType",
                               static_cast<int>(type_id));
        throw Exception(EXCEPTION_TYPE_UNKNOWN_TYPE, msg);
      }
    }
    ret_value.size_.len = PELOTON_VALUE_NULL;
    return ret_value;
  }

  static inline Value GetZeroValueByType(Type::TypeId type_id) {
    std::string zero_string("0");

    switch (type_id) {
      case Type::BOOLEAN:
        return GetBooleanValue(false);
      case Type::TINYINT:
        return GetTinyIntValue(0);
      case Type::SMALLINT:
        return GetSmallIntValue(0);
      case Type::INTEGER:
        return GetIntegerValue(0);
      case Type::BIGINT:
        return GetBigIntValue(0);
      case Type::DECIMAL:
        return GetDoubleValue((double)0);
      case Type::TIMESTAMP:
        return GetTimestampValue(0);
      case Type::VARCHAR:
        return GetVarcharValue(zero_string);
      case Type::VARBINARY:
        return GetVarbinaryValue(zero_string);
      default:
        break;
    }
    std::string msg = StringUtil::Format(
        "Unknown Type '%d' for GetZeroValueByType", static_cast<int>(type_id));
    throw Exception(EXCEPTION_TYPE_UNKNOWN_TYPE, msg);
  }

  static inline Value CastAsBigInt(const Value &value) {
    if (Type::GetInstance(Type::BIGINT)->IsCoercableFrom(value.GetTypeId())) {
      if (value.IsNull())
        return ValueFactory::GetBigIntValue((int64_t)PELOTON_INT64_NULL);
      switch (value.GetTypeId()) {
        case Type::TINYINT:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int8_t>());
        case Type::SMALLINT:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int16_t>());
        case Type::INTEGER:
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<int32_t>());
        case Type::BIGINT:
          return ValueFactory::GetBigIntValue(value.GetAs<int64_t>());
        case Type::DECIMAL: {
          if (value.GetAs<double>() > (double)PELOTON_INT64_MAX ||
              value.GetAs<double>() < (double)PELOTON_INT64_MIN)
            throw Exception(EXCEPTION_TYPE_OUT_OF_RANGE,
                            "Numeric value out of range.");
          return ValueFactory::GetBigIntValue((int64_t)value.GetAs<double>());
        }
        case Type::VARCHAR: {
          std::string str = value.ToString();
          int64_t bigint = 0;
          try {
            bigint = stoll(str);
{'fraction_non_alphanumeric': 0.1268061783756851, 'fraction_numerical': 0.009632951336987211, 'mean_word_length': 2.8873466752743706, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4870471', 'n_tokens_mistral': 3798, 'n_tokens_neox': 3747, 'n_words': 779}