Accept arbitrary numeric types for numbers() arguments (for scientific notation)

This is to make the syntax simpler, i.e. avoid explicit cast to UInt64
if you want to use scientific notation (i.e. 1e9 over 1 000 000 000).

v2: use plain evaluateConstantExpression() over
evaluateConstantExpressionOrIdentifierAsLiteral() since identifier will
not work anyway
This commit is contained in:
Azat Khuzhin 2021-02-10 22:07:52 +03:00
parent be831d09f7
commit 5001b19613
3 changed files with 17 additions and 1 deletions

View File

@ -6,6 +6,7 @@
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
#include <Storages/System/StorageSystemNumbers.h> #include <Storages/System/StorageSystemNumbers.h>
#include <Interpreters/evaluateConstantExpression.h> #include <Interpreters/evaluateConstantExpression.h>
#include <Interpreters/convertFieldToType.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <DataTypes/DataTypesNumber.h> #include <DataTypes/DataTypesNumber.h>
#include "registerTableFunctions.h" #include "registerTableFunctions.h"
@ -17,6 +18,7 @@ namespace DB
namespace ErrorCodes namespace ErrorCodes
{ {
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
} }
@ -56,7 +58,16 @@ void registerTableFunctionNumbers(TableFunctionFactory & factory)
template <bool multithreaded> template <bool multithreaded>
UInt64 TableFunctionNumbers<multithreaded>::evaluateArgument(const Context & context, ASTPtr & argument) const UInt64 TableFunctionNumbers<multithreaded>::evaluateArgument(const Context & context, ASTPtr & argument) const
{ {
return evaluateConstantExpressionOrIdentifierAsLiteral(argument, context)->as<ASTLiteral &>().value.safeGet<UInt64>(); const auto & [field, type] = evaluateConstantExpression(argument, context);
if (!isNativeNumber(type))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type {} expression, must be numeric type", type->getName());
Field converted = convertFieldToType(field, DataTypeUInt64());
if (converted.isNull())
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "The value {} is not representable as UInt64", applyVisitor(FieldVisitorToString(), field));
return converted.safeGet<UInt64>();
} }
} }

View File

@ -0,0 +1,5 @@
select * from numbers(1e2) format Null;
select * from numbers_mt(1e2) format Null;
select * from numbers_mt('100') format Null; -- { serverError 43 }
select * from numbers_mt(inf) format Null; -- { serverError 43 }
select * from numbers_mt(nan) format Null; -- { serverError 43 }