2017-04-01 09:19:00 +00:00
|
|
|
#include <DataTypes/FieldToDataType.h>
|
|
|
|
#include <DataTypes/DataTypeTuple.h>
|
2020-10-10 06:49:03 +00:00
|
|
|
#include <DataTypes/DataTypeMap.h>
|
2021-08-20 21:11:22 +00:00
|
|
|
#include <DataTypes/DataTypeObject.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <DataTypes/DataTypesNumber.h>
|
2018-08-23 19:11:31 +00:00
|
|
|
#include <DataTypes/DataTypesDecimal.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <DataTypes/DataTypeString.h>
|
|
|
|
#include <DataTypes/DataTypeArray.h>
|
2017-12-07 08:31:47 +00:00
|
|
|
#include <DataTypes/DataTypeNullable.h>
|
|
|
|
#include <DataTypes/DataTypeNothing.h>
|
2021-05-03 22:46:51 +00:00
|
|
|
#include <DataTypes/DataTypeUUID.h>
|
2022-11-29 17:34:16 +00:00
|
|
|
#include <DataTypes/DataTypeIPv4andIPv6.h>
|
2018-01-11 18:37:11 +00:00
|
|
|
#include <DataTypes/getLeastSupertype.h>
|
2019-02-11 13:11:52 +00:00
|
|
|
#include <DataTypes/DataTypeFactory.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Common/Exception.h>
|
2015-06-29 04:54:52 +00:00
|
|
|
|
2015-10-12 07:05:54 +00:00
|
|
|
|
2015-06-29 04:54:52 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2016-01-11 21:46:36 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int EMPTY_DATA_PASSED;
|
2023-02-04 12:49:32 +00:00
|
|
|
extern const int NOT_IMPLEMENTED;
|
2016-01-11 21:46:36 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Null &) const
|
2017-03-12 10:13:45 +00:00
|
|
|
{
|
2017-12-07 08:31:47 +00:00
|
|
|
return std::make_shared<DataTypeNullable>(std::make_shared<DataTypeNothing>());
|
2017-03-12 10:13:45 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const UInt64 & x) const
|
2017-03-12 10:13:45 +00:00
|
|
|
{
|
2018-11-26 00:56:50 +00:00
|
|
|
if (x <= std::numeric_limits<UInt8>::max()) return std::make_shared<DataTypeUInt8>();
|
2017-12-07 03:35:19 +00:00
|
|
|
if (x <= std::numeric_limits<UInt16>::max()) return std::make_shared<DataTypeUInt16>();
|
|
|
|
if (x <= std::numeric_limits<UInt32>::max()) return std::make_shared<DataTypeUInt32>();
|
2017-03-12 10:13:45 +00:00
|
|
|
return std::make_shared<DataTypeUInt64>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Int64 & x) const
|
2017-03-12 10:13:45 +00:00
|
|
|
{
|
2023-08-09 15:03:50 +00:00
|
|
|
if (x <= std::numeric_limits<Int8>::max() && x >= std::numeric_limits<Int8>::min()) return std::make_shared<DataTypeInt8>();
|
|
|
|
if (x <= std::numeric_limits<Int16>::max() && x >= std::numeric_limits<Int16>::min()) return std::make_shared<DataTypeInt16>();
|
|
|
|
if (x <= std::numeric_limits<Int32>::max() && x >= std::numeric_limits<Int32>::min()) return std::make_shared<DataTypeInt32>();
|
2017-03-12 10:13:45 +00:00
|
|
|
return std::make_shared<DataTypeInt64>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Float64 &) const
|
2021-05-03 15:20:12 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeFloat64>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const UInt128 &) const
|
2021-05-03 15:20:12 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeUInt128>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Int128 &) const
|
2020-08-19 11:52:17 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeInt128>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const UInt256 &) const
|
2017-03-12 10:13:45 +00:00
|
|
|
{
|
2021-05-03 15:20:12 +00:00
|
|
|
return std::make_shared<DataTypeUInt256>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Int256 &) const
|
2021-05-03 15:20:12 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeInt256>();
|
2017-03-12 10:13:45 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const UUID &) const
|
2021-05-03 22:46:51 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeUUID>();
|
2017-03-12 10:13:45 +00:00
|
|
|
}
|
|
|
|
|
2022-11-14 14:17:17 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const IPv4 &) const
|
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeIPv4>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const IPv6 &) const
|
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeIPv6>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const String &) const
|
2017-03-12 10:13:45 +00:00
|
|
|
{
|
|
|
|
return std::make_shared<DataTypeString>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const DecimalField<Decimal32> & x) const
|
2018-08-23 19:11:31 +00:00
|
|
|
{
|
|
|
|
using Type = DataTypeDecimal<Decimal32>;
|
|
|
|
return std::make_shared<Type>(Type::maxPrecision(), x.getScale());
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const DecimalField<Decimal64> & x) const
|
2018-08-23 19:11:31 +00:00
|
|
|
{
|
|
|
|
using Type = DataTypeDecimal<Decimal64>;
|
|
|
|
return std::make_shared<Type>(Type::maxPrecision(), x.getScale());
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const DecimalField<Decimal128> & x) const
|
2018-08-23 19:11:31 +00:00
|
|
|
{
|
2018-10-22 08:25:11 +00:00
|
|
|
using Type = DataTypeDecimal<Decimal128>;
|
2018-08-23 19:11:31 +00:00
|
|
|
return std::make_shared<Type>(Type::maxPrecision(), x.getScale());
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const DecimalField<Decimal256> & x) const
|
2020-08-19 11:52:17 +00:00
|
|
|
{
|
|
|
|
using Type = DataTypeDecimal<Decimal256>;
|
|
|
|
return std::make_shared<Type>(Type::maxPrecision(), x.getScale());
|
|
|
|
}
|
2017-03-12 10:13:45 +00:00
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Array & x) const
|
2015-06-29 04:54:52 +00:00
|
|
|
{
|
2017-12-07 03:35:19 +00:00
|
|
|
DataTypes element_types;
|
|
|
|
element_types.reserve(x.size());
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2023-08-15 18:38:25 +00:00
|
|
|
bool has_signed_int = false;
|
2023-09-08 07:05:04 +00:00
|
|
|
bool uint64_convert_possible = true;
|
2018-02-28 04:30:27 +00:00
|
|
|
for (const Field & elem : x)
|
2023-08-15 18:38:25 +00:00
|
|
|
{
|
|
|
|
DataTypePtr type = applyVisitor(*this, elem);
|
|
|
|
element_types.emplace_back(type);
|
2023-09-08 07:05:04 +00:00
|
|
|
checkUInt64ToIn64Conversion(has_signed_int, uint64_convert_possible, type, elem);
|
2023-08-15 18:38:25 +00:00
|
|
|
}
|
|
|
|
|
2023-09-08 07:05:04 +00:00
|
|
|
if (has_signed_int && uint64_convert_possible)
|
|
|
|
convertUInt64ToInt64IfPossible(element_types);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2023-08-14 19:25:32 +00:00
|
|
|
return std::make_shared<DataTypeArray>(getLeastSupertype<on_error>(element_types));
|
2015-06-29 04:54:52 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Tuple & tuple) const
|
2015-12-24 14:31:41 +00:00
|
|
|
{
|
|
|
|
if (tuple.empty())
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::EMPTY_DATA_PASSED, "Cannot infer type of an empty tuple");
|
2015-12-24 14:31:41 +00:00
|
|
|
|
|
|
|
DataTypes element_types;
|
2021-06-15 19:55:21 +00:00
|
|
|
element_types.reserve(tuple.size());
|
2015-12-24 14:31:41 +00:00
|
|
|
|
2018-02-28 04:30:27 +00:00
|
|
|
for (const auto & element : tuple)
|
2022-06-22 16:25:57 +00:00
|
|
|
element_types.push_back(applyVisitor(*this, element));
|
2015-12-24 14:31:41 +00:00
|
|
|
|
2016-05-28 07:48:40 +00:00
|
|
|
return std::make_shared<DataTypeTuple>(element_types);
|
2015-12-24 14:31:41 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Map & map) const
|
2020-10-10 06:49:03 +00:00
|
|
|
{
|
2020-12-03 03:52:41 +00:00
|
|
|
DataTypes key_types;
|
|
|
|
DataTypes value_types;
|
|
|
|
key_types.reserve(map.size());
|
|
|
|
value_types.reserve(map.size());
|
|
|
|
|
2023-08-15 18:38:25 +00:00
|
|
|
bool k_has_signed_int = false;
|
2023-09-08 07:05:04 +00:00
|
|
|
bool k_uint64_convert_possible = true;
|
2023-08-15 18:38:25 +00:00
|
|
|
bool v_has_signed_int = false;
|
2023-09-08 07:05:04 +00:00
|
|
|
bool v_uint64_convert_possible = true;
|
2020-12-03 03:52:41 +00:00
|
|
|
for (const auto & elem : map)
|
|
|
|
{
|
|
|
|
const auto & tuple = elem.safeGet<const Tuple &>();
|
|
|
|
assert(tuple.size() == 2);
|
2023-08-15 18:38:25 +00:00
|
|
|
DataTypePtr k_type = applyVisitor(*this, tuple[0]);
|
|
|
|
key_types.push_back(k_type);
|
2023-09-08 07:05:04 +00:00
|
|
|
checkUInt64ToIn64Conversion(k_has_signed_int, k_uint64_convert_possible, k_type, tuple[0]);
|
2023-08-15 18:38:25 +00:00
|
|
|
DataTypePtr v_type = applyVisitor(*this, tuple[1]);
|
|
|
|
value_types.push_back(v_type);
|
2023-09-08 07:05:04 +00:00
|
|
|
checkUInt64ToIn64Conversion(v_has_signed_int, v_uint64_convert_possible, v_type, tuple[1]);
|
2020-12-03 03:52:41 +00:00
|
|
|
}
|
|
|
|
|
2023-09-08 07:05:04 +00:00
|
|
|
if (k_has_signed_int && k_uint64_convert_possible)
|
|
|
|
convertUInt64ToInt64IfPossible(key_types);
|
2023-08-15 18:38:25 +00:00
|
|
|
|
2023-09-08 07:05:04 +00:00
|
|
|
if (v_has_signed_int && v_uint64_convert_possible)
|
|
|
|
convertUInt64ToInt64IfPossible(value_types);
|
2023-08-15 18:38:25 +00:00
|
|
|
|
2021-05-06 05:33:06 +00:00
|
|
|
return std::make_shared<DataTypeMap>(
|
2022-06-22 16:25:57 +00:00
|
|
|
getLeastSupertype<on_error>(key_types),
|
2022-06-28 14:21:21 +00:00
|
|
|
getLeastSupertype<on_error>(value_types));
|
2020-10-10 06:49:03 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const Object &) const
|
2021-08-20 21:11:22 +00:00
|
|
|
{
|
|
|
|
/// TODO: Do we need different parameters for type Object?
|
|
|
|
return std::make_shared<DataTypeObject>("json", false);
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const AggregateFunctionStateData & x) const
|
2019-02-11 13:11:52 +00:00
|
|
|
{
|
2020-04-22 05:39:31 +00:00
|
|
|
const auto & name = static_cast<const AggregateFunctionStateData &>(x).name;
|
2019-02-11 13:11:52 +00:00
|
|
|
return DataTypeFactory::instance().get(name);
|
|
|
|
}
|
2015-12-24 14:31:41 +00:00
|
|
|
|
2023-02-03 16:07:02 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator() (const CustomType &) const
|
|
|
|
{
|
|
|
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Not implemented");
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
DataTypePtr FieldToDataType<on_error>::operator()(const bool &) const
|
2022-01-18 11:52:27 +00:00
|
|
|
{
|
|
|
|
return DataTypeFactory::instance().get("Bool");
|
|
|
|
}
|
|
|
|
|
2023-09-08 07:05:04 +00:00
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
void FieldToDataType<on_error>::checkUInt64ToIn64Conversion(bool & has_signed_int, bool & uint64_convert_possible, const DataTypePtr & type, const Field & elem) const
|
|
|
|
{
|
|
|
|
if (uint64_convert_possible)
|
|
|
|
{
|
|
|
|
bool is_native_int = WhichDataType(type).isNativeInt();
|
|
|
|
|
|
|
|
if (is_native_int)
|
|
|
|
has_signed_int |= is_native_int;
|
|
|
|
else if (type->getTypeId() == TypeIndex::UInt64)
|
|
|
|
uint64_convert_possible &= (elem.template get<UInt64>() <= std::numeric_limits<Int64>::max());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <LeastSupertypeOnError on_error>
|
|
|
|
void FieldToDataType<on_error>::convertUInt64ToInt64IfPossible(DataTypes & data_types) const
|
|
|
|
{
|
|
|
|
for (auto& type : data_types)
|
|
|
|
if (type->getTypeId() == TypeIndex::UInt64)
|
|
|
|
type = std::make_shared<DataTypeInt64>();
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:25:57 +00:00
|
|
|
template class FieldToDataType<LeastSupertypeOnError::Throw>;
|
|
|
|
template class FieldToDataType<LeastSupertypeOnError::String>;
|
|
|
|
template class FieldToDataType<LeastSupertypeOnError::Null>;
|
|
|
|
|
2015-06-29 04:54:52 +00:00
|
|
|
}
|