#include #include #include namespace DB { namespace { template struct TypeProcessorImpl { static DataTypeTraits::EnrichedDataTypePtr execute() { using EnrichedT1 = std::tuple; using EnrichedT2 = typename NumberTraits::EmbedType::Type; using TCombined = typename NumberTraits::TypeProduct::Type; auto type_res = DataTypeTraits::ToEnrichedDataTypeObject::execute(); if ((type_res.first == DataTypePtr()) && (type_res.second == DataTypePtr())) throw Exception("Types " + String(TypeName::get()) + " and " + String(TypeName::get()) + " are not upscalable to a common type without loss of precision", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); return type_res; } }; template struct RightTypeProcessor { static DataTypeTraits::EnrichedDataTypePtr execute(const IDataType & type2) { if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); if (checkDataType(&type2)) return TypeProcessorImpl::execute(); throw Exception("Logical error: not a numeric type passed to function getSmallestCommonNumericType", ErrorCodes::LOGICAL_ERROR); } }; template struct LeftTypeProcessor { static DataTypeTraits::EnrichedDataTypePtr execute(const DataTypePtr & right, const IDataType & type2) { if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); if (checkDataType(&*right)) return RightTypeProcessor::execute(type2); throw Exception("Logical error: not a numeric type passed to function getSmallestCommonNumericType", ErrorCodes::LOGICAL_ERROR); } }; } DataTypeTraits::EnrichedDataTypePtr getSmallestCommonNumericType(const DataTypeTraits::EnrichedDataTypePtr & type1, const IDataType & type2) { const DataTypePtr & left = type1.first; const DataTypePtr & right = type1.second; if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); if (checkDataType(&*left)) return LeftTypeProcessor::execute(right, type2); throw Exception("Logical error: not a numeric type passed to function getSmallestCommonNumericType", ErrorCodes::LOGICAL_ERROR); } } namespace DB { void registerFunctionsTransform(FunctionFactory & factory) { factory.registerFunction(); } }