mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Making Monotonicity an aggregate to use with designated initializers
This commit is contained in:
parent
340fb049cf
commit
61e0c6208b
@ -130,20 +130,17 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const override
|
||||
{
|
||||
IFunction::Monotonicity is_monotonic{true};
|
||||
IFunction::Monotonicity is_not_monotonic;
|
||||
if constexpr (std::is_same_v<typename Transform::FactorTransform, ZeroTransform>)
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
if (std::is_same_v<typename Transform::FactorTransform, ZeroTransform>)
|
||||
{
|
||||
is_monotonic.is_always_monotonic = true;
|
||||
return is_monotonic;
|
||||
}
|
||||
const IFunction::Monotonicity is_monotonic = { .is_monotonic = true };
|
||||
const IFunction::Monotonicity is_not_monotonic;
|
||||
|
||||
/// This method is called only if the function has one argument. Therefore, we do not care about the non-local time zone.
|
||||
const DateLUTImpl & date_lut = DateLUT::instance();
|
||||
|
||||
if (left.isNull() || right.isNull())
|
||||
return is_not_monotonic;
|
||||
return {};
|
||||
|
||||
/// The function is monotonous on the [left, right] segment, if the factor transformation returns the same values for them.
|
||||
|
||||
|
@ -128,14 +128,11 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const override
|
||||
{
|
||||
IFunction::Monotonicity is_monotonic { true };
|
||||
IFunction::Monotonicity is_not_monotonic;
|
||||
if constexpr (std::is_same_v<typename Transform::FactorTransform, ZeroTransform>)
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
if (std::is_same_v<typename Transform::FactorTransform, ZeroTransform>)
|
||||
{
|
||||
is_monotonic.is_always_monotonic = true;
|
||||
return is_monotonic;
|
||||
}
|
||||
const IFunction::Monotonicity is_monotonic = { .is_monotonic = true };
|
||||
const IFunction::Monotonicity is_not_monotonic;
|
||||
|
||||
/// This method is called only if the function has one argument. Therefore, we do not care about the non-local time zone.
|
||||
const DateLUTImpl & date_lut = DateLUT::instance();
|
||||
|
@ -290,7 +290,7 @@ struct PositiveMonotonicity
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const Field &, const Field &)
|
||||
{
|
||||
return { true };
|
||||
return { .is_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1954,7 +1954,7 @@ struct PositiveMonotonicity
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const IDataType &, const Field &, const Field &)
|
||||
{
|
||||
return { true };
|
||||
return { .is_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
@ -1963,7 +1963,7 @@ struct UnknownMonotonicity
|
||||
static bool has() { return false; }
|
||||
static IFunction::Monotonicity get(const IDataType &, const Field &, const Field &)
|
||||
{
|
||||
return { false };
|
||||
return { };
|
||||
}
|
||||
};
|
||||
|
||||
@ -1989,13 +1989,13 @@ struct ToNumberMonotonicity
|
||||
/// (Enum has separate case, because it is different data type)
|
||||
if (checkAndGetDataType<DataTypeNumber<T>>(&type) ||
|
||||
checkAndGetDataType<DataTypeEnum<T>>(&type))
|
||||
return { true, true, true };
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
/// Float cases.
|
||||
|
||||
/// When converting to Float, the conversion is always monotonic.
|
||||
if (std::is_floating_point_v<T>)
|
||||
return {true, true, true};
|
||||
if constexpr (std::is_floating_point_v<T>)
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
/// If converting from Float, for monotonicity, arguments must fit in range of result type.
|
||||
if (WhichDataType(type).isFloat())
|
||||
@ -2010,7 +2010,7 @@ struct ToNumberMonotonicity
|
||||
&& left_float <= static_cast<Float64>(std::numeric_limits<T>::max())
|
||||
&& right_float >= static_cast<Float64>(std::numeric_limits<T>::min())
|
||||
&& right_float <= static_cast<Float64>(std::numeric_limits<T>::max()))
|
||||
return { true };
|
||||
return { .is_monotonic = true };
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -2035,10 +2035,10 @@ struct ToNumberMonotonicity
|
||||
if (size_of_from == size_of_to)
|
||||
{
|
||||
if (from_is_unsigned == to_is_unsigned)
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
if (left_in_first_half == right_in_first_half)
|
||||
return {true};
|
||||
return { .is_monotonic = true };
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -2047,14 +2047,14 @@ struct ToNumberMonotonicity
|
||||
if (size_of_from < size_of_to)
|
||||
{
|
||||
if (from_is_unsigned == to_is_unsigned)
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
if (!to_is_unsigned)
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
/// signed -> unsigned. If arguments from the same half, then function is monotonic.
|
||||
if (left_in_first_half == right_in_first_half)
|
||||
return {true};
|
||||
return { .is_monotonic = true };
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -2071,10 +2071,14 @@ struct ToNumberMonotonicity
|
||||
return {};
|
||||
|
||||
if (to_is_unsigned)
|
||||
return {true};
|
||||
return { .is_monotonic = true };
|
||||
else
|
||||
{
|
||||
// If To is signed, it's possible that the signedness is different after conversion. So we check it explicitly.
|
||||
return {(T(left.get<UInt64>()) >= 0) == (T(right.get<UInt64>()) >= 0)};
|
||||
const bool is_monotonic = (T(left.get<UInt64>()) >= 0) == (T(right.get<UInt64>()) >= 0);
|
||||
|
||||
return { .is_monotonic = is_monotonic };
|
||||
}
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
@ -2089,7 +2093,7 @@ struct ToDateMonotonicity
|
||||
{
|
||||
auto which = WhichDataType(type);
|
||||
if (which.isDateOrDate32() || which.isDateTime() || which.isDateTime64() || which.isInt8() || which.isInt16() || which.isUInt8() || which.isUInt16())
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
else if (
|
||||
(which.isUInt() && ((left.isNull() || left.get<UInt64>() < 0xFFFF) && (right.isNull() || right.get<UInt64>() >= 0xFFFF)))
|
||||
|| (which.isInt() && ((left.isNull() || left.get<Int64>() < 0xFFFF) && (right.isNull() || right.get<Int64>() >= 0xFFFF)))
|
||||
@ -2097,7 +2101,7 @@ struct ToDateMonotonicity
|
||||
|| !type.isValueRepresentedByNumber())
|
||||
return {};
|
||||
else
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
@ -2108,7 +2112,7 @@ struct ToDateTimeMonotonicity
|
||||
static IFunction::Monotonicity get(const IDataType & type, const Field &, const Field &)
|
||||
{
|
||||
if (type.isValueRepresentedByNumber())
|
||||
return {true, true, true};
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
else
|
||||
return {};
|
||||
}
|
||||
@ -2123,7 +2127,7 @@ struct ToStringMonotonicity
|
||||
|
||||
static IFunction::Monotonicity get(const IDataType & type, const Field & left, const Field & right)
|
||||
{
|
||||
IFunction::Monotonicity positive(true, true);
|
||||
IFunction::Monotonicity positive{ .is_monotonic = true };
|
||||
IFunction::Monotonicity not_monotonic;
|
||||
|
||||
const auto * type_ptr = &type;
|
||||
|
@ -614,7 +614,7 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType &, const Field &, const Field &) const override
|
||||
{
|
||||
return { true, true, true };
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -250,12 +250,9 @@ public:
|
||||
/// The property of monotonicity for a certain range.
|
||||
struct Monotonicity
|
||||
{
|
||||
bool is_monotonic = false; /// Is the function monotonous (nondecreasing or nonincreasing).
|
||||
bool is_positive = true; /// true if the function is nondecreasing, false, if notincreasing. If is_monotonic = false, then it does not matter.
|
||||
bool is_monotonic = false; /// Is the function monotonous (non-decreasing or non-increasing).
|
||||
bool is_positive = true; /// true if the function is non-decreasing, false if non-increasing. If is_monotonic = false, then it does not matter.
|
||||
bool is_always_monotonic = false; /// Is true if function is monotonic on the whole input range I
|
||||
|
||||
Monotonicity(bool is_monotonic_ = false, bool is_positive_ = true, bool is_always_monotonic_ = false)
|
||||
: is_monotonic(is_monotonic_), is_positive(is_positive_), is_always_monotonic(is_always_monotonic_) {}
|
||||
};
|
||||
|
||||
/** Get information about monotonicity on a range of values. Call only if hasInformationAboutMonotonicity.
|
||||
|
@ -46,7 +46,7 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameAbs>
|
||||
if ((left_float < 0 && right_float > 0) || (left_float > 0 && right_float < 0))
|
||||
return {};
|
||||
|
||||
return { true, (left_float > 0) };
|
||||
return { .is_monotonic = true, .is_positive = left_float > 0 };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -143,7 +143,7 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType &, const Field &, const Field &) const override
|
||||
{
|
||||
return { true, true, true };
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -139,10 +139,7 @@ namespace DB
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType &, const Field &, const Field &) const override
|
||||
{
|
||||
return Monotonicity(
|
||||
true, // is_monotonic
|
||||
true, // is_positive
|
||||
true); // is_always_monotonic
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -55,7 +55,7 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameIntExp10>
|
||||
if (left_float < 0 || right_float > 19)
|
||||
return {};
|
||||
|
||||
return { true };
|
||||
return { .is_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,7 +58,7 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameIntExp2>
|
||||
if (left_float < 0 || right_float > 63)
|
||||
return {};
|
||||
|
||||
return { true };
|
||||
return { .is_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameNegate>
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const Field &, const Field &)
|
||||
{
|
||||
return { true, false };
|
||||
return { .is_monotonic = true, .is_positive = false };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,10 @@ template <>
|
||||
struct FunctionUnaryArithmeticMonotonicity<NameSign>
|
||||
{
|
||||
static bool has() { return true; }
|
||||
static IFunction::Monotonicity get(const Field &, const Field &) { return {true, true, false}; }
|
||||
static IFunction::Monotonicity get(const Field &, const Field &)
|
||||
{
|
||||
return { .is_monotonic = true };
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionSign(FunctionFactory & factory)
|
||||
|
@ -157,10 +157,7 @@ namespace DB
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType &, const Field &, const Field &) const override
|
||||
{
|
||||
return Monotonicity(
|
||||
true, // is_monotonic
|
||||
true, // is_positive
|
||||
true); // is_always_monotonic
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -311,7 +311,7 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType &, const Field &, const Field &) const override
|
||||
{
|
||||
return { true, true, true };
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -66,7 +66,8 @@ public:
|
||||
|
||||
Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const override
|
||||
{
|
||||
return {is_constant_timezone, is_constant_timezone, is_constant_timezone};
|
||||
const bool b = is_constant_timezone;
|
||||
return { .is_monotonic = b, .is_positive = b, .is_always_monotonic = b };
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -239,7 +239,9 @@ public:
|
||||
const IDataType * type_ptr = &type;
|
||||
Field left_mut = left;
|
||||
Field right_mut = right;
|
||||
Monotonicity result(true, true, true);
|
||||
|
||||
Monotonicity result = { .is_monotonic = true, .is_positive = true, .is_always_monotonic = true };
|
||||
|
||||
/// monotonicity is only defined for unary functions, so the chain must describe a sequence of nested calls
|
||||
for (size_t i = 0; i < nested_functions.size(); ++i)
|
||||
{
|
||||
|
@ -28,7 +28,9 @@ public:
|
||||
const TablesWithColumns & tables;
|
||||
ContextPtr context;
|
||||
const std::unordered_set<String> & group_by_function_hashes;
|
||||
Monotonicity monotonicity{true, true, true};
|
||||
|
||||
Monotonicity monotonicity = { .is_monotonic = true, .is_positive = true, .is_always_monotonic = true };
|
||||
|
||||
ASTIdentifier * identifier = nullptr;
|
||||
DataTypePtr arg_data_type = {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user