This is an automated email from the ASF dual-hosted git repository.

lihaopeng pushed a commit to branch vectorized
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git

commit 990723c15b346f0838314e53c8138e574176a5b9
Author: zhangstar333 <87313068+zhangstar...@users.noreply.github.com>
AuthorDate: Thu Jan 13 20:27:34 2022 +0800

    [Vectorized][Function] Support function 
stddev/variance/stddev_samp/variance_samp (#7734)
---
 be/src/exprs/aggregate_functions.cpp               |   2 +-
 be/src/vec/CMakeLists.txt                          |   1 +
 .../vec/aggregate_functions/aggregate_function.h   |   5 +
 .../aggregate_functions/aggregate_function_null.h  |   9 +-
 .../aggregate_function_simple_factory.cpp          |   6 +-
 .../aggregate_function_simple_factory.h            |  20 +-
 .../aggregate_function_stddev.cpp                  | 101 ++++++++
 .../aggregate_function_stddev.h                    | 285 +++++++++++++++++++++
 .../java/org/apache/doris/catalog/FunctionSet.java |  68 +++++
 9 files changed, 486 insertions(+), 11 deletions(-)

diff --git a/be/src/exprs/aggregate_functions.cpp 
b/be/src/exprs/aggregate_functions.cpp
index a22c3ee..93166cf 100644
--- a/be/src/exprs/aggregate_functions.cpp
+++ b/be/src/exprs/aggregate_functions.cpp
@@ -1874,8 +1874,8 @@ static double compute_knuth_variance(const 
KnuthVarianceState& state, bool pop)
 static DecimalV2Value decimalv2_compute_knuth_variance(const 
DecimalV2KnuthVarianceState& state,
                                                        bool pop) {
     DecimalV2Value new_count = DecimalV2Value();
-    new_count.assign_from_double(state.count);
     if (state.count == 1) return new_count;
+    new_count.assign_from_double(state.count);
     DecimalV2Value new_m2 = DecimalV2Value::from_decimal_val(state.m2);
     if (pop)
         return new_m2 / new_count;
diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt
index aa302ce..9c4d947 100644
--- a/be/src/vec/CMakeLists.txt
+++ b/be/src/vec/CMakeLists.txt
@@ -31,6 +31,7 @@ set(VEC_FILES
   aggregate_functions/aggregate_function_bitmap.cpp
   aggregate_functions/aggregate_function_reader.cpp
   aggregate_functions/aggregate_function_window.cpp
+  aggregate_functions/aggregate_function_stddev.cpp
   aggregate_functions/aggregate_function_simple_factory.cpp
   columns/collator.cpp
   columns/column.cpp
diff --git a/be/src/vec/aggregate_functions/aggregate_function.h 
b/be/src/vec/aggregate_functions/aggregate_function.h
index 412382f..4c2ef36 100644
--- a/be/src/vec/aggregate_functions/aggregate_function.h
+++ b/be/src/vec/aggregate_functions/aggregate_function.h
@@ -114,6 +114,11 @@ public:
       */
     virtual bool is_state() const { return false; }
 
+    /// if return false, during insert_result_into function, you colud get 
nullable result column, 
+    /// so could insert to null value by yourself, rather than by 
AggregateFunctionNullBase;
+    /// because you maybe be calculate a invalid value, but want to use null 
replace it;
+    virtual bool insert_to_null_default() const { return true; }
+
     /** The inner loop that uses the function pointer is better than using the 
virtual function.
       * The reason is that in the case of virtual functions GCC 5.1.2 
generates code,
       *  which, at each iteration of the loop, reloads the function address 
(the offset value in the virtual function table) from memory to the register.
diff --git a/be/src/vec/aggregate_functions/aggregate_function_null.h 
b/be/src/vec/aggregate_functions/aggregate_function_null.h
index 4c61e2b..9458d7d 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_null.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_null.h
@@ -144,9 +144,12 @@ public:
         if constexpr (result_is_nullable) {
             ColumnNullable& to_concrete = assert_cast<ColumnNullable&>(to);
             if (get_flag(place)) {
-                nested_function->insert_result_into(nested_place(place),
-                                                    
to_concrete.get_nested_column());
-                to_concrete.get_null_map_data().push_back(0);
+                if (nested_function->insert_to_null_default()) {
+                    nested_function->insert_result_into(nested_place(place), 
to_concrete.get_nested_column());
+                    to_concrete.get_null_map_data().push_back(0);
+                } else {
+                    nested_function->insert_result_into(nested_place(place), 
to);  //want to insert into null value by self
+                }
             } else {
                 to_concrete.insert_default();
             }
diff --git 
a/be/src/vec/aggregate_functions/aggregate_function_simple_factory.cpp 
b/be/src/vec/aggregate_functions/aggregate_function_simple_factory.cpp
index 8a1995b..ba1b2ba 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_simple_factory.cpp
+++ b/be/src/vec/aggregate_functions/aggregate_function_simple_factory.cpp
@@ -35,6 +35,7 @@ void 
register_aggregate_function_combinator_distinct(AggregateFunctionSimpleFact
 void register_aggregate_function_bitmap(AggregateFunctionSimpleFactory& 
factory);
 void register_aggregate_function_window_rank(AggregateFunctionSimpleFactory& 
factory);
 void 
register_aggregate_function_window_lead_lag(AggregateFunctionSimpleFactory& 
factory);
+void 
register_aggregate_function_stddev_variance(AggregateFunctionSimpleFactory& 
factory);
 AggregateFunctionSimpleFactory& AggregateFunctionSimpleFactory::instance() {
     static std::once_flag oc;
     static AggregateFunctionSimpleFactory instance;
@@ -49,10 +50,11 @@ AggregateFunctionSimpleFactory& 
AggregateFunctionSimpleFactory::instance() {
         register_aggregate_function_HLL_union_agg(instance);
         register_aggregate_function_reader(instance); // register aggregate 
function for agg reader
         register_aggregate_function_window_rank(instance);
-
+        register_aggregate_function_stddev_variance(instance);
+        
         // if you only register function with no nullable, and wants to add 
nullable automatically, you should place function above this line
         register_aggregate_function_combinator_null(instance);
-
+        
         register_aggregate_function_reader_no_spread(instance);
         register_aggregate_function_window_lead_lag(instance);
     });
diff --git a/be/src/vec/aggregate_functions/aggregate_function_simple_factory.h 
b/be/src/vec/aggregate_functions/aggregate_function_simple_factory.h
index d12c27a..1bac4f1 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_simple_factory.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_simple_factory.h
@@ -45,7 +45,7 @@ private:
 
     AggregateFunctions aggregate_functions;
     AggregateFunctions nullable_aggregate_functions;
-
+    std::unordered_map<std::string, std::string> function_alias;
 public:
     void register_nullable_function_combinator(const Creator& creator) {
         for (const auto& entity : aggregate_functions) {
@@ -77,15 +77,21 @@ public:
                 nullable = true;
             }
         }
+
+        std::string name_str = name;
+        if (function_alias.count(name)) {
+            name_str = function_alias[name];
+        }
+
         if (nullable) {
-            return nullable_aggregate_functions.find(name) == 
nullable_aggregate_functions.end()
+            return nullable_aggregate_functions.find(name_str) == 
nullable_aggregate_functions.end()
                            ? nullptr
-                           : nullable_aggregate_functions[name](name, 
argument_types, parameters,
+                           : nullable_aggregate_functions[name_str](name_str, 
argument_types, parameters,
                                                                 
result_is_nullable);
         } else {
-            return aggregate_functions.find(name) == aggregate_functions.end()
+            return aggregate_functions.find(name_str) == 
aggregate_functions.end()
                            ? nullptr
-                           : aggregate_functions[name](name, argument_types, 
parameters,
+                           : aggregate_functions[name_str](name_str, 
argument_types, parameters,
                                                        result_is_nullable);
         }
     }
@@ -98,6 +104,10 @@ public:
         }
     }
 
+    void register_alias(const std::string& name, const std::string& alias) {
+        function_alias[alias] = name;
+    }
+
 public:
     static AggregateFunctionSimpleFactory& instance();
 };
diff --git a/be/src/vec/aggregate_functions/aggregate_function_stddev.cpp 
b/be/src/vec/aggregate_functions/aggregate_function_stddev.cpp
new file mode 100644
index 0000000..f1794d6
--- /dev/null
+++ b/be/src/vec/aggregate_functions/aggregate_function_stddev.cpp
@@ -0,0 +1,101 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "vec/aggregate_functions/aggregate_function_stddev.h"
+
+#include "common/logging.h"
+#include "vec/aggregate_functions/aggregate_function_simple_factory.h"
+#include "vec/aggregate_functions/factory_helpers.h"
+#include "vec/aggregate_functions/helpers.h"
+namespace doris::vectorized {
+
+template <template <typename> class AggregateFunctionTemplate, template 
<typename> class NameData,
+          template <typename, typename> class Data, bool is_stddev>
+static IAggregateFunction* create_function_single_value(const String& name,
+                                                        const DataTypes& 
argument_types,
+                                                        const Array& 
parameters) {
+    auto type = argument_types[0].get();
+    if (type->is_nullable()) {
+        type = assert_cast<const 
DataTypeNullable*>(type)->get_nested_type().get();
+    }
+    WhichDataType which(*type);
+
+#define DISPATCH(TYPE)                                                         
                \
+    if (which.idx == TypeIndex::TYPE)                                          
                \
+        return new AggregateFunctionTemplate<NameData<Data<TYPE, 
BaseData<TYPE, is_stddev>>>>( \
+                argument_types);
+    FOR_NUMERIC_TYPES(DISPATCH)
+#undef DISPATCH
+    if (which.is_decimal()) {
+        return new AggregateFunctionTemplate<
+                NameData<Data<Decimal128, 
BaseDatadecimal<is_stddev>>>>(argument_types);
+    }
+    DCHECK(false) << "with unknowed type, failed in  
create_aggregate_function_stddev_variance";
+    return nullptr;
+}
+
+template <bool is_stddev>
+AggregateFunctionPtr create_aggregate_function_variance_samp(const 
std::string& name,
+                                                             const DataTypes& 
argument_types,
+                                                             const Array& 
parameters,
+                                                             const bool 
result_is_nullable) {
+    return AggregateFunctionPtr(
+            create_function_single_value<AggregateFunctionStddevSamp, 
VarianceSampData, SampData,
+                                         is_stddev>(name, argument_types, 
parameters));
+}
+
+template <bool is_stddev>
+AggregateFunctionPtr create_aggregate_function_stddev_samp(const std::string& 
name,
+                                                           const DataTypes& 
argument_types,
+                                                           const Array& 
parameters,
+                                                           const bool 
result_is_nullable) {
+    return AggregateFunctionPtr(
+            create_function_single_value<AggregateFunctionStddevSamp, 
StddevSampData, SampData,
+                                         is_stddev>(name, argument_types, 
parameters));
+}
+
+template <bool is_stddev>
+AggregateFunctionPtr create_aggregate_function_variance_pop(const std::string& 
name,
+                                                            const DataTypes& 
argument_types,
+                                                            const Array& 
parameters,
+                                                            const bool 
result_is_nullable) {
+    return AggregateFunctionPtr(
+            create_function_single_value<AggregateFunctionStddevSamp, 
VarianceData, PopData,
+                                         is_stddev>(name, argument_types, 
parameters));
+}
+
+template <bool is_stddev>
+AggregateFunctionPtr create_aggregate_function_stddev_pop(const std::string& 
name,
+                                                          const DataTypes& 
argument_types,
+                                                          const Array& 
parameters,
+                                                          const bool 
result_is_nullable) {
+    return AggregateFunctionPtr(
+            create_function_single_value<AggregateFunctionStddevSamp, 
StddevData, PopData,
+                                         is_stddev>(name, argument_types, 
parameters));
+}
+
+void 
register_aggregate_function_stddev_variance(AggregateFunctionSimpleFactory& 
factory) {
+    factory.register_function("variance_samp", 
create_aggregate_function_variance_samp<false>);
+    factory.register_function("variance", 
create_aggregate_function_variance_pop<false>);
+    factory.register_alias("variance_samp", "var_samp");
+    factory.register_alias("variance", "var_pop");
+    factory.register_alias("variance", "variance_pop");
+    factory.register_function("stddev_samp", 
create_aggregate_function_stddev_samp<true>);
+    factory.register_function("stddev", 
create_aggregate_function_stddev_pop<true>);
+    factory.register_alias("stddev", "stddev_pop");
+}
+} // namespace doris::vectorized
\ No newline at end of file
diff --git a/be/src/vec/aggregate_functions/aggregate_function_stddev.h 
b/be/src/vec/aggregate_functions/aggregate_function_stddev.h
new file mode 100644
index 0000000..6cdba200
--- /dev/null
+++ b/be/src/vec/aggregate_functions/aggregate_function_stddev.h
@@ -0,0 +1,285 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "common/status.h"
+#include "vec/aggregate_functions/aggregate_function.h"
+#include "vec/columns/columns_number.h"
+#include "vec/data_types/data_type_decimal.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/io/io_helper.h"
+namespace doris::vectorized {
+
+template <typename T, bool is_stddev>
+struct BaseData {
+    BaseData() : mean(0.0), m2(0.0), count(0) {}
+
+    void write(BufferWritable& buf) const {
+        write_binary(mean, buf);
+        write_binary(m2, buf);
+        write_binary(count, buf);
+    }
+
+    void read(BufferReadable& buf) {
+        read_binary(mean, buf);
+        read_binary(m2, buf);
+        read_binary(count, buf);
+    }
+
+    void reset() {
+        mean = 0.0;
+        m2 = 0.0;
+        count = 0;
+    }
+
+    double get_result(double res) const {
+        if constexpr (is_stddev) {
+            return std::sqrt(res);
+        } else {
+            return res;
+        }
+    }
+
+    double get_pop_result() const {
+        if (count == 1) {
+            return 0.0;
+        }
+        double res = m2 / count;
+        return get_result(res);
+    }
+
+    double get_samp_result() const {
+        double res = m2 / (count - 1);
+        return get_result(res);
+    }
+
+    static const DataTypePtr get_return_type() {
+        return make_nullable(std::make_shared<DataTypeNumber<Float64>>());
+    }
+
+    void merge(const BaseData& rhs) {
+        if (rhs.count == 0) {
+            return;
+        }
+        double delta = mean - rhs.mean;
+        double sum_count = count + rhs.count;
+        mean = rhs.mean + delta * count / sum_count;
+        m2 = rhs.m2 + m2 + (delta * delta) * rhs.count * count / sum_count;
+        count = sum_count;
+    }
+
+    void add(const IColumn** columns, size_t row_num) {
+        const auto& sources = static_cast<const ColumnVector<T>&>(*columns[0]);
+        double source_data = sources.get_data()[row_num];
+
+        double delta = source_data - mean;
+        double r = delta / (1 + count);
+        mean += r;
+        m2 += count * delta * r;
+        count += 1;
+    }
+
+    double mean;
+    double m2;
+    int64_t count;
+};
+
+template <bool is_stddev>
+struct BaseDatadecimal {
+    BaseDatadecimal() : mean(0), m2(0), count(0) {}
+
+    void write(BufferWritable& buf) const {
+        write_binary(mean, buf);
+        write_binary(m2, buf);
+        write_binary(count, buf);
+    }
+
+    void read(BufferReadable& buf) {
+        read_binary(mean, buf);
+        read_binary(m2, buf);
+        read_binary(count, buf);
+    }
+
+    void reset() {
+        mean = DecimalV2Value();
+        m2 = DecimalV2Value();
+        count = {};
+    }
+
+    DecimalV2Value get_result(DecimalV2Value res) const {
+        if constexpr (is_stddev) {
+            return DecimalV2Value::sqrt(res);
+        } else {
+            return res;
+        }
+    }
+
+    DecimalV2Value get_pop_result() const {
+        DecimalV2Value new_count = DecimalV2Value();
+        if (count == 1) {
+            return new_count;
+        }
+        DecimalV2Value res = m2 / new_count.assign_from_double(count);
+        return get_result(res);
+    }
+
+    DecimalV2Value get_samp_result() const {
+        DecimalV2Value new_count = DecimalV2Value();
+        DecimalV2Value res = m2 / new_count.assign_from_double(count - 1);
+        return get_result(res);
+    }
+
+    static const DataTypePtr get_return_type() {
+        return make_nullable(std::make_shared<DataTypeDecimal<Decimal128>>(27, 
9));
+    }
+
+    void merge(const BaseDatadecimal& rhs) {
+        if (rhs.count == 0) {
+            return;
+        }
+        DecimalV2Value new_count = DecimalV2Value();
+        new_count.assign_from_double(count);
+        DecimalV2Value rhs_count = DecimalV2Value();
+        rhs_count.assign_from_double(rhs.count);
+
+        DecimalV2Value delta = mean - rhs.mean;
+        DecimalV2Value sum_count = new_count + rhs_count;
+        mean = rhs.mean + delta * (new_count / sum_count);
+        m2 = rhs.m2 + m2 + (delta * delta) * (rhs_count * new_count / 
sum_count);
+        count += rhs.count;
+    }
+
+    void add(const IColumn** columns, size_t row_num) {
+        DecimalV2Value source_data = DecimalV2Value();
+        const auto& sources = static_cast<const 
ColumnDecimal<Decimal128>&>(*columns[0]);
+        source_data = (DecimalV2Value)sources.get_data()[row_num];
+
+        DecimalV2Value new_count = DecimalV2Value();
+        new_count.assign_from_double(count);
+        DecimalV2Value increase_count = DecimalV2Value();
+        increase_count.assign_from_double(1 + count);
+
+        DecimalV2Value delta = source_data - mean;
+        DecimalV2Value r = delta / increase_count;
+        mean += r;
+        m2 += new_count * delta * r;
+        count += 1;
+    }
+
+    DecimalV2Value mean;
+    DecimalV2Value m2;
+    int64_t count;
+};
+
+template <typename T, typename Data>
+struct PopData : Data {
+    using ColVecResult = std::conditional_t<IsDecimalNumber<T>, 
ColumnDecimal<Decimal128>, ColumnVector<Float64>>;
+    void insert_result_into(IColumn& to) const {
+        ColumnNullable& nullable_column = assert_cast<ColumnNullable&>(to);
+        auto& col = 
static_cast<ColVecResult&>(nullable_column.get_nested_column());
+        if constexpr (IsDecimalNumber<T>) {
+            col.get_data().push_back(this->get_pop_result().value());
+        } else {
+            col.get_data().push_back(this->get_pop_result());
+        }
+        nullable_column.get_null_map_data().push_back(0);
+    }
+};
+
+template <typename T, typename Data>
+struct SampData : Data {
+    using ColVecResult = std::conditional_t<IsDecimalNumber<T>, 
ColumnDecimal<Decimal128>, ColumnVector<Float64>>;
+    void insert_result_into(IColumn& to) const {
+        ColumnNullable& nullable_column = assert_cast<ColumnNullable&>(to);
+        if (this->count == 1) {
+            nullable_column.insert_default();
+        } else {
+            auto& col = 
static_cast<ColVecResult&>(nullable_column.get_nested_column());
+            if constexpr (IsDecimalNumber<T>) {
+                col.get_data().push_back(this->get_samp_result().value());
+            } else {
+                col.get_data().push_back(this->get_samp_result());
+            }
+            nullable_column.get_null_map_data().push_back(0);
+        }
+    }
+};
+
+template <typename Data>
+struct StddevData : Data {
+    static const char* name() { return "stddev"; }
+};
+
+template <typename Data>
+struct VarianceData : Data {
+    static const char* name() { return "variance"; }
+};
+
+template <typename Data>
+struct VarianceSampData : Data {
+    static const char* name() { return "variance_samp"; }
+};
+
+template <typename Data>
+struct StddevSampData : Data {
+    static const char* name() { return "stddev_samp"; }
+};
+
+template <typename Data>
+class AggregateFunctionStddevSamp final
+        : public IAggregateFunctionDataHelper<Data, 
AggregateFunctionStddevSamp<Data>> {
+public:
+    AggregateFunctionStddevSamp(const DataTypes& argument_types_)
+            : IAggregateFunctionDataHelper<Data, 
AggregateFunctionStddevSamp<Data>>(argument_types_,
+                                                                               
     {}) {}
+
+    String get_name() const override { return Data::name(); }
+
+    bool insert_to_null_default() const override { return false; }
+
+    DataTypePtr get_return_type() const override { return 
Data::get_return_type(); }
+
+    void add(AggregateDataPtr __restrict place, const IColumn** columns, 
size_t row_num,
+             Arena*) const override {
+        this->data(place).add(columns, row_num);
+    }
+
+    void reset(AggregateDataPtr __restrict place) const override { 
this->data(place).reset(); }
+
+    void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs,
+               Arena*) const override {
+        this->data(place).merge(this->data(rhs));
+    }
+
+    void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& 
buf) const override {
+        this->data(place).write(buf);
+    }
+
+    void deserialize(AggregateDataPtr __restrict place, BufferReadable& buf,
+                     Arena*) const override {
+        this->data(place).read(buf);
+    }
+
+    void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& 
to) const override {
+        this->data(place).insert_result_into(to);
+    }
+
+    const char* get_header_file_path() const override { return __FILE__; }
+};
+
+} // namespace doris::vectorized
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index 7c0cde1..0c8079c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -1674,6 +1674,74 @@ public class 
FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo
                         null,
                         prefix + STDDEV_POP_FINALIZE_SYMBOL.get(t),
                         false, false, false));
+                //vec stddev stddev_samp stddev_pop
+                addBuiltin(AggregateFunction.createBuiltin("stddev",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + STDDEV_POP_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("stddev_samp",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + STDDEV_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("stddev_pop",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + STDDEV_POP_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                
+                //vec: variance variance_samp var_samp variance_pop var_pop
+                addBuiltin(AggregateFunction.createBuiltin("variance",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + VAR_POP_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("variance_pop",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + VAR_POP_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("var_pop",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + VAR_POP_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("variance_samp",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + VAR_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));
+                addBuiltin(AggregateFunction.createBuiltin("var_samp",
+                        Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), t,
+                        prefix + STDDEV_INIT_SYMBOL.get(t),
+                        prefix + STDDEV_UPDATE_SYMBOL.get(t),
+                        prefix + STDDEV_MERGE_SYMBOL.get(t),
+                        null,
+                        prefix + VAR_FINALIZE_SYMBOL.get(t),
+                        false, false, false, true));                        
+
                 addBuiltin(AggregateFunction.createBuiltin("variance",
                         Lists.newArrayList(t), STDDEV_RETTYPE_SYMBOL.get(t), 
Type.VARCHAR,
                         prefix + STDDEV_INIT_SYMBOL.get(t),

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to