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
The following commit(s) were added to refs/heads/vectorized by this push:
new 24787ed [Vectorized][Function] Support function
stddev/variance/stddev_samp/variance_samp (#7734)
24787ed is described below
commit 24787ed6426f7ffd7fd9bc025605e952fa956b49
Author: zhangstar333 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]