mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 16:12: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
|
||||
|
||||
```sq;
|
||||
```sql
|
||||
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
|
||||
|
||||
```sq;
|
||||
```sql
|
||||
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));
|
||||
}
|
||||
|
||||
template <bool RespectNulls = false, bool NullIsGreater = false>
|
||||
AggregateFunctionPtr createAggregateFunctionNullableAny(const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||
template <bool RespectNulls = false>
|
||||
AggregateFunctionPtr createAggregateFunctionNullableAny(
|
||||
const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings * settings)
|
||||
{
|
||||
return AggregateFunctionPtr(
|
||||
createAggregateFunctionSingleNullableValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData, RespectNulls, NullIsGreater>(
|
||||
createAggregateFunctionSingleNullableValue<AggregateFunctionsSingleValue, AggregateFunctionAnyData, RespectNulls>(
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return AggregateFunctionPtr(createAggregateFunctionSingleNullableValue<
|
||||
AggregateFunctionsSingleValue,
|
||||
AggregateFunctionAnyLastData,
|
||||
RespectNulls,
|
||||
NullIsGreater>(name, argument_types, parameters, settings));
|
||||
RespectNulls>(name, argument_types, parameters, 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",
|
||||
{ createAggregateFunctionNullableAny<true>, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("first_value_ignore_nulls",
|
||||
{ createAggregateFunctionNullableAny<false>, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("last_value",
|
||||
{ createAggregateFunctionAnyLast, properties },
|
||||
AggregateFunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction("last_value_respect_nulls",
|
||||
{ createAggregateFunctionNullableAnyLast<true>, properties },
|
||||
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
|
||||
// that are rewritten to AggregateFunctionNothing, in this case
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -766,7 +766,7 @@ static_assert(
|
||||
|
||||
|
||||
/// For any other value types.
|
||||
template <bool IS_NULLABLE = false, bool IS_NULL_GREATER = false>
|
||||
template <bool IS_NULLABLE = false>
|
||||
struct SingleValueDataGeneric
|
||||
{
|
||||
private:
|
||||
@ -778,7 +778,6 @@ private:
|
||||
public:
|
||||
static constexpr bool is_nullable = IS_NULLABLE;
|
||||
static constexpr bool is_any = false;
|
||||
static constexpr bool is_null_greater = IS_NULL_GREATER;
|
||||
|
||||
bool has() const
|
||||
{
|
||||
@ -881,26 +880,13 @@ public:
|
||||
{
|
||||
Field 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;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
value = new_value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value.isNull() && !new_value.isNull()) || (!new_value.isNull() && new_value < value))
|
||||
{
|
||||
value = new_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -928,24 +914,12 @@ public:
|
||||
change(to, arena);
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value.isNull() && !to.value.isNull()) || (!to.value.isNull() || to.value < value))
|
||||
{
|
||||
value = to.value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
value = to.value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -972,24 +946,12 @@ public:
|
||||
{
|
||||
Field 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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value.isNull() && !new_value.isNull()) || (!new_value.isNull() && value < new_value))
|
||||
{
|
||||
value = new_value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
value = new_value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1012,25 +974,12 @@ public:
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value.isNull() && !to.value.isNull()) || (!to.value.isNull() && value < to.value))
|
||||
{
|
||||
value = to.value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
value = to.value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11,10 +11,6 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
}
|
||||
struct Settings;
|
||||
|
||||
/// min, max, any, anyLast, anyHeavy, etc...
|
||||
@ -51,29 +47,23 @@ 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, 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)
|
||||
{
|
||||
assertNoParameters(name, parameters);
|
||||
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];
|
||||
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.
|
||||
if constexpr (!RespectNulls)
|
||||
{
|
||||
return createAggregateFunctionSingleValue<AggregateFunctionTemplate, Data>(name, argument_types, Array(), settings);
|
||||
}
|
||||
else if constexpr (NullIsGreater)
|
||||
{
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true, true>>>(argument_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true, false>>>(argument_type);
|
||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric<true>>>(argument_type);
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1104,7 +1104,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
NullsAction nulls_action = NullsAction::DEFAULT;
|
||||
NullsAction nulls_action = NullsAction::EMPTY;
|
||||
if (respect_nulls.ignore(pos, expected))
|
||||
{
|
||||
nulls_action = NullsAction::RESPECT_NULLS;
|
||||
@ -1150,19 +1150,25 @@ private:
|
||||
|
||||
enum NullsAction
|
||||
{
|
||||
DEFAULT = 0,
|
||||
EMPTY = 0,
|
||||
RESPECT_NULLS = 1,
|
||||
IGNORE_NULLS = 2,
|
||||
};
|
||||
static String transformFunctionNameForRepectNulls(const String & original_function_name, NullsAction nulls_action)
|
||||
{
|
||||
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"}},
|
||||
{"last_value", {"last_value_ignore_nulls", "last_value_respect_nulls", "last_value_ignore_nulls"}},
|
||||
{"first_value", {"first_value", "first_value_respect_nulls", "first_value"}},
|
||||
{"last_value", {"last_value", "last_value_respect_nulls", "last_value"}},
|
||||
};
|
||||
auto it = renamed_functions_with_nulls.find(original_function_name);
|
||||
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];
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user