mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 10:02:01 +00:00
updated
This commit is contained in:
parent
8e16db7060
commit
10daacb18f
@ -9,7 +9,7 @@ Selects the first encountered value, similar to `any`, but could accept NULL.
|
|||||||
|
|
||||||
## examples
|
## examples
|
||||||
|
|
||||||
```sq;
|
```sql
|
||||||
insert into test_data (a,b) values (1,null), (2,3), (4, 5), (6,null)
|
insert into test_data (a,b) values (1,null), (2,3), (4, 5), (6,null)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Selects the last encountered value, similar to `anyLast`, but could accept NULL.
|
|||||||
|
|
||||||
## examples
|
## examples
|
||||||
|
|
||||||
```sq;
|
```sql
|
||||||
insert into test_data (a,b) values (1,null), (2,3), (4, 5), (6,null)
|
insert into test_data (a,b) values (1,null), (2,3), (4, 5), (6,null)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -14,11 +14,12 @@ AggregateFunctionPtr createAggregateFunctionAny(const std::string & name, const
|
|||||||
return AggregateFunctionPtr(createAggregateFunctionSingleValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData>(name, argument_types, parameters, settings));
|
return AggregateFunctionPtr(createAggregateFunctionSingleValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData>(name, argument_types, parameters, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool RespectNulls = false, bool NullIsGreater = false>
|
template <bool RespectNulls = false>
|
||||||
AggregateFunctionPtr createAggregateFunctionNullableAny(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
AggregateFunctionPtr createAggregateFunctionNullableAny(
|
||||||
|
const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||||
{
|
{
|
||||||
return AggregateFunctionPtr(
|
return AggregateFunctionPtr(
|
||||||
createAggregateFunctionSingleNullableValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData, RespectNulls, NullIsGreater>(
|
createAggregateFunctionSingleNullableValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData, RespectNulls>(
|
||||||
name, argument_types, parameters, settings));
|
name, argument_types, parameters, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,14 +28,13 @@ AggregateFunctionPtr createAggregateFunctionAnyLast(const std::string & name, co
|
|||||||
return AggregateFunctionPtr(createAggregateFunctionSingleValue<AggregateFunctionsSingleValue, AggregateFunctionAnyLastData>(name, argument_types, parameters, settings));
|
return AggregateFunctionPtr(createAggregateFunctionSingleValue<AggregateFunctionsSingleValue, AggregateFunctionAnyLastData>(name, argument_types, parameters, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool RespectNulls = false, bool NullIsGreater = false>
|
template <bool RespectNulls = false>
|
||||||
AggregateFunctionPtr createAggregateFunctionNullableAnyLast(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
AggregateFunctionPtr createAggregateFunctionNullableAnyLast(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||||
{
|
{
|
||||||
return AggregateFunctionPtr(createAggregateFunctionSingleNullableValue<
|
return AggregateFunctionPtr(createAggregateFunctionSingleNullableValue<
|
||||||
AggregateFunctionsSingleValue,
|
AggregateFunctionsSingleValue,
|
||||||
AggregateFunctionAnyLastData,
|
AggregateFunctionAnyLastData,
|
||||||
RespectNulls,
|
RespectNulls>(name, argument_types, parameters, settings));
|
||||||
NullIsGreater>(name, argument_types, parameters, settings));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionPtr createAggregateFunctionAnyHeavy(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
AggregateFunctionPtr createAggregateFunctionAnyHeavy(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||||
@ -59,18 +59,12 @@ void registerAggregateFunctionsAny(AggregateFunctionFactory & factory)
|
|||||||
factory.registerFunction("first_value_respect_nulls",
|
factory.registerFunction("first_value_respect_nulls",
|
||||||
{ createAggregateFunctionNullableAny<true>, properties },
|
{ createAggregateFunctionNullableAny<true>, properties },
|
||||||
AggregateFunctionFactory::CaseInsensitive);
|
AggregateFunctionFactory::CaseInsensitive);
|
||||||
factory.registerFunction("first_value_ignore_nulls",
|
|
||||||
{ createAggregateFunctionNullableAny<false>, properties },
|
|
||||||
AggregateFunctionFactory::CaseInsensitive);
|
|
||||||
factory.registerFunction("last_value",
|
factory.registerFunction("last_value",
|
||||||
{ createAggregateFunctionAnyLast, properties },
|
{ createAggregateFunctionAnyLast, properties },
|
||||||
AggregateFunctionFactory::CaseInsensitive);
|
AggregateFunctionFactory::CaseInsensitive);
|
||||||
factory.registerFunction("last_value_respect_nulls",
|
factory.registerFunction("last_value_respect_nulls",
|
||||||
{ createAggregateFunctionNullableAnyLast<true>, properties },
|
{ createAggregateFunctionNullableAnyLast<true>, properties },
|
||||||
AggregateFunctionFactory::CaseInsensitive);
|
AggregateFunctionFactory::CaseInsensitive);
|
||||||
factory.registerFunction("last_value_ignore_nulls",
|
|
||||||
{ createAggregateFunctionNullableAnyLast<false>, properties },
|
|
||||||
AggregateFunctionFactory::CaseInsensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ AggregateFunctionPtr AggregateFunctionFactory::get(
|
|||||||
// nullability themselves. Another special case is functions from Nothing
|
// nullability themselves. Another special case is functions from Nothing
|
||||||
// that are rewritten to AggregateFunctionNothing, in this case
|
// that are rewritten to AggregateFunctionNothing, in this case
|
||||||
// nested_function is nullptr.
|
// nested_function is nullptr.
|
||||||
if ((!nested_function || !nested_function->isOnlyWindowFunction()))
|
if (!nested_function || !nested_function->isOnlyWindowFunction())
|
||||||
return combinator->transformAggregateFunction(nested_function, out_properties, types_without_low_cardinality, parameters);
|
return combinator->transformAggregateFunction(nested_function, out_properties, types_without_low_cardinality, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,7 +766,7 @@ static_assert(
|
|||||||
|
|
||||||
|
|
||||||
/// For any other value types.
|
/// For any other value types.
|
||||||
template <bool IS_NULLABLE = false, bool IS_NULL_GREATER = false>
|
template <bool IS_NULLABLE = false>
|
||||||
struct SingleValueDataGeneric
|
struct SingleValueDataGeneric
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -778,7 +778,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
static constexpr bool is_nullable = IS_NULLABLE;
|
static constexpr bool is_nullable = IS_NULLABLE;
|
||||||
static constexpr bool is_any = false;
|
static constexpr bool is_any = false;
|
||||||
static constexpr bool is_null_greater = IS_NULL_GREATER;
|
|
||||||
|
|
||||||
bool has() const
|
bool has() const
|
||||||
{
|
{
|
||||||
@ -881,26 +880,13 @@ public:
|
|||||||
{
|
{
|
||||||
Field new_value;
|
Field new_value;
|
||||||
column.get(row_num, new_value);
|
column.get(row_num, new_value);
|
||||||
if constexpr (!is_null_greater)
|
if (!value.isNull() && (new_value.isNull() || new_value < value))
|
||||||
{
|
{
|
||||||
if (!value.isNull() && (new_value.isNull() || new_value < value))
|
value = new_value;
|
||||||
{
|
return true;
|
||||||
value = new_value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if ((value.isNull() && !new_value.isNull()) || (!new_value.isNull() && new_value < value))
|
|
||||||
{
|
|
||||||
value = new_value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -928,24 +914,12 @@ public:
|
|||||||
change(to, arena);
|
change(to, arena);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if constexpr (!is_null_greater)
|
if (to.value.isNull() || (!value.isNull() && to.value < value))
|
||||||
{
|
{
|
||||||
if (to.value.isNull() || (!value.isNull() && to.value < value))
|
value = to.value;
|
||||||
{
|
return true;
|
||||||
value = to.value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((value.isNull() && !to.value.isNull()) || (!to.value.isNull() || to.value < value))
|
|
||||||
{
|
|
||||||
value = to.value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -972,24 +946,12 @@ public:
|
|||||||
{
|
{
|
||||||
Field new_value;
|
Field new_value;
|
||||||
column.get(row_num, new_value);
|
column.get(row_num, new_value);
|
||||||
if constexpr (is_null_greater)
|
if (!value.isNull() && (new_value.isNull() || value < new_value))
|
||||||
{
|
{
|
||||||
if (!value.isNull() && (new_value.isNull() || value < new_value))
|
value = new_value;
|
||||||
{
|
return true;
|
||||||
value = new_value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((value.isNull() && !new_value.isNull()) || (!new_value.isNull() && value < new_value))
|
|
||||||
{
|
|
||||||
value = new_value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1012,25 +974,12 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
if constexpr (is_nullable)
|
if constexpr (is_nullable)
|
||||||
{
|
{
|
||||||
if constexpr (is_null_greater)
|
if (!value.isNull() && (to.value.isNull() || value < to.value))
|
||||||
{
|
{
|
||||||
if (!value.isNull() && (to.value.isNull() || value < to.value))
|
value = to.value;
|
||||||
{
|
return true;
|
||||||
value = to.value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((value.isNull() && !to.value.isNull()) || (!to.value.isNull() && value < to.value))
|
|
||||||
{
|
|
||||||
value = to.value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -11,10 +11,6 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
|
||||||
{
|
|
||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
|
||||||
}
|
|
||||||
struct Settings;
|
struct Settings;
|
||||||
|
|
||||||
/// min, max, any, anyLast, anyHeavy, etc...
|
/// min, max, any, anyLast, anyHeavy, etc...
|
||||||
@ -51,29 +47,23 @@ static IAggregateFunction * createAggregateFunctionSingleValue(const String & na
|
|||||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<>>>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<>>>(argument_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class AggregateFunctionTemplate, template <typename> class Data, bool RespectNulls = false, bool NullIsGreater = false>
|
template <template <typename> class AggregateFunctionTemplate, template <typename> class Data, bool RespectNulls = false>
|
||||||
static IAggregateFunction * createAggregateFunctionSingleNullableValue(const String & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
static IAggregateFunction * createAggregateFunctionSingleNullableValue(const String & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||||
{
|
{
|
||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
assertUnary(name, argument_types);
|
assertUnary(name, argument_types);
|
||||||
if (parameters.size() > 2)
|
|
||||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "name's parameter size must not be larger then 2");
|
|
||||||
|
|
||||||
const DataTypePtr & argument_type = argument_types[0];
|
const DataTypePtr & argument_type = argument_types[0];
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
// if the resule value could be null(excluding the case that no row is matched),
|
// If the result value could be null (excluding the case that no row is matched),
|
||||||
// use SingleValueDataGeneric.
|
// use SingleValueDataGeneric.
|
||||||
if constexpr (!RespectNulls)
|
if constexpr (!RespectNulls)
|
||||||
{
|
{
|
||||||
return createAggregateFunctionSingleValue<AggregateFunctionTemplate, Data>(name, argument_types, Array(), settings);
|
return createAggregateFunctionSingleValue<AggregateFunctionTemplate, Data>(name, argument_types, Array(), settings);
|
||||||
}
|
}
|
||||||
else if constexpr (NullIsGreater)
|
|
||||||
{
|
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true, true>>>(argument_type);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true, false>>>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true>>>(argument_type);
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -1104,7 +1104,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NullsAction nulls_action = NullsAction::DEFAULT;
|
NullsAction nulls_action = NullsAction::EMPTY;
|
||||||
if (respect_nulls.ignore(pos, expected))
|
if (respect_nulls.ignore(pos, expected))
|
||||||
{
|
{
|
||||||
nulls_action = NullsAction::RESPECT_NULLS;
|
nulls_action = NullsAction::RESPECT_NULLS;
|
||||||
@ -1150,19 +1150,25 @@ private:
|
|||||||
|
|
||||||
enum NullsAction
|
enum NullsAction
|
||||||
{
|
{
|
||||||
DEFAULT = 0,
|
EMPTY = 0,
|
||||||
RESPECT_NULLS = 1,
|
RESPECT_NULLS = 1,
|
||||||
IGNORE_NULLS = 2,
|
IGNORE_NULLS = 2,
|
||||||
};
|
};
|
||||||
static String transformFunctionNameForRepectNulls(const String & original_function_name, NullsAction nulls_action)
|
static String transformFunctionNameForRepectNulls(const String & original_function_name, NullsAction nulls_action)
|
||||||
{
|
{
|
||||||
static std::unordered_map<String, std::vector<String>> renamed_functions_with_nulls = {
|
static std::unordered_map<String, std::vector<String>> renamed_functions_with_nulls = {
|
||||||
{"first_value", {"first_value_ignore_nulls", "first_value_respect_nulls", "first_value_ignore_nulls"}},
|
{"first_value", {"first_value", "first_value_respect_nulls", "first_value"}},
|
||||||
{"last_value", {"last_value_ignore_nulls", "last_value_respect_nulls", "last_value_ignore_nulls"}},
|
{"last_value", {"last_value", "last_value_respect_nulls", "last_value"}},
|
||||||
};
|
};
|
||||||
auto it = renamed_functions_with_nulls.find(original_function_name);
|
auto it = renamed_functions_with_nulls.find(original_function_name);
|
||||||
if (it == renamed_functions_with_nulls.end())
|
if (it == renamed_functions_with_nulls.end())
|
||||||
return original_function_name;
|
{
|
||||||
|
if (nulls_action == NullsAction::EMPTY)
|
||||||
|
return original_function_name;
|
||||||
|
else
|
||||||
|
throw Exception(
|
||||||
|
ErrorCodes::SYNTAX_ERROR, "Function {} does not support RESPECT NULLS or IGNORE NULLS", original_function_name);
|
||||||
|
}
|
||||||
return it->second[nulls_action];
|
return it->second[nulls_action];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user