blob: 435f39fa28fda75cb24f6eaa1cd220abda264e7e [file] [log] [blame]
/*
* 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 "gtest/gtest.h"
#include "dbcommon/function/agg-func.h"
#include "dbcommon/testutil/agg-func-utils.h"
#include "dbcommon/testutil/tuple-batch-utils.h"
#include "dbcommon/testutil/vector-utils.h"
namespace dbcommon {
TEST_F(AggFuncTest, has_no_group_by_count_star) {
std::vector<Datum> params(4);
{
std::vector<int64_t> initAggGrpVals = {3};
std::unique_ptr<AggGroupValues> grpValsBase =
generateAggGroupValues<int64_t>(initAggGrpVals, false, false);
std::vector<uint64_t> hashGroups = {0, 0};
params[0] = CreateDatum<AggGroupValues *>(grpValsBase.get());
params[2] = CreateDatum<const std::vector<uint64_t> *>(&hashGroups);
params[3] = CreateDatum<bool>(false);
count_star(params.data(), 4);
auto grpVals =
reinterpret_cast<AggPrimitiveGroupValues *>(grpValsBase.get());
auto accessor = grpVals->getAccessor<AggPrimitiveGroupValues::Accessor>();
EXPECT_EQ(5, DatumGetValue<int64_t>(accessor.at(0)->accVal.value));
}
}
TEST_F(AggFuncTest, has_no_group_by_count_inc) {
func_type testFunc = count_inc;
std::vector<int64_t> initAggGrpVals = {20};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<int64_t> vals = {1, 1, 2, 1};
std::vector<bool> nulls = {false, false, false, true};
SelectList sel = {0, 2};
{
LOG_INFO("Testing without seleletList");
std::unique_ptr<Vector> vec = VectorUtility::generateSelectVector<int64_t>(
BIGINTID, vals, &nulls, nullptr);
grpVals = generateAggGroupValues<int64_t>(initAggGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 0, 1, 0};
LOG_INFO("Testing has GroupBy");
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({23}, grpVals.get());
LOG_INFO("Testing has no GroupBy");
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({26}, grpVals.get());
LOG_INFO("Testing has no nulls");
vec->setHasNull(false);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({30}, grpVals.get());
}
{
LOG_INFO("Testing with seleletList");
std::unique_ptr<Vector> vec = VectorUtility::generateSelectVector<int64_t>(
BIGINTID, vals, &nulls, nullptr);
vec->setSelected(&sel, false);
grpVals = generateAggGroupValues<int64_t>(initAggGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 1};
LOG_INFO("Testing has GroupBy");
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({22}, grpVals.get());
LOG_INFO("Testing has no GroupBy");
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({24}, grpVals.get());
LOG_INFO("Testing has no nulls");
vec->setHasNull(false);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({26}, grpVals.get());
}
}
TEST_F(AggFuncTest, has_no_group_by_count_add) {
func_type testFunc = count_add;
std::vector<int64_t> initAggGrpVals = {0};
std::vector<int64_t> vals = {9, 1, 2, 4};
SelectList sel = {0, 2, 3};
std::unique_ptr<AggGroupValues> grpVals;
{
LOG_INFO("Testing with seleletList");
grpVals = generateAggGroupValues<int64_t>(initAggGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 1, 1};
std::unique_ptr<Vector> vec = VectorUtility::generateSelectVector<int64_t>(
BIGINTID, vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({15}, grpVals.get());
}
{
LOG_INFO("Testing without seleletList");
std::vector<uint64_t> hashGroups = {0, 0, 1, 0};
grpVals = generateAggGroupValues<int64_t>(initAggGrpVals, false, true);
std::unique_ptr<Vector> vec = VectorUtility::generateSelectVector<int64_t>(
BIGINTID, vals, nullptr, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<int64_t>({16}, grpVals.get());
}
}
template <class T, TypeKind TK, class RT>
void AggFuncTest::testSumHasNoGroupBy(func_type testFunc) {
std::vector<RT> initAggGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<T> vals = {9, 1, 2, 4};
std::vector<bool> nulls = {true, false, true, false};
SelectList sel = {0, 2, 3};
std::unique_ptr<Vector> vec;
{
LOG_INFO("Testing with seleletList");
grpVals = generateAggGroupValues<RT>(initAggGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 1, 1};
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<RT>({15}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<RT>({19}, grpVals.get());
}
{
LOG_INFO("Testing without seleletList");
std::vector<uint64_t> hashGroups = {0, 0, 1, 0};
grpVals = generateAggGroupValues<RT>(initAggGrpVals, false, true);
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, nullptr);
LOG_INFO("Testing has no nulls");
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<RT>({16}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAcc<RT>({21}, grpVals.get());
}
}
TEST_F(AggFuncTest, has_no_group_by_Sum) {
testSumHasNoGroupBy<int8_t, TINYINTID, int64_t>(sum_int8_add);
testSumHasNoGroupBy<int64_t, BIGINTID, int64_t>(sum_int8_sum);
testSumHasNoGroupBy<int16_t, SMALLINTID, int64_t>(sum_int16_add);
testSumHasNoGroupBy<int64_t, BIGINTID, int64_t>(sum_int16_sum);
testSumHasNoGroupBy<int32_t, INTID, int64_t>(sum_int32_add);
testSumHasNoGroupBy<int64_t, BIGINTID, int64_t>(sum_int32_sum);
testSumHasNoGroupBy<int64_t, BIGINTID, int64_t>(sum_int64_add);
testSumHasNoGroupBy<int64_t, BIGINTID, int64_t>(sum_int64_sum);
testSumHasNoGroupBy<float, FLOATID, double>(sum_float_add);
testSumHasNoGroupBy<double, DOUBLEID, double>(sum_float_sum);
testSumHasNoGroupBy<double, DOUBLEID, double>(sum_double_add);
testSumHasNoGroupBy<double, DOUBLEID, double>(sum_double_sum);
}
template <class T, TypeKind TK>
void AggFuncTest::testAvgAccuHasNoGroupBy(func_type testFunc) {
std::vector<T> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<T> vals = {6, 2, 4, 5, 7};
std::vector<bool> nulls = {false, true, false, false, true};
{
LOG_INFO("Testing first stage avg");
std::unique_ptr<Vector> vec;
{
LOG_INFO("Testing with seleletList");
std::vector<uint64_t> hashGroups = {0, 1, 1};
SelectList sel = {0, 3, 4};
grpVals = generateAggGroupValues<T>(initGrpVals, true, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{18, 3}}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{29, 5}}, grpVals.get());
}
{
LOG_INFO("Testing without seleletList");
grpVals = generateAggGroupValues<T>(initGrpVals, true, true);
LOG_INFO("Testing has no nulls");
std::vector<uint64_t> hashGroups = {0, 0, 1, 1, 1};
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{24, 5}}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{39, 8}}, grpVals.get());
}
}
}
TEST_F(AggFuncTest, has_no_group_by_AvgAccumulate) {
testAvgAccuHasNoGroupBy<int8_t, TINYINTID>(avg_int8_accu);
testAvgAccuHasNoGroupBy<int16_t, SMALLINTID>(avg_int16_accu);
testAvgAccuHasNoGroupBy<int32_t, INTID>(avg_int32_accu);
testAvgAccuHasNoGroupBy<int64_t, BIGINTID>(avg_int64_accu);
testAvgAccuHasNoGroupBy<float, FLOATID>(avg_float_accu);
testAvgAccuHasNoGroupBy<double, DOUBLEID>(avg_double_accu);
}
template <class T, TypeKind TK>
void AggFuncTest::testAvgAmalgHasNoGroupBy(func_type testFunc) {
std::vector<T> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
{
LOG_INFO("Testing second stage avg");
std::vector<double> vals = {6, 2, 4, 5, 7};
std::vector<uint64_t> counts = {1, 1, 1, 1, 1};
std::vector<bool> nulls = {false, true, false, false, true};
{
LOG_INFO("Testing without seleletList");
std::unique_ptr<Vector> vecSum, vecCount;
vecSum = VectorUtility::generateSelectVector<double>(
TypeKind::DECIMALNEWID == TK ? DECIMALNEWID : DOUBLEID, vals, &nulls,
nullptr);
vecCount = VectorUtility::generateSelectVector<uint64_t>(BIGINTID, counts,
&nulls, nullptr);
std::vector<std::unique_ptr<Vector>> vecs;
vecs.push_back(std::move(vecSum));
vecs.push_back(std::move(vecCount));
std::unique_ptr<dbcommon::Vector> vec =
VectorUtility::generateSelectStructVector(
vecs, nullptr, nullptr,
(TypeKind::DECIMALNEWID == TK ? AVG_DECIMAL_TRANS_DATA_ID
: AVG_DOUBLE_TRANS_DATA_ID));
grpVals = generateAggGroupValues<T>(initGrpVals, true, true);
std::vector<uint64_t> hashGroups = {0, 0, 1, 1, 1};
LOG_INFO("Testing has nulls");
vec->getChildVector(0)->setHasNull(true);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{15, 3}}, grpVals.get());
LOG_INFO("Testing has no nulls");
std::vector<bool> nonulls(nulls.size(), false);
vecSum = VectorUtility::generateSelectVector<double>(
TypeKind::DECIMALNEWID == TK ? DECIMALNEWID : DOUBLEID, vals,
&nonulls, nullptr);
vecCount = VectorUtility::generateSelectVector<uint64_t>(
BIGINTID, counts, &nonulls, nullptr);
vec->childs[0] = std::move(vecSum);
vec->childs[1] = std::move(vecCount);
vec->getChildVector(0)->setHasNull(false);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{39, 8}}, grpVals.get());
}
{
LOG_INFO("Testing with seleletList");
std::unique_ptr<Vector> vecSum, vecCount;
vecSum = VectorUtility::generateSelectVector<double>(
TypeKind::DECIMALNEWID == TK ? DECIMALNEWID : DOUBLEID, vals, &nulls,
nullptr);
vecCount = VectorUtility::generateSelectVector<uint64_t>(BIGINTID, counts,
&nulls, nullptr);
std::vector<std::unique_ptr<Vector>> vecs;
vecs.push_back(std::move(vecSum));
vecs.push_back(std::move(vecCount));
std::unique_ptr<dbcommon::Vector> vec =
VectorUtility::generateSelectStructVector(
vecs, nullptr, nullptr,
(TypeKind::DECIMALNEWID == TK ? AVG_DECIMAL_TRANS_DATA_ID
: AVG_DOUBLE_TRANS_DATA_ID));
std::vector<uint64_t> hashGroups = {0, 1, 1};
SelectList sel = {0, 3, 4};
vec->setSelected(&sel, false);
grpVals = generateAggGroupValues<T>(initGrpVals, true, true);
LOG_INFO("Testing has nulls");
vec->getChildVector(0)->setHasNull(true);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{11, 2}}, grpVals.get());
LOG_INFO("Testing has no nulls");
std::vector<bool> nonulls(nulls.size(), false);
vecSum = VectorUtility::generateSelectVector<double>(
TypeKind::DECIMALNEWID == TK ? DECIMALNEWID : DOUBLEID, vals,
&nonulls, nullptr);
vecCount = VectorUtility::generateSelectVector<uint64_t>(
BIGINTID, counts, &nonulls, nullptr);
vec->childs[0] = std::move(vecSum);
vec->childs[1] = std::move(vecCount);
vec->setSelected(&sel, false);
vec->getChildVector(0)->setHasNull(false);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
checkAvg({{29, 5}}, grpVals.get());
}
}
}
TEST_F(AggFuncTest, has_no_group_by_AvgAmalgamate) {
testAvgAmalgHasNoGroupBy<int8_t, TINYINTID>(avg_int8_amalg);
testAvgAmalgHasNoGroupBy<int16_t, SMALLINTID>(avg_int16_amalg);
testAvgAmalgHasNoGroupBy<int32_t, INTID>(avg_int32_amalg);
testAvgAmalgHasNoGroupBy<int64_t, BIGINTID>(avg_int64_amalg);
testAvgAmalgHasNoGroupBy<float, FLOATID>(avg_float_amalg);
testAvgAmalgHasNoGroupBy<double, DOUBLEID>(avg_double_amalg);
}
TEST_F(AggFuncTest, has_no_group_by_AvgAverage) {
std::vector<Datum> params(1);
params[0] =
CreateDatum<AvgPrimitiveTransData *>(new AvgPrimitiveTransData({11, 2}));
Datum avgDouble = avg_double_avg(params.data(), 1);
EXPECT_EQ(5.5, DatumGetValue<double>(avgDouble));
params[0] = CreateDatum(new AvgDecimalTransData({{0, 11, 0}, 2}));
Datum avgDecimal = avg_decimal_avg(params.data(), 1);
std::string avgStr = dbcommon::DecimalType::toString(
(DatumGetValue<DecimalVar *>(avgDecimal))->highbits,
(DatumGetValue<DecimalVar *>(avgDecimal))->lowbits,
(DatumGetValue<DecimalVar *>(avgDecimal))->scale);
EXPECT_EQ(5.5, std::stod(avgStr));
}
TEST_F(AggFuncTest, has_no_group_by_Scalar) {
std::vector<Datum> params(5);
Scalar scalar(CreateDatum<int64_t>(3));
std::vector<int64_t> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<uint64_t> hashGroups = {0, 0, 0};
params[2] = CreateDatum<const std::vector<uint64_t> *>(&hashGroups);
params[3] = CreateDatum<bool>(false);
params[4] = CreateDatum<Scalar *>(&scalar);
{
LOG_INFO("Testing COUNT(SCALAR)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
count_inc(params.data(), 5);
checkAcc<int64_t>({3}, grpVals.get());
}
{
LOG_INFO("Testing SUM(SCALAR)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
sum_int64_add(params.data(), 5);
checkAcc<int64_t>({9}, grpVals.get());
}
{
LOG_INFO("Testing AVG(SCALAR)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, true, true);
params[0] = CreateDatum(grpVals.get());
avg_int64_accu(params.data(), 5);
checkAvg({{9, 3}}, grpVals.get());
}
}
TEST_F(AggFuncTest, has_no_group_by_Statictis) {
std::vector<Datum> params(5);
Vector::uptr vec = Vector::BuildVector(BIGINTID, true);
std::vector<int64_t> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<uint64_t> hashGroups = {0, 0, 0};
params[2] = CreateDatum<const std::vector<uint64_t> *>(&hashGroups);
params[3] = CreateDatum<bool>(false);
params[4] = CreateDatum<Vector *>(vec.get());
VectorStatistics stat;
stat.hasMinMaxStats = true;
stat.minimum = CreateDatum(uint64_t(199));
stat.maximum = CreateDatum(uint64_t(998));
stat.sum = CreateDatum(uint64_t(6666));
stat.valueCount = 233;
vec->setVectorStatistics(stat);
{
LOG_INFO("Testing COUNT(STATISTICS)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
count_inc(params.data(), 5);
checkAcc<int64_t>({233}, grpVals.get());
count_inc(params.data(), 5);
checkAcc<int64_t>({233 * 2}, grpVals.get());
}
{
LOG_INFO("Testing SUM(STATISTICS)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
sum_int64_add(params.data(), 5);
checkAcc<int64_t>({6666}, grpVals.get());
sum_int64_add(params.data(), 5);
checkAcc<int64_t>({6666 * 2}, grpVals.get());
}
{
LOG_INFO("Testing AVG(STATISTICS)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, true, true);
params[0] = CreateDatum(grpVals.get());
avg_int64_accu(params.data(), 5);
checkAvg({{6666, 233}}, grpVals.get());
avg_int64_accu(params.data(), 5);
checkAvg({{6666 * 2, 233 * 2}}, grpVals.get());
}
{
LOG_INFO("Testing MIN/MAX(STATISTICS)");
grpVals = generateAggGroupValues<int64_t>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
min_int64_smaller(params.data(), 5);
checkAcc<int64_t>({199}, grpVals.get());
min_int64_smaller(params.data(), 5);
checkAcc<int64_t>({199}, grpVals.get());
}
}
TEST_F(AggFuncTest, has_no_group_by_Null) {
std::vector<uint64_t> hashGroups = {0, 1, 2, 3, 4};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<int64_t> vals = {6, 2, 4, 5, 7};
std::vector<bool> nulls = {false, true, false, false, true};
std::unique_ptr<Vector> vec = VectorUtility::generateSelectVector<int64_t>(
BIGINTID, vals, &nulls, nullptr);
{ // !isAvg
grpVals = generateAggGroupValues<uint64_t>(hashGroups, false, true);
callFunc(sum_int64_add, grpVals.get(), &hashGroups, true, vec.get());
checkNull(nulls, grpVals.get(), false);
grpVals = generateAggGroupValues<uint64_t>(hashGroups, false, true);
callFunc(sum_int64_sum, grpVals.get(), &hashGroups, true, vec.get());
checkNull(nulls, grpVals.get(), false);
}
}
template <class T, TypeKind TK>
void AggFuncTest::testMinMaxHasNoGroupBy(func_type testFunc, bool testMin) {
std::vector<T> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<T> vals = {6, 2, 4, 5, 7};
std::vector<bool> nulls = {false, true, false, true, false};
{ // small scale
std::unique_ptr<Vector> vec;
{ // without vec but with scalar
std::unique_ptr<Scalar> scalar = generateScalar<T>(TK, 1);
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
callFuncScalar(testFunc, grpVals.get(), &hashGroups, true, scalar.get());
checkAcc<T>({1}, grpVals.get());
}
{
LOG_INFO("Testing with seleletList");
std::vector<uint64_t> hashGroups = {0, 0, 0};
SelectList sel = {0, 3, 4};
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({6}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({5}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({5}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
}
{
LOG_INFO("Testing without seleletList");
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({4}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, nullptr, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({2}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(TK, vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAcc<T>({2}, grpVals.get());
else
checkAcc<T>({7}, grpVals.get());
}
}
}
template <>
void AggFuncTest::testMinMaxHasNoGroupBy<std::string, STRINGID>(
func_type testFunc, bool testMin) {
typedef std::string T;
std::vector<T> initGrpVals = {"0"};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<T> vals = {"6", "2", "4", "5", "7"};
std::vector<bool> nulls = {false, true, false, true, false};
{
LOG_INFO("Testing MIN/MAX(STATISTICS)");
Vector::uptr vec = Vector::BuildVector(STRINGID, true);
VectorStatistics stat;
stat.hasMinMaxStats = true;
stat.minimum = CreateDatum<const char *>("hello");
stat.maximum = CreateDatum<const char *>("hi");
stat.valueCount = 233;
vec->setVectorStatistics(stat);
std::vector<uint64_t> hashGroups = {0};
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"hello"}, grpVals.get());
else
checkAccOnString({"hi"}, grpVals.get());
stat.minimum = CreateDatum<const char *>("heihei");
stat.maximum = CreateDatum<const char *>("xixi");
vec->setVectorStatistics(stat);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"heihei"}, grpVals.get());
else
checkAccOnString({"xixi"}, grpVals.get());
}
{ // small scale
std::unique_ptr<Vector> vec;
{ // without vec but with scalar
LOG_INFO("Testing scalar");
std::unique_ptr<Scalar> scalar = generateScalar<T>("1");
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
callFuncScalar(testFunc, grpVals.get(), &hashGroups, true, scalar.get());
checkAccOnString({"1"}, grpVals.get());
}
{
LOG_INFO("Testing with seleletList");
std::vector<uint64_t> hashGroups = {0, 0, 0};
SelectList sel = {0, 3, 4};
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has nulls");
vec =
VectorUtility::generateSelectVector<T>(STRINGID, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"6"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has no nulls");
vec =
VectorUtility::generateSelectVector<T>(STRINGID, vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"5"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
LOG_INFO("Testing has nulls");
vec =
VectorUtility::generateSelectVector<T>(STRINGID, vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"5"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
}
{
LOG_INFO("Testing without seleletList");
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(STRINGID, vals, &nulls,
nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"4"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpVals, false, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectVector<T>(STRINGID, vals, nullptr,
nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"2"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectVector<T>(STRINGID, vals, &nulls,
nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnString({"2"}, grpVals.get());
else
checkAccOnString({"7"}, grpVals.get());
}
}
}
template <>
void AggFuncTest::testMinMaxHasNoGroupBy<Timestamp, TIMESTAMPID>(
func_type testFunc, bool testMin) {
typedef Timestamp T;
std::vector<std::string> initGrpValStrs = {"1970-01-01 00:00:00"};
std::vector<T> initGrpVals = {{0, 0}};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<std::string> valStrs = {
"2018-01-19 17:25:10", "2018-01-19 17:25:10.1123",
"2018-01-19 17:25:10 BC", "2018-01-19 17:25:10.1123 BC",
"2018-01-19 17:25:10.22"};
std::vector<T> vals = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
std::vector<bool> nulls = {false, true, false, true, false};
{ // small scale
std::unique_ptr<Vector> vec;
{ // without vec but with scalar
Timestamp tsScalar;
std::unique_ptr<Scalar> scalar =
generateScalar<T>("2018-01-19 19:52:00", &tsScalar);
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
grpVals = generateAggGroupValues<T>(initGrpValStrs, initGrpVals, true);
callFuncScalar(testFunc, grpVals.get(), &hashGroups, true, scalar.get());
checkAccOnTimestamp({{1516391520, 0}}, grpVals.get());
}
{
LOG_INFO("Testing with selectList");
std::vector<uint64_t> hashGroups = {0, 0, 0};
SelectList sel = {0, 3, 4};
grpVals = generateAggGroupValues<T>(initGrpValStrs, initGrpVals, true);
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectTimestampVector(TIMESTAMPID, valStrs,
&vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{1516382710, 0}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpValStrs, initGrpVals, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectTimestampVector(TIMESTAMPID, valStrs,
&vals, nullptr, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{-125815962890, 112300000}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectTimestampVector(TIMESTAMPID, valStrs,
&vals, &nulls, &sel);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{-125815962890, 112300000}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
}
{
LOG_INFO("Testing without selectList");
grpVals = generateAggGroupValues<T>(initGrpValStrs, initGrpVals, true);
std::vector<uint64_t> hashGroups = {0, 0, 0, 0, 0};
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectTimestampVector(
TIMESTAMPID, valStrs, &vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{-125815962890, 0}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
grpVals = generateAggGroupValues<T>(initGrpValStrs, initGrpVals, true);
LOG_INFO("Testing has no nulls");
vec = VectorUtility::generateSelectTimestampVector(
TIMESTAMPID, valStrs, &vals, nullptr, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{-125815962890, 0}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
LOG_INFO("Testing has nulls");
vec = VectorUtility::generateSelectTimestampVector(
TIMESTAMPID, valStrs, &vals, &nulls, nullptr);
callFunc(testFunc, grpVals.get(), &hashGroups, false, vec.get());
if (testMin)
checkAccOnTimestamp({{-125815962890, 0}}, grpVals.get());
else
checkAccOnTimestamp({{1516382710, 220000000}}, grpVals.get());
}
}
}
TEST_F(AggFuncTest, DISABLED_has_no_group_by_MinMax) {
testMinMaxHasNoGroupBy<int8_t, TINYINTID>(min_int8_smaller, true);
testMinMaxHasNoGroupBy<int16_t, SMALLINTID>(min_int16_smaller, true);
testMinMaxHasNoGroupBy<int32_t, INTID>(min_int32_smaller, true);
testMinMaxHasNoGroupBy<int64_t, BIGINTID>(min_int64_smaller, true);
testMinMaxHasNoGroupBy<float, FLOATID>(min_float_smaller, true);
testMinMaxHasNoGroupBy<double, DOUBLEID>(min_double_smaller, true);
testMinMaxHasNoGroupBy<std::string, STRINGID>(min_string_smaller, true);
testMinMaxHasNoGroupBy<Timestamp, TIMESTAMPID>(min_timestamp_smaller, true);
testMinMaxHasNoGroupBy<int8_t, TINYINTID>(max_int8_larger, false);
testMinMaxHasNoGroupBy<int16_t, SMALLINTID>(max_int16_larger, false);
testMinMaxHasNoGroupBy<int32_t, INTID>(max_int32_larger, false);
testMinMaxHasNoGroupBy<int64_t, BIGINTID>(max_int64_larger, false);
testMinMaxHasNoGroupBy<float, FLOATID>(max_float_larger, false);
testMinMaxHasNoGroupBy<double, DOUBLEID>(max_double_larger, false);
testMinMaxHasNoGroupBy<std::string, STRINGID>(max_string_larger, false);
testMinMaxHasNoGroupBy<Timestamp, TIMESTAMPID>(max_timestamp_larger, false);
}
TEST_F(AggFuncTest, TestDecimalScalar_has_no_group_by) {
this->isDecimal_ = true;
std::vector<Datum> params(5);
std::unique_ptr<Scalar> scalar = generateScalar(DECIMALNEWID, 3);
std::vector<double> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<uint64_t> hashGroups = {0, 0, 0};
params[2] = CreateDatum<const std::vector<uint64_t> *>(&hashGroups);
params[3] = CreateDatum<bool>(false);
params[4] = CreateDatum<Scalar *>(scalar.get());
{
LOG_INFO("Testing SUM(SCALAR)");
grpVals = generateAggGroupValues<double>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
sum_decimal_add(params.data(), 5);
checkAcc<double>({9}, grpVals.get());
sum_decimal_add(params.data(), 5);
checkAcc<double>({18}, grpVals.get());
}
{
LOG_INFO("Testing AVG(SCALAR)");
grpVals = generateAggGroupValues<double>(initGrpVals, true, true);
params[0] = CreateDatum(grpVals.get());
avg_decimal_accu(params.data(), 5);
checkAvg({{9, 3}}, grpVals.get());
avg_decimal_accu(params.data(), 5);
checkAvg({{18, 6}}, grpVals.get());
}
}
TEST_F(AggFuncTest, TestDecimal_has_no_group_by_Statictis) {
this->isDecimal_ = true;
std::vector<Datum> params(5);
Vector::uptr vec = Vector::BuildVector(DECIMALNEWID, true);
std::vector<double> initGrpVals = {0};
std::unique_ptr<AggGroupValues> grpVals;
std::vector<uint64_t> hashGroups = {0, 0, 0};
params[2] = CreateDatum<const std::vector<uint64_t> *>(&hashGroups);
params[3] = CreateDatum<bool>(false);
params[4] = CreateDatum<Vector *>(vec.get());
DecimalVar min{0, 199, 0}, max{0, 998, 0}, sum{0, 6666, 0};
VectorStatistics stat;
stat.hasMinMaxStats = true;
stat.minimum = CreateDatum<const char *>("199");
stat.maximum = CreateDatum<const char *>("998");
stat.sum = CreateDatum<const char *>("6666");
stat.valueCount = 233;
vec->setVectorStatistics(stat);
{
LOG_INFO("Testing SUM(STATISTICS)");
grpVals = generateAggGroupValues<double>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
sum_decimal_add(params.data(), 5);
checkAcc<double>({6666}, grpVals.get());
sum_decimal_add(params.data(), 5);
checkAcc<double>({6666 * 2}, grpVals.get());
}
{
LOG_INFO("Testing AVG(STATISTICS)");
grpVals = generateAggGroupValues<double>(initGrpVals, true, true);
params[0] = CreateDatum(grpVals.get());
avg_decimal_accu(params.data(), 5);
checkAvg({{6666, 233}}, grpVals.get());
avg_decimal_accu(params.data(), 5);
checkAvg({{6666 * 2, 233 * 2}}, grpVals.get());
}
{
LOG_INFO("Testing MIN/MAX(STATISTICS)");
grpVals = generateAggGroupValues<double>(initGrpVals, false, true);
params[0] = CreateDatum(grpVals.get());
min_decimal_smaller(params.data(), 5);
checkAcc<double>({199}, grpVals.get());
stat.minimum = CreateDatum<const char *>("6");
vec->setVectorStatistics(stat);
min_decimal_smaller(params.data(), 5);
checkAcc<double>({6}, grpVals.get());
}
}
TEST_F(AggFuncTest, TestDecimal_has_no_group_by) {
this->isDecimal_ = true;
testMinMaxHasNoGroupBy<double, DECIMALNEWID>(min_decimal_smaller, true);
testMinMaxHasNoGroupBy<double, DECIMALNEWID>(max_decimal_larger, false);
testSumHasNoGroupBy<double, DECIMALNEWID, double>(sum_decimal_add);
testSumHasNoGroupBy<double, DECIMALNEWID, double>(sum_decimal_sum);
testAvgAccuHasNoGroupBy<double, DECIMALNEWID>(avg_decimal_accu);
testAvgAmalgHasNoGroupBy<double, DECIMALNEWID>(avg_decimal_amalg);
}
} // namespace dbcommon