mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Introduced intExp functions; using it where appropriate; make them available in SQL [#CLICKHOUSE-3].
This commit is contained in:
parent
46c733ec11
commit
74f191dfd3
@ -26,6 +26,8 @@ generate_function_register(Arithmetic
|
||||
FunctionBitTestAll
|
||||
FunctionGCD
|
||||
FunctionLCM
|
||||
FunctionIntExp2
|
||||
FunctionIntExp10
|
||||
)
|
||||
|
||||
generate_function_register(Array
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <ext/range.h>
|
||||
#include <common/intExp.h>
|
||||
#include <boost/math/common_factor.hpp>
|
||||
|
||||
|
||||
@ -453,6 +454,29 @@ struct LCMImpl
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
struct IntExp2Impl
|
||||
{
|
||||
using ResultType = UInt64;
|
||||
|
||||
static inline ResultType apply(A a)
|
||||
{
|
||||
return intExp2(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
struct IntExp10Impl
|
||||
{
|
||||
using ResultType = UInt64;
|
||||
|
||||
static inline ResultType apply(A a)
|
||||
{
|
||||
return intExp10(a);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// this one is just for convenience
|
||||
template <bool B, typename T1, typename T2> using If = typename std::conditional<B, T1, T2>::type;
|
||||
/// these ones for better semantics
|
||||
@ -1013,6 +1037,8 @@ struct NameLeast { static constexpr auto name = "least"; };
|
||||
struct NameGreatest { static constexpr auto name = "greatest"; };
|
||||
struct NameGCD { static constexpr auto name = "gcd"; };
|
||||
struct NameLCM { static constexpr auto name = "lcm"; };
|
||||
struct NameIntExp2 { static constexpr auto name = "intExp2"; };
|
||||
struct NameIntExp10 { static constexpr auto name = "intExp10"; };
|
||||
|
||||
using FunctionPlus = FunctionBinaryArithmetic<PlusImpl, NamePlus>;
|
||||
using FunctionMinus = FunctionBinaryArithmetic<MinusImpl, NameMinus>;
|
||||
@ -1036,6 +1062,10 @@ using FunctionLeast = FunctionBinaryArithmetic<LeastImpl, NameLeast>;
|
||||
using FunctionGreatest = FunctionBinaryArithmetic<GreatestImpl, NameGreatest>;
|
||||
using FunctionGCD = FunctionBinaryArithmetic<GCDImpl, NameGCD>;
|
||||
using FunctionLCM = FunctionBinaryArithmetic<LCMImpl, NameLCM>;
|
||||
/// Assumed to be injective for the purpose of query optimization, but in fact it is not injective because of possible overflow.
|
||||
using FunctionIntExp2 = FunctionUnaryArithmetic<IntExp2Impl, NameIntExp2, true>;
|
||||
using FunctionIntExp10 = FunctionUnaryArithmetic<IntExp10Impl, NameIntExp10, true>;
|
||||
|
||||
|
||||
/// Monotonicity properties for some functions.
|
||||
|
||||
@ -1072,6 +1102,36 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameBitNot>
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameIntExp2>
|
||||
{
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const Field & left, const Field & right)
|
||||
{
|
||||
Float64 left_float = left.isNull() ? -std::numeric_limits<Float64>::infinity() : applyVisitor(FieldVisitorConvertToNumber<Float64>(), left);
|
||||
Float64 right_float = right.isNull() ? std::numeric_limits<Float64>::infinity() : applyVisitor(FieldVisitorConvertToNumber<Float64>(), right);
|
||||
|
||||
if (left_float < 0 || right_float > 63)
|
||||
return {};
|
||||
|
||||
return { true };
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameIntExp10>
|
||||
{
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const Field & left, const Field & right)
|
||||
{
|
||||
Float64 left_float = left.isNull() ? -std::numeric_limits<Float64>::infinity() : applyVisitor(FieldVisitorConvertToNumber<Float64>(), left);
|
||||
Float64 right_float = right.isNull() ? std::numeric_limits<Float64>::infinity() : applyVisitor(FieldVisitorConvertToNumber<Float64>(), right);
|
||||
|
||||
if (left_float < 0 || right_float > 19)
|
||||
return {};
|
||||
|
||||
return { true };
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Optimizations for integer division by a constant.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <common/exp10.h>
|
||||
#include <common/intExp.h>
|
||||
|
||||
#include <Parsers/CommonParsers.h>
|
||||
#include <Parsers/ParserSampleRatio.h>
|
||||
@ -48,13 +48,13 @@ static bool parseDecimal(const char * pos, const char * end, ASTSampleRatio::Rat
|
||||
return false;
|
||||
}
|
||||
|
||||
res.numerator = num_before * exp10(number_of_digits_after_point) + num_after;
|
||||
res.denominator = exp10(number_of_digits_after_point);
|
||||
res.numerator = num_before * intExp10(number_of_digits_after_point) + num_after;
|
||||
res.denominator = intExp10(number_of_digits_after_point);
|
||||
|
||||
if (exponent > 0)
|
||||
res.numerator *= exp10(exponent);
|
||||
res.numerator *= intExp10(exponent);
|
||||
if (exponent < 0)
|
||||
res.denominator *= exp10(-exponent);
|
||||
res.denominator *= intExp10(-exponent);
|
||||
|
||||
/// NOTE You do not need to remove the common power of ten from the numerator and denominator.
|
||||
return true;
|
||||
|
@ -1 +1 @@
|
||||
SELECT number, exp10(number) FROM system.numbers LIMIT 310;
|
||||
SELECT number, exp10(number) FROM system.numbers LIMIT 310;
|
||||
|
70
dbms/tests/queries/0_stateless/00536_int_exp.reference
Normal file
70
dbms/tests/queries/0_stateless/00536_int_exp.reference
Normal file
@ -0,0 +1,70 @@
|
||||
1 1 1 1 1 1
|
||||
2 2 1 10 10 1
|
||||
4 4 1 100 100 1
|
||||
8 8 1 1000 1000 1
|
||||
16 16 1 10000 10000 1
|
||||
32 32 1 100000 100000 1
|
||||
64 64 1 1000000 1000000 1
|
||||
128 128 1 10000000 10000000 1
|
||||
256 256 1 100000000 100000000 1
|
||||
512 512 1 1000000000 1000000000 1
|
||||
1024 1024 1 10000000000 10000000000 1
|
||||
2048 2048 1 100000000000 100000000000 1
|
||||
4096 4096 1 1000000000000 1000000000000 1
|
||||
8192 8192 1 10000000000000 10000000000000 1
|
||||
16384 16384 1 100000000000000 100000000000000 1
|
||||
32768 32768 1 1000000000000000 1000000000000000 1
|
||||
65536 65536 1 10000000000000000 10000000000000000 1
|
||||
131072 131072 1 100000000000000000 100000000000000000 1
|
||||
262144 262144 1 1000000000000000000 1000000000000000000 1
|
||||
524288 524288 1 10000000000000000000 10000000000000000000 1
|
||||
1048576 1048576 1 100000000000000000000 18446744073709551615 0
|
||||
2097152 2097152 1 1e21 18446744073709551615 0
|
||||
4194304 4194304 1 1e22 18446744073709551615 0
|
||||
8388608 8388608 1 1e23 18446744073709551615 0
|
||||
16777216 16777216 1 1e24 18446744073709551615 0
|
||||
33554432 33554432 1 1e25 18446744073709551615 0
|
||||
67108864 67108864 1 1e26 18446744073709551615 0
|
||||
134217728 134217728 1 1e27 18446744073709551615 0
|
||||
268435456 268435456 1 1e28 18446744073709551615 0
|
||||
536870912 536870912 1 1e29 18446744073709551615 0
|
||||
1073741824 1073741824 1 1e30 18446744073709551615 0
|
||||
2147483648 2147483648 1 1e31 18446744073709551615 0
|
||||
4294967296 4294967296 1 1e32 18446744073709551615 0
|
||||
8589934592 8589934592 1 1e33 18446744073709551615 0
|
||||
17179869184 17179869184 1 1e34 18446744073709551615 0
|
||||
34359738368 34359738368 1 1e35 18446744073709551615 0
|
||||
68719476736 68719476736 1 1e36 18446744073709551615 0
|
||||
137438953472 137438953472 1 1e37 18446744073709551615 0
|
||||
274877906944 274877906944 1 1e38 18446744073709551615 0
|
||||
549755813888 549755813888 1 1e39 18446744073709551615 0
|
||||
1099511627776 1099511627776 1 1e40 18446744073709551615 0
|
||||
2199023255552 2199023255552 1 1e41 18446744073709551615 0
|
||||
4398046511104 4398046511104 1 1e42 18446744073709551615 0
|
||||
8796093022208 8796093022208 1 1e43 18446744073709551615 0
|
||||
17592186044416 17592186044416 1 1e44 18446744073709551615 0
|
||||
35184372088832 35184372088832 1 1e45 18446744073709551615 0
|
||||
70368744177664 70368744177664 1 1e46 18446744073709551615 0
|
||||
140737488355328 140737488355328 1 1e47 18446744073709551615 0
|
||||
281474976710656 281474976710656 1 1e48 18446744073709551615 0
|
||||
562949953421312 562949953421312 1 1e49 18446744073709551615 0
|
||||
1125899906842624 1125899906842624 1 1e50 18446744073709551615 0
|
||||
2251799813685248 2251799813685248 1 1e51 18446744073709551615 0
|
||||
4503599627370496 4503599627370496 1 1e52 18446744073709551615 0
|
||||
9007199254740992 9007199254740992 1 1e53 18446744073709551615 0
|
||||
18014398509481984 18014398509481984 1 1e54 18446744073709551615 0
|
||||
36028797018963970 36028797018963968 1 1e55 18446744073709551615 0
|
||||
72057594037927940 72057594037927936 1 1e56 18446744073709551615 0
|
||||
144115188075855870 144115188075855872 1 1e57 18446744073709551615 0
|
||||
288230376151711740 288230376151711744 1 1e58 18446744073709551615 0
|
||||
576460752303423500 576460752303423488 1 1e59 18446744073709551615 0
|
||||
1152921504606847000 1152921504606846976 1 1e60 18446744073709551615 0
|
||||
2305843009213694000 2305843009213693952 1 1e61 18446744073709551615 0
|
||||
4611686018427388000 4611686018427387904 1 1e62 18446744073709551615 0
|
||||
9223372036854776000 9223372036854775808 1 1e63 18446744073709551615 0
|
||||
18446744073709552000 1 0 1e64 18446744073709551615 0
|
||||
36893488147419103000 2 0 1e65 18446744073709551615 0
|
||||
73786976294838210000 4 0 1e66 18446744073709551615 0
|
||||
147573952589676410000 8 0 1e67 18446744073709551615 0
|
||||
295147905179352830000 16 0 1e68 18446744073709551615 0
|
||||
590295810358705700000 32 0 1e69 18446744073709551615 0
|
1
dbms/tests/queries/0_stateless/00536_int_exp.sql
Normal file
1
dbms/tests/queries/0_stateless/00536_int_exp.sql
Normal file
@ -0,0 +1 @@
|
||||
SELECT exp2(number) AS e2d, intExp2(number) AS e2i, e2d = e2i AS e2eq, exp10(number) AS e10d, intExp10(number) AS e10i, e10d = e10i AS e10eq FROM system.numbers LIMIT 70;
|
@ -34,6 +34,7 @@ add_library (common
|
||||
include/common/LocalDateTime.h
|
||||
include/common/ErrorHandlers.h
|
||||
include/common/exp10.h
|
||||
include/common/intExp.h
|
||||
include/common/mremap.h
|
||||
include/common/likely.h
|
||||
include/common/logger_useful.h
|
||||
|
33
libs/libcommon/include/common/intExp.h
Normal file
33
libs/libcommon/include/common/intExp.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
|
||||
/// On overlow, the function returns unspecified value.
|
||||
|
||||
inline uint64_t intExp2(int x)
|
||||
{
|
||||
return 1ULL << x;
|
||||
}
|
||||
|
||||
inline uint64_t intExp10(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
return 0;
|
||||
if (x > 19)
|
||||
return std::numeric_limits<uint64_t>::max();
|
||||
|
||||
static const uint64_t table[20] =
|
||||
{
|
||||
1ULL, 10ULL, 100ULL,
|
||||
1000ULL, 10000ULL, 100000ULL,
|
||||
1000000ULL, 10000000ULL, 100000000ULL,
|
||||
1000000000ULL, 10000000000ULL, 100000000000ULL,
|
||||
1000000000000ULL, 10000000000000ULL, 100000000000000ULL,
|
||||
1000000000000000ULL, 10000000000000000ULL, 100000000000000000ULL,
|
||||
1000000000000000000ULL, 10000000000000000000ULL
|
||||
};
|
||||
|
||||
return table[x];
|
||||
}
|
Loading…
Reference in New Issue
Block a user