mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Separate first_value and first_value_respect_nulls states
This commit is contained in:
parent
b10e46b2bc
commit
a3e342a477
@ -50,22 +50,19 @@ void registerAggregateFunctionsAny(AggregateFunctionFactory & factory)
|
||||
|
||||
factory.registerFunction("any", { createAggregateFunctionAny, properties });
|
||||
factory.registerAlias("any_value", "any", AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerAlias("first_value", "any", AggregateFunctionFactory::CaseInsensitive);
|
||||
|
||||
factory.registerFunction("any_respect_nulls", {createAggregateFunctionNullableAny<true>, properties});
|
||||
factory.registerAlias("any_value_respect_nulls", "any_respect_nulls", AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerAlias("first_value_respect_nulls", "any_respect_nulls", AggregateFunctionFactory::CaseInsensitive);
|
||||
|
||||
factory.registerFunction("anyLast", { createAggregateFunctionAnyLast, properties });
|
||||
factory.registerFunction("anyHeavy", { createAggregateFunctionAnyHeavy, properties });
|
||||
factory.registerAlias("last_value", "anyLast", AggregateFunctionFactory::CaseInsensitive);
|
||||
|
||||
// Synonyms for use as window functions.
|
||||
factory.registerFunction("first_value",
|
||||
{ createAggregateFunctionAny, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("first_value_respect_nulls",
|
||||
{ createAggregateFunctionNullableAny<true>, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("last_value",
|
||||
{ createAggregateFunctionAnyLast, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("last_value_respect_nulls",
|
||||
{ createAggregateFunctionNullableAnyLast<true>, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("anyLast_respect_nulls", {createAggregateFunctionNullableAnyLast<true>, properties});
|
||||
factory.registerAlias("last_value_respect_nulls", "anyLast_respect_nulls", AggregateFunctionFactory::CaseInsensitive);
|
||||
|
||||
factory.registerFunction("anyHeavy", {createAggregateFunctionAnyHeavy, properties});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1084,7 +1084,7 @@ struct AggregateFunctionMaxData : Data
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename Data>
|
||||
template <typename Data, bool RespectNulls = false>
|
||||
struct AggregateFunctionAnyData : Data
|
||||
{
|
||||
using Self = AggregateFunctionAnyData;
|
||||
@ -1094,7 +1094,13 @@ struct AggregateFunctionAnyData : Data
|
||||
bool changeIfBetter(const Self & to, Arena * arena) { return this->changeFirstTime(to, arena); }
|
||||
void addManyDefaults(const IColumn & column, size_t /*length*/, Arena * arena) { this->changeFirstTime(column, 0, arena); }
|
||||
|
||||
static const char * name() { return "any"; }
|
||||
static const char * name()
|
||||
{
|
||||
if constexpr (RespectNulls)
|
||||
return "any_respect_nulls";
|
||||
else
|
||||
return "any";
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
@ -1113,7 +1119,7 @@ struct AggregateFunctionAnyData : Data
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename Data>
|
||||
template <typename Data, bool RespectNulls = false>
|
||||
struct AggregateFunctionAnyLastData : Data
|
||||
{
|
||||
using Self = AggregateFunctionAnyLastData;
|
||||
@ -1122,7 +1128,13 @@ struct AggregateFunctionAnyLastData : Data
|
||||
bool changeIfBetter(const Self & to, Arena * arena) { return this->changeEveryTime(to, arena); }
|
||||
void addManyDefaults(const IColumn & column, size_t /*length*/, Arena * arena) { this->changeEveryTime(column, 0, arena); }
|
||||
|
||||
static const char * name() { return "anyLast"; }
|
||||
static const char * name()
|
||||
{
|
||||
if constexpr (RespectNulls)
|
||||
return "anyLast_respect_nulls";
|
||||
else
|
||||
return "anyLast";
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
|
||||
|
@ -14,8 +14,9 @@ namespace DB
|
||||
struct Settings;
|
||||
|
||||
/// min, max, any, anyLast, anyHeavy, etc...
|
||||
template <template <typename> class AggregateFunctionTemplate, template <typename> class Data>
|
||||
static IAggregateFunction * createAggregateFunctionSingleValue(const String & name, const DataTypes & argument_types, const Array & parameters, const Settings *)
|
||||
template <template <typename> class AggregateFunctionTemplate, template <typename, bool...> class Data>
|
||||
static IAggregateFunction *
|
||||
createAggregateFunctionSingleValue(const String & name, const DataTypes & argument_types, const Array & parameters, const Settings *)
|
||||
{
|
||||
assertNoParameters(name, parameters);
|
||||
assertUnary(name, argument_types);
|
||||
@ -47,8 +48,9 @@ static IAggregateFunction * createAggregateFunctionSingleValue(const String & na
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<>>>(argument_type);
|
||||
}
|
||||
|
||||
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)
|
||||
template <template <typename> class AggregateFunctionTemplate, template <typename, bool> class Data, bool RespectNulls = false>
|
||||
static IAggregateFunction * createAggregateFunctionSingleNullableValue(
|
||||
const String & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||
{
|
||||
assertNoParameters(name, parameters);
|
||||
assertUnary(name, argument_types);
|
||||
@ -63,7 +65,7 @@ static IAggregateFunction * createAggregateFunctionSingleNullableValue(const Str
|
||||
}
|
||||
else
|
||||
{
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true>>>(argument_type);
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true>, RespectNulls>>(argument_type);
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1138,7 +1138,8 @@ public:
|
||||
{
|
||||
nulls_action = NullsAction::IGNORE_NULLS;
|
||||
}
|
||||
function_node->name = transformFunctionNameForRepectNulls(function_node->name, nulls_action);
|
||||
if (nulls_action == NullsAction::RESPECT_NULLS)
|
||||
function_node->name = transformFunctionNameForRespectNulls(function_node->name, nulls_action);
|
||||
|
||||
if (over.ignore(pos, expected))
|
||||
{
|
||||
@ -1179,11 +1180,14 @@ private:
|
||||
RESPECT_NULLS = 1,
|
||||
IGNORE_NULLS = 2,
|
||||
};
|
||||
static String transformFunctionNameForRepectNulls(const String & original_function_name, NullsAction nulls_action)
|
||||
static String transformFunctionNameForRespectNulls(const String & original_function_name, NullsAction nulls_action)
|
||||
{
|
||||
static std::unordered_map<String, std::vector<String>> renamed_functions_with_nulls = {
|
||||
{"first_value", {"first_value", "first_value_respect_nulls", "first_value"}},
|
||||
{"last_value", {"last_value", "last_value_respect_nulls", "last_value"}},
|
||||
static std::unordered_map<String, String> renamed_functions_with_nulls = {
|
||||
{"any", "any_respect_nulls"},
|
||||
{"any_value", "any_respect_nulls"},
|
||||
{"first_value", "any_respect_nulls"},
|
||||
{"anyLast", "anyLast_respect_nulls"},
|
||||
{"last_value", "anyLast_respect_nulls"},
|
||||
};
|
||||
auto it = renamed_functions_with_nulls.find(original_function_name);
|
||||
if (it == renamed_functions_with_nulls.end())
|
||||
@ -1191,10 +1195,9 @@ private:
|
||||
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);
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Function {} does not support RESPECT NULLS", original_function_name);
|
||||
}
|
||||
return it->second[nulls_action];
|
||||
return it->second;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
AggregateFunction(any_respect_nulls, UInt8) AggregateFunction(anyLast_respect_nulls, UInt8)
|
||||
0
|
||||
\N
|
||||
0
|
||||
\N
|
||||
0
|
||||
\N
|
||||
4
|
||||
\N
|
||||
\N
|
15
tests/queries/0_stateless/02922_respect_nulls_states.sql
Normal file
15
tests/queries/0_stateless/02922_respect_nulls_states.sql
Normal file
@ -0,0 +1,15 @@
|
||||
SELECT toTypeName(first_value_respect_nullsState(dummy)), toTypeName(last_value_respect_nullsState(dummy)) from system.one;
|
||||
|
||||
SELECT first_value_respect_nullsMerge(t) FROM (Select first_value_respect_nullsState(dummy) as t FROM system.one);
|
||||
SELECT first_value_respect_nullsMerge(t) FROM (Select first_value_respect_nullsState(NULL::Nullable(UInt8)) as t FROM system.one);
|
||||
SELECT first_value_respect_nullsMerge(t) FROM (Select first_value_respect_nullsState(number) as t FROM numbers(5));
|
||||
SELECT first_value_respect_nullsMerge(t) FROM (Select first_value_respect_nullsState(NULL::Nullable(UInt8)) as t FROM numbers(5));
|
||||
|
||||
SELECT last_value_respect_nullsMerge(t) FROM (Select last_value_respect_nullsState(dummy) as t FROM system.one);
|
||||
SELECT last_value_respect_nullsMerge(t) FROM (Select last_value_respect_nullsState(NULL::Nullable(UInt8)) as t FROM system.one);
|
||||
SELECT last_value_respect_nullsMerge(t) FROM (Select last_value_respect_nullsState(number) as t FROM numbers(5));
|
||||
SELECT last_value_respect_nullsMerge(t) FROM (Select last_value_respect_nullsState(NULL::Nullable(UInt8)) as t FROM numbers(5));
|
||||
|
||||
SELECT first_value_respect_nullsMerge(t) FROM (Select first_valueState(number) as t from numbers(0)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT first_value_respect_nullsMerge(CAST(unhex('00'), 'AggregateFunction(any, UInt64)')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT first_value_respect_nullsMerge(CAST(unhex('00'), 'AggregateFunction(any_respect_nulls, UInt64)'));
|
Loading…
Reference in New Issue
Block a user