This is an automated email from the ASF dual-hosted git repository.
panxiaolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 7e364ebeec6 [env](compiler)Reduce window function template
instantiations (#61232)
7e364ebeec6 is described below
commit 7e364ebeec6a123737c5037862eaf9137937d2b8
Author: Mryange <[email protected]>
AuthorDate: Wed Apr 1 09:58:45 2026 +0800
[env](compiler)Reduce window function template instantiations (#61232)
1. **Remove `ColVecType` from window-path Data types** (`LeadLagData`,
`FirstLastData`, `NthValueData`): The window path enters via virtual
`IAggregateFunction*`, so devirtualizing `insert_from` is pointless. Use
`IColumn::insert_from` virtual call instead. Reader path (CRTP batch
loop) keeps `ColVecType`.
2. **Move `ColVecType` from class-level to function-level** on
`Value`/`CopiedValue`: Only `insert_into` needs it; other members
(`reset`, `is_null`, `set_value`) no longer get 24× instantiated.
3. **Use `void` as marker type**: `FirstLastData` inherits
`ReaderFirstAndLastData<void, ...>`. `if constexpr
(std::is_same_v<ColVecType, void>)` selects virtual vs devirtualized
path at compile time.
4. **Lift `arg_ignore_null` to compile-time**: The old runtime `if`
inside the 24-type switch doubled instantiations. Now dispatched at
registration via lambda.
5. **Delete the 300-line type switch**: Replaced by
`CREATE_WINDOW_FUNCTION_DIRECT` macro that directly instantiates 4
combinations (2×2).
## Compile time (single-thread -j1)
Before
```
[1/7] Compiling: be/src/exprs/aggregate/aggregate_function_window.cpp
→ 25.9s
[2/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_first.cpp
→ 60.5s
[3/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_funnel.cpp
→ 19.6s
[4/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lag.cpp
→ 60.6s
[5/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_last.cpp
→ 63.9s
[6/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lead.cpp
→ 69.1s
[7/7] Compiling:
be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
→ 74.5s
```
Now
```
[1/7] Compiling: be/src/exprs/aggregate/aggregate_function_window.cpp
→ 25.4s
[2/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_first.cpp
→ 24.4s
[3/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_funnel.cpp
→ 19.3s
[4/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lag.cpp
→ 24.4s
[5/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_last.cpp
→ 25.1s
[6/7] Compiling: be/src/exprs/aggregate/aggregate_function_window_lead.cpp
→ 24.9s
[7/7] Compiling:
be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
→ 25.2s
```
---
.../aggregate_function_reader_first_last.h | 44 ++-
.../exprs/aggregate/aggregate_function_window.cpp | 38 ++-
be/src/exprs/aggregate/aggregate_function_window.h | 16 +-
.../aggregate/aggregate_function_window_first.cpp | 7 +-
.../aggregate/aggregate_function_window_impl.h | 346 ++-------------------
.../aggregate/aggregate_function_window_lag.cpp | 4 +-
.../aggregate/aggregate_function_window_last.cpp | 7 +-
.../aggregate/aggregate_function_window_lead.cpp | 4 +-
.../aggregate_function_window_nth_value.cpp | 7 +-
be/test/exprs/aggregate/agg_replace_test.cpp | 20 +-
10 files changed, 133 insertions(+), 360 deletions(-)
diff --git a/be/src/exprs/aggregate/aggregate_function_reader_first_last.h
b/be/src/exprs/aggregate/aggregate_function_reader_first_last.h
index 33fc9d55749..4a2caaee43f 100644
--- a/be/src/exprs/aggregate/aggregate_function_reader_first_last.h
+++ b/be/src/exprs/aggregate/aggregate_function_reader_first_last.h
@@ -17,6 +17,8 @@
#pragma once
+#include <type_traits>
+
#include "core/column/column_array.h"
#include "core/column/column_map.h"
#include "core/column/column_nullable.h"
@@ -32,7 +34,7 @@
namespace doris {
#include "common/compile_check_begin.h"
-template <typename ColVecType, bool arg_is_nullable>
+template <bool arg_is_nullable>
struct Value {
public:
bool is_null() const {
@@ -46,6 +48,7 @@ public:
return false;
}
+ template <typename ColVecType>
void insert_into(IColumn& to) const {
if constexpr (arg_is_nullable) {
const auto* col = assert_cast<const ColumnNullable*,
TypeCheckOnRelease::DISABLE>(_ptr);
@@ -56,6 +59,17 @@ public:
}
}
+ // Non-template version: virtual dispatch on IColumn::insert_from.
+ // Used by window path where devirtualization is not beneficial.
+ void insert_into(IColumn& to) const {
+ if constexpr (arg_is_nullable) {
+ const auto* col = assert_cast<const ColumnNullable*,
TypeCheckOnRelease::DISABLE>(_ptr);
+ to.insert_from(col->get_nested_column(), _offset);
+ } else {
+ to.insert_from(*_ptr, _offset);
+ }
+ }
+
void set_value(const IColumn* column, size_t row) {
_ptr = column;
_offset = row;
@@ -71,15 +85,17 @@ protected:
size_t _offset = 0;
};
-template <typename ColVecType, bool arg_is_nullable>
-struct CopiedValue : public Value<ColVecType, arg_is_nullable> {
+template <bool arg_is_nullable>
+struct CopiedValue : public Value<arg_is_nullable> {
public:
+ template <typename ColVecType>
void insert_into(IColumn& to) const {
assert_cast<ColVecType&,
TypeCheckOnRelease::DISABLE>(to).insert(_copied_value);
}
bool is_null() const { return this->_ptr == nullptr; }
+ template <typename ColVecType>
void set_value(const IColumn* column, size_t row) {
// here _ptr, maybe null at row, so call reset to set nullptr
// But we will use is_null() check first, others have set _ptr column
to a meaningless address
@@ -108,8 +124,8 @@ private:
template <typename ColVecType, bool result_is_nullable, bool arg_is_nullable,
bool is_copy>
struct ReaderFirstAndLastData {
public:
- using StoreType = std::conditional_t<is_copy, CopiedValue<ColVecType,
arg_is_nullable>,
- Value<ColVecType, arg_is_nullable>>;
+ using StoreType =
+ std::conditional_t<is_copy, CopiedValue<arg_is_nullable>,
Value<arg_is_nullable>>;
static constexpr bool nullable = arg_is_nullable;
static constexpr bool result_nullable = result_is_nullable;
@@ -126,17 +142,29 @@ public:
} else {
auto& col = assert_cast<ColumnNullable&>(to);
col.get_null_map_data().push_back(0);
- _data_value.insert_into(col.get_nested_column());
+ if constexpr (!std::is_same_v<ColVecType, void>) {
+ _data_value.template
insert_into<ColVecType>(col.get_nested_column());
+ } else {
+ _data_value.insert_into(col.get_nested_column());
+ }
}
} else {
- _data_value.insert_into(to);
+ if constexpr (!std::is_same_v<ColVecType, void>) {
+ _data_value.template insert_into<ColVecType>(to);
+ } else {
+ _data_value.insert_into(to);
+ }
}
}
// here not check the columns[0] is null at the row,
// but it is need to check in other
void set_value(const IColumn** columns, size_t pos) {
- _data_value.set_value(columns[0], pos);
+ if constexpr (is_copy) {
+ _data_value.template set_value<ColVecType>(columns[0], pos);
+ } else {
+ _data_value.set_value(columns[0], pos);
+ }
_has_value = true;
}
diff --git a/be/src/exprs/aggregate/aggregate_function_window.cpp
b/be/src/exprs/aggregate/aggregate_function_window.cpp
index 01e35bb999a..41bbebdf0c8 100644
--- a/be/src/exprs/aggregate/aggregate_function_window.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window.cpp
@@ -49,11 +49,17 @@ AggregateFunctionPtr
create_aggregate_function_window_first(const std::string& n
const DataTypePtr&
result_type,
const bool
result_is_nullable,
const
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_first_ignore_null(
+ const std::string& name, const DataTypes& argument_types, const
DataTypePtr& result_type,
+ const bool result_is_nullable, const AggregateFunctionAttr& attr);
AggregateFunctionPtr create_aggregate_function_window_last(const std::string&
name,
const DataTypes&
argument_types,
const DataTypePtr&
result_type,
const bool
result_is_nullable,
const
AggregateFunctionAttr& attr);
+AggregateFunctionPtr create_aggregate_function_window_last_ignore_null(
+ const std::string& name, const DataTypes& argument_types, const
DataTypePtr& result_type,
+ const bool result_is_nullable, const AggregateFunctionAttr& attr);
AggregateFunctionPtr create_aggregate_function_window_nth_value(const
std::string& name,
const
DataTypes& argument_types,
const
DataTypePtr& result_type,
@@ -89,8 +95,36 @@ void register_aggregate_function_window_lead_lag_first_last(
AggregateFunctionSimpleFactory& factory) {
factory.register_function_both("lead",
create_aggregate_function_window_lead);
factory.register_function_both("lag",
create_aggregate_function_window_lag);
- factory.register_function_both("first_value",
create_aggregate_function_window_first);
- factory.register_function_both("last_value",
create_aggregate_function_window_last);
+ // FE rewrites first_value(k1, false) → first_value(k1), so
argument_types.size() == 2
+ // means arg_ignore_null = true. Dispatch at registration to avoid runtime
branching
+ // that would double template instantiations.
+ factory.register_function_both(
+ "first_value",
+ [](const std::string& name, const DataTypes& argument_types,
+ const DataTypePtr& result_type, const bool result_is_nullable,
+ const AggregateFunctionAttr& attr) -> AggregateFunctionPtr {
+ if (argument_types.size() == 2) {
+ return create_aggregate_function_window_first_ignore_null(
+ name, argument_types, result_type,
result_is_nullable, attr);
+ }
+ return create_aggregate_function_window_first(name,
argument_types, result_type,
+
result_is_nullable, attr);
+ });
+ factory.register_function_both(
+ "last_value",
+ [](const std::string& name, const DataTypes& argument_types,
+ const DataTypePtr& result_type, const bool result_is_nullable,
+ const AggregateFunctionAttr& attr) -> AggregateFunctionPtr {
+ if (argument_types.size() == 2) {
+ return create_aggregate_function_window_last_ignore_null(
+ name, argument_types, result_type,
result_is_nullable, attr);
+ }
+ return create_aggregate_function_window_last(name,
argument_types, result_type,
+
result_is_nullable, attr);
+ });
+ // nth_value always has 2 args (column, N) from FE.
+ // WindowFunctionNthValueImpl does not implement ignore-null logic,
+ // so register directly without dispatch.
factory.register_function_both("nth_value",
create_aggregate_function_window_nth_value);
}
diff --git a/be/src/exprs/aggregate/aggregate_function_window.h
b/be/src/exprs/aggregate/aggregate_function_window.h
index fe7556c47b6..9b654c77ff5 100644
--- a/be/src/exprs/aggregate/aggregate_function_window.h
+++ b/be/src/exprs/aggregate/aggregate_function_window.h
@@ -397,15 +397,15 @@ public:
void deserialize(AggregateDataPtr place, BufferReadable& buf, Arena&)
const override {}
};
-template <typename ColVecType, bool result_is_nullable, bool arg_is_nullable>
+template <bool result_is_nullable, bool arg_is_nullable>
struct FirstLastData
- : public ReaderFirstAndLastData<ColVecType, result_is_nullable,
arg_is_nullable, false> {
+ : public ReaderFirstAndLastData<void, result_is_nullable,
arg_is_nullable, false> {
public:
void set_is_null() { this->_data_value.reset(); }
};
-template <typename ColVecType, bool result_is_nullable, bool arg_is_nullable>
-struct NthValueData : public FirstLastData<ColVecType, result_is_nullable,
arg_is_nullable> {
+template <bool result_is_nullable, bool arg_is_nullable>
+struct NthValueData : public FirstLastData<result_is_nullable,
arg_is_nullable> {
public:
void reset() {
this->_data_value.reset();
@@ -418,8 +418,8 @@ public:
int64_t _frame_total_rows = 0;
};
-template <typename ColVecType, bool arg_is_nullable>
-struct BaseValue : public Value<ColVecType, arg_is_nullable> {
+template <bool arg_is_nullable>
+struct BaseValue : public Value<arg_is_nullable> {
public:
bool is_null() const { return this->_ptr == nullptr; }
// because _ptr pointer to first_argument or third argument, so it's
difficult to cast ptr
@@ -427,7 +427,7 @@ public:
StringRef get_value() const { return
this->_ptr->get_data_at(this->_offset); }
};
-template <typename ColVecType, bool result_is_nullable, bool arg_is_nullable>
+template <bool result_is_nullable, bool arg_is_nullable>
struct LeadLagData {
public:
static constexpr bool result_nullable = result_is_nullable;
@@ -492,7 +492,7 @@ public:
int64_t get_offset_value() const { return _offset_value; }
private:
- BaseValue<ColVecType, arg_is_nullable> _data_value;
+ BaseValue<arg_is_nullable> _data_value;
bool _is_inited = false;
int64_t _offset_value = 0;
};
diff --git a/be/src/exprs/aggregate/aggregate_function_window_first.cpp
b/be/src/exprs/aggregate/aggregate_function_window_first.cpp
index 63b7054d5d4..79051c09665 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_first.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_first.cpp
@@ -20,8 +20,11 @@
namespace doris {
#include "common/compile_check_begin.h"
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_first,
FirstLastData,
- WindowFunctionFirstImpl);
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_first,
FirstLastData,
+ WindowFunctionFirstImpl, false);
+
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_first_ignore_null,
FirstLastData,
+ WindowFunctionFirstImpl, true);
#include "common/compile_check_end.h"
} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_impl.h
b/be/src/exprs/aggregate/aggregate_function_window_impl.h
index c3f6f0d4033..09fbb199736 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_impl.h
+++ b/be/src/exprs/aggregate/aggregate_function_window_impl.h
@@ -29,328 +29,30 @@
namespace doris {
#include "common/compile_check_begin.h"
-template <template <typename> class AggregateFunctionTemplate,
- template <typename ColVecType, bool, bool> class Data,
- template <typename, bool> class Impl, bool result_is_nullable, bool
arg_is_nullable>
-AggregateFunctionPtr create_function_lead_lag_first_last(const String& name,
- const DataTypes&
argument_types) {
- bool arg_ignore_null_value = false;
- // FE have rewrite case first_value(k1,false)--->first_value(k1)
- // so size is 2, must will be arg_ignore_null_value
- if (argument_types.size() == 2) {
- DCHECK(name == "first_value" || name == "last_value" || name ==
"nth_value")
- << "invalid function name: " << name;
- arg_ignore_null_value = true;
- }
- switch (argument_types[0]->get_primitive_type()) {
- case PrimitiveType::TYPE_BOOLEAN: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnUInt8, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnUInt8, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_TINYINT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt8, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt8, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_SMALLINT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt16, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt16, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_INT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt32, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt32, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_BIGINT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt64, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt64, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_LARGEINT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt128, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnInt128, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_FLOAT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnFloat32, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnFloat32, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DOUBLE: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnFloat64, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnFloat64, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DECIMAL32: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal32, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal32, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DECIMAL64: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal64, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal64, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DECIMAL128I: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal128V3, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal128V3, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DECIMALV2: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal128V2, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal128V2, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DECIMAL256: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal256, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDecimal256, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_STRING:
- case PrimitiveType::TYPE_CHAR:
- case PrimitiveType::TYPE_VARCHAR:
- case PrimitiveType::TYPE_JSONB: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnString, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnString, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DATETIMEV2: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDateTimeV2, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDateTimeV2, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_DATEV2: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDateV2, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnDateV2, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_IPV4: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnIPv4, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnIPv4, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_IPV6: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnIPv6, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnIPv6, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_ARRAY: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnArray, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnArray, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_MAP: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnMap, result_is_nullable, arg_is_nullable>,
true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnMap, result_is_nullable, arg_is_nullable>,
false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_STRUCT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnStruct, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnStruct, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_VARIANT: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnVariant, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnVariant, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_BITMAP: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnBitmap, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnBitmap, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_HLL: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnHLL, result_is_nullable, arg_is_nullable>,
true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnHLL, result_is_nullable, arg_is_nullable>,
false>>>(
- argument_types);
- }
- }
- case PrimitiveType::TYPE_QUANTILE_STATE: {
- if (arg_ignore_null_value) {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnQuantileState, result_is_nullable,
arg_is_nullable>, true>>>(
- argument_types);
- } else {
- return std::make_shared<AggregateFunctionTemplate<
- Impl<Data<ColumnQuantileState, result_is_nullable,
arg_is_nullable>, false>>>(
- argument_types);
- }
- }
- default:
- LOG(WARNING) << "with unknowed type, failed in
create_aggregate_function_" << name
- << " and type is: " << argument_types[0]->get_name();
- return nullptr;
- }
-}
-
-#define CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(CREATE_FUNCTION_NAME,
FUNCTION_DATA, \
- FUNCTION_IMPL)
\
- AggregateFunctionPtr CREATE_FUNCTION_NAME(
\
- const std::string& name, const DataTypes& argument_types,
\
- const DataTypePtr& result_type, const bool result_is_nullable,
\
- const AggregateFunctionAttr& attr) {
\
- const bool arg_is_nullable = argument_types[0]->is_nullable();
\
- AggregateFunctionPtr res = nullptr;
\
-
\
- std::visit(
\
- [&](auto result_is_nullable, auto arg_is_nullable) {
\
- res = AggregateFunctionPtr(
\
-
create_function_lead_lag_first_last<WindowFunctionData, FUNCTION_DATA, \
- FUNCTION_IMPL,
result_is_nullable, \
-
arg_is_nullable>(name, \
-
argument_types)); \
- },
\
- make_bool_variant(result_is_nullable),
make_bool_variant(arg_is_nullable)); \
- if (!res) {
\
- LOG(WARNING) << " failed in create_aggregate_function_" << name
\
- << " and type is: " << argument_types[0]->get_name();
\
- }
\
- return res;
\
+// All window-path Data types (LeadLagData, FirstLastData, NthValueData) no
longer have
+// ColVecType template parameter. Direct instantiation with only
(result_is_nullable, arg_is_nullable).
+// ARG_IGNORE_NULL is a compile-time bool for first_value/last_value
ignore-null variants.
+#define CREATE_WINDOW_FUNCTION_DIRECT(CREATE_FUNCTION_NAME, FUNCTION_DATA,
FUNCTION_IMPL, \
+ ARG_IGNORE_NULL)
\
+ AggregateFunctionPtr CREATE_FUNCTION_NAME(
\
+ const std::string& name, const DataTypes& argument_types,
\
+ const DataTypePtr& result_type, const bool result_is_nullable,
\
+ const AggregateFunctionAttr& attr) {
\
+ const bool arg_is_nullable = argument_types[0]->is_nullable();
\
+ AggregateFunctionPtr res = nullptr;
\
+
\
+ std::visit(
\
+ [&](auto result_is_nullable, auto arg_is_nullable) {
\
+ res = std::make_shared<WindowFunctionData<
\
+ FUNCTION_IMPL<FUNCTION_DATA<result_is_nullable,
arg_is_nullable>, \
+ ARG_IGNORE_NULL>>>(argument_types);
\
+ },
\
+ make_bool_variant(result_is_nullable),
make_bool_variant(arg_is_nullable)); \
+ if (!res) {
\
+ LOG(WARNING) << " failed in create_aggregate_function_" << name
\
+ << " and type is: " << argument_types[0]->get_name();
\
+ }
\
+ return res;
\
}
#include "common/compile_check_end.h"
diff --git a/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
b/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
index 73b7af57cfa..ab7d0c2ab16 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_lag.cpp
@@ -20,8 +20,8 @@
namespace doris {
#include "common/compile_check_begin.h"
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lag,
LeadLagData,
- WindowFunctionLagImpl);
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_lag,
LeadLagData,
+ WindowFunctionLagImpl, false);
#include "common/compile_check_end.h"
} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_last.cpp
b/be/src/exprs/aggregate/aggregate_function_window_last.cpp
index 7b864404817..18bb98d4052 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_last.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_last.cpp
@@ -20,8 +20,11 @@
namespace doris {
#include "common/compile_check_begin.h"
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_last,
FirstLastData,
- WindowFunctionLastImpl);
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_last,
FirstLastData,
+ WindowFunctionLastImpl, false);
+
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_last_ignore_null,
FirstLastData,
+ WindowFunctionLastImpl, true);
#include "common/compile_check_end.h"
} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
b/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
index dacf7e51e29..4739acc485c 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_lead.cpp
@@ -20,8 +20,8 @@
namespace doris {
#include "common/compile_check_begin.h"
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_lead,
LeadLagData,
- WindowFunctionLeadImpl);
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_lead,
LeadLagData,
+ WindowFunctionLeadImpl, false);
#include "common/compile_check_end.h"
} // namespace doris
diff --git a/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
b/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
index d2efa2144fb..9ce84cfb76a 100644
--- a/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
+++ b/be/src/exprs/aggregate/aggregate_function_window_nth_value.cpp
@@ -20,8 +20,11 @@
namespace doris {
#include "common/compile_check_begin.h"
-CREATE_WINDOW_FUNCTION_WITH_NAME_AND_DATA(create_aggregate_function_window_nth_value,
NthValueData,
- WindowFunctionNthValueImpl);
+// nth_value always has 2 args (column, N) from FE.
+// WindowFunctionNthValueImpl does not implement ignore-null logic,
+// so always use false.
+CREATE_WINDOW_FUNCTION_DIRECT(create_aggregate_function_window_nth_value,
NthValueData,
+ WindowFunctionNthValueImpl, false);
#include "common/compile_check_end.h"
} // namespace doris
diff --git a/be/test/exprs/aggregate/agg_replace_test.cpp
b/be/test/exprs/aggregate/agg_replace_test.cpp
index 0b082e8c658..a0e90ede1cf 100644
--- a/be/test/exprs/aggregate/agg_replace_test.cpp
+++ b/be/test/exprs/aggregate/agg_replace_test.cpp
@@ -313,7 +313,7 @@ public:
EXPECT_EQ(input_nums, data_column->size());
//test Value
{
- Value<ColumnType, nullable> value;
+ Value<nullable> value;
EXPECT_TRUE(value.is_null());
for (int64_t i = 0; i < input_nums; ++i) {
value.set_value(data_column.get(), i);
@@ -332,17 +332,17 @@ public:
}
//test CopiedValue
{
- CopiedValue<ColumnType, nullable> value;
+ CopiedValue<nullable> value;
EXPECT_TRUE(value.is_null());
for (int64_t i = 0; i < input_nums; ++i) {
- value.set_value(data_column.get(), i);
+ value.template set_value<ColumnType>(data_column.get(), i);
EXPECT_FALSE(value.is_null());
auto to_column = data_type->create_column();
if constexpr (nullable) {
auto& nullable_col =
assert_cast<ColumnNullable&>(*to_column);
- value.insert_into(nullable_col.get_nested_column());
+ value.template
insert_into<ColumnType>(nullable_col.get_nested_column());
} else {
- value.insert_into(*to_column);
+ value.template insert_into<ColumnType>(*to_column);
}
EXPECT_EQ(1, to_column->size());
check_column_basic<DataType, nullable>(to_column.get(), i);
@@ -360,7 +360,7 @@ public:
EXPECT_EQ(input_nums + 1, data_column->size());
//test Value
{
- Value<ColumnArray, nullable> value;
+ Value<nullable> value;
EXPECT_TRUE(value.is_null());
for (int64_t i = 0; i <= input_nums; ++i) {
value.set_value(data_column.get(), i);
@@ -378,17 +378,17 @@ public:
}
//test CopiedValue
{
- CopiedValue<ColumnArray, nullable> value;
+ CopiedValue<nullable> value;
EXPECT_TRUE(value.is_null());
for (int64_t i = 0; i <= input_nums; ++i) {
- value.set_value(data_column.get(), i);
+ value.template set_value<ColumnArray>(data_column.get(), i);
EXPECT_FALSE(value.is_null());
auto to_column = data_type->create_column();
if constexpr (nullable) {
auto& nullable_col =
assert_cast<ColumnNullable&>(*to_column);
- value.insert_into(nullable_col.get_nested_column());
+ value.template
insert_into<ColumnArray>(nullable_col.get_nested_column());
} else {
- value.insert_into(*to_column);
+ value.template insert_into<ColumnArray>(*to_column);
}
EXPECT_EQ(1, to_column->size());
check_column_array<DataType, nullable>(to_column.get(), i);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]