diff --git a/src/DataTypes/DataTypesNumber.cpp b/src/DataTypes/DataTypesNumber.cpp index f260daa15b4..3fbf81791dd 100644 --- a/src/DataTypes/DataTypesNumber.cpp +++ b/src/DataTypes/DataTypesNumber.cpp @@ -15,101 +15,25 @@ namespace ErrorCodes extern const int UNEXPECTED_AST_STRUCTURE; } -static DataTypePtr createForInt8(const ASTPtr & arguments) +template +static DataTypePtr createNumericDataType(const ASTPtr & arguments) { - if (arguments) { - if (arguments->children.size() > 1) - throw Exception("INT8 data type family must not have more than one argument - display width", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - const auto * argument = arguments->children[0]->as(); - if (!argument || argument->value.getType() != Field::Types::UInt64 || argument->value.get() == 0) - throw Exception("INT8 data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } - - return std::make_shared(); -} - -static DataTypePtr createForInt16(const ASTPtr & arguments) -{ - if (arguments) { - if (arguments->children.size() > 1) - throw Exception("INT16 data type family must not have more than one argument - display width", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - const auto * argument = arguments->children[0]->as(); - if (!argument || argument->value.getType() != Field::Types::UInt64 || argument->value.get() == 0) - throw Exception("INT16 data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } - - return std::make_shared(); -} - -static DataTypePtr createForInt32(const ASTPtr & arguments) -{ - if (arguments) { - if (arguments->children.size() > 1) - throw Exception("INT32 data type family must not have more than one argument - display width", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - const auto * argument = arguments->children[0]->as(); - if (!argument || argument->value.getType() != Field::Types::UInt64 || argument->value.get() == 0) - throw Exception("INT32 data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } - - return std::make_shared(); -} - -static DataTypePtr createForInt64(const ASTPtr & arguments) -{ - if (arguments) { - if (arguments->children.size() > 1) - throw Exception("INT64 data type family must not have more than one argument - display width", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - const auto * argument = arguments->children[0]->as(); - if (!argument || argument->value.getType() != Field::Types::UInt64 || argument->value.get() == 0) - throw Exception("INT64 data type family may have only a number (positive integer) as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } - - return std::make_shared(); -} - -static DataTypePtr createForFloat32(const ASTPtr & arguments) -{ - if (arguments) { - if (arguments->children.size() > 2) - throw Exception("FLOAT32 data type family must not have more than two arguments - total number of digits and number of digits following the decimal point", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - else if (arguments->children.size() == 1) { - const auto * argument = arguments->children[0]->as(); - if (!argument || argument->value.getType() != Field::Types::UInt64) - throw Exception("FLOAT32 data type family may have a non negative number as its argument", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } else if (arguments->children.size() == 2) { - const auto * beforePoint = arguments->children[0]->as(); - const auto * afterPoint = arguments->children[1]->as(); - if (!beforePoint || beforePoint->value.getType() != Field::Types::UInt64 || - !afterPoint|| afterPoint->value.getType() != Field::Types::UInt64) - throw Exception("FLOAT32 data type family may have a non negative number as its arguments", ErrorCodes::UNEXPECTED_AST_STRUCTURE); + if (arguments) + { + if (std::is_integral_v) + { + if (arguments->children.size() > 1) + throw Exception(String(TypeName::get()) + " data type family must not have more than one argument - display width", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + } + else + { + if (arguments->children.size() > 2) + throw Exception(String(TypeName::get()) + " data type family must not have more than two arguments - total number of digits and number of digits following the decimal point", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); } } - - return std::make_shared(); + return std::make_shared>(); } -static DataTypePtr createForFloat64(const ASTPtr & arguments) -{ - if (arguments) { - if (arguments->children.size() != 2) - throw Exception("FLOAT64 data type family must have only two arguments - total number of digits and number of digits following the decimal point", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - else { - const auto * beforePoint = arguments->children[0]->as(); - const auto * afterPoint = arguments->children[1]->as(); - if (!beforePoint || beforePoint->value.getType() != Field::Types::UInt64 || - !afterPoint|| afterPoint->value.getType() != Field::Types::UInt64) - throw Exception("FLOAT64 data type family may have a non negative number as its arguments", ErrorCodes::UNEXPECTED_AST_STRUCTURE); - } - } - - return std::make_shared(); -} - - void registerDataTypeNumbers(DataTypeFactory & factory) { @@ -118,12 +42,12 @@ void registerDataTypeNumbers(DataTypeFactory & factory) factory.registerSimpleDataType("UInt32", [] { return DataTypePtr(std::make_shared()); }); factory.registerSimpleDataType("UInt64", [] { return DataTypePtr(std::make_shared()); }); - factory.registerDataType("Int8", createForInt8); - factory.registerDataType("Int16", createForInt16); - factory.registerDataType("Int32", createForInt32); - factory.registerDataType("Int64", createForInt64); - factory.registerDataType("Float32", createForFloat32); - factory.registerDataType("Float64", createForFloat64); + factory.registerDataType("Int8", createNumericDataType); + factory.registerDataType("Int16", createNumericDataType); + factory.registerDataType("Int32", createNumericDataType); + factory.registerDataType("Int64", createNumericDataType); + factory.registerDataType("Float32", createNumericDataType); + factory.registerDataType("Float64", createNumericDataType); /// These synonyms are added for compatibility.