Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions be/src/vec/columns/column_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ void ColumnObject::insert_range_from(const IColumn& src, size_t start, size_t le
}

ColumnPtr ColumnObject::replicate(const Offsets& offsets) const {
if (subcolumns.empty()) {
if (num_rows == 0 || subcolumns.empty()) {
// Add an emtpy column with offsets.back rows
auto res = ColumnObject::create(true, false);
res->set_num_rows(offsets.back());
Expand All @@ -934,7 +934,7 @@ ColumnPtr ColumnObject::replicate(const Offsets& offsets) const {
}

ColumnPtr ColumnObject::permute(const Permutation& perm, size_t limit) const {
if (subcolumns.empty()) {
if (num_rows == 0 || subcolumns.empty()) {
if (limit == 0) {
limit = num_rows;
} else {
Expand Down Expand Up @@ -1499,7 +1499,7 @@ ColumnPtr ColumnObject::filter(const Filter& filter, ssize_t count) const {
return finalized_object.apply_for_subcolumns(
[&](const auto& subcolumn) { return subcolumn.filter(filter, count); });
}
if (subcolumns.empty()) {
if (num_rows == 0 || subcolumns.empty()) {
// Add an emtpy column with filtered rows
auto res = ColumnObject::create(true, false);
res->set_num_rows(count_bytes_in_filter(filter));
Expand All @@ -1518,7 +1518,7 @@ Status ColumnObject::filter_by_selector(const uint16_t* sel, size_t sel_size, IC
if (!is_finalized()) {
finalize();
}
if (subcolumns.empty()) {
if (num_rows == 0 || subcolumns.empty()) {
assert_cast<ColumnObject*>(col_ptr)->insert_many_defaults(sel_size);
return Status::OK();
}
Expand Down
37 changes: 37 additions & 0 deletions be/test/vec/columns/column_object_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,47 @@
#include <gtest/gtest-test-part.h>
#include <gtest/gtest.h>

#include "vec/columns/common_column_test.h"

namespace doris::vectorized {

class ColumnObjectTest : public ::testing::Test {};

auto construct_dst_varint_column() {
// 1. create an empty variant column
vectorized::ColumnObject::Subcolumns dynamic_subcolumns;
dynamic_subcolumns.create_root(vectorized::ColumnObject::Subcolumn(0, true, true /*root*/));
dynamic_subcolumns.add(vectorized::PathInData("v.f"),
vectorized::ColumnObject::Subcolumn {0, true});
dynamic_subcolumns.add(vectorized::PathInData("v.e"),
vectorized::ColumnObject::Subcolumn {0, true});
dynamic_subcolumns.add(vectorized::PathInData("v.b"),
vectorized::ColumnObject::Subcolumn {0, true});
dynamic_subcolumns.add(vectorized::PathInData("v.b.d"),
vectorized::ColumnObject::Subcolumn {0, true});
dynamic_subcolumns.add(vectorized::PathInData("v.c.d"),
vectorized::ColumnObject::Subcolumn {0, true});
return ColumnObject::create(std::move(dynamic_subcolumns), true);
}

TEST_F(ColumnObjectTest, permute) {
auto column_variant = construct_dst_varint_column();
{
// test empty column and limit == 0
IColumn::Permutation permutation(0);
auto col = column_variant->clone_empty();
col->permute(permutation, 0);
EXPECT_EQ(col->size(), 0);
}

MutableColumns columns;
columns.push_back(column_variant->get_ptr());
assert_column_vector_permute(columns, 0);
assert_column_vector_permute(columns, 1);
assert_column_vector_permute(columns, column_variant->size());
assert_column_vector_permute(columns, UINT64_MAX);
}

// TEST
TEST_F(ColumnObjectTest, test_pop_back) {
ColumnObject::Subcolumn subcolumn(0, true /* is_nullable */, false /* is_root */);
Expand Down
111 changes: 111 additions & 0 deletions be/test/vec/columns/common_column_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// 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 <gtest/gtest-message.h>
#include <gtest/gtest-test-part.h>
#include <gtest/gtest.h>

#include <filesystem>
#include <fstream>
#include <iostream>
#include <random>
#include <string>

#include "vec/columns/column.h"
#include "vec/common/cow.h"
#include "vec/core/field.h"
#include "vec/core/sort_block.h"
#include "vec/core/sort_description.h"
#include "vec/core/types.h"
#include "vec/data_types/data_type.h"

// this test is gonna to be a column test template for all column which should make ut test to coverage the function defined in column (all maybe we need 79 interfaces to be tested)
// for example column_array should test this function:
// size, reserve, resize, empty, byte_size, allocated_bytes, clone_resized,
// get_shrinked_column, filter, filter_by_selector, serialize_vec, deserialize_vec, get_max_row_byte_size
//
namespace doris::vectorized {

class CommonColumnTest : public ::testing::Test {
public:
void SetUp() override {}

// this function helps to check sort permutation behavior for column which use column::compare_at
static void stable_get_column_permutation(const IColumn& column, bool ascending, size_t limit,
int nan_direction_hint,
IColumn::Permutation& out_permutation) {
(void)(limit);

size_t size = column.size();
out_permutation.resize(size);
std::iota(out_permutation.begin(), out_permutation.end(),
IColumn::Permutation::value_type(0));

std::stable_sort(out_permutation.begin(), out_permutation.end(),
[&](size_t lhs, size_t rhs) {
int res = column.compare_at(lhs, rhs, column, nan_direction_hint);
// to check element in column is sorted or not
if (ascending)
return res < 0;
else
return res > 0;
});
}
};

auto check_permute = [](const IColumn& column, const IColumn::Permutation& permutation,
size_t limit, size_t expected_size) {
auto res_col = column.permute(permutation, limit);
EXPECT_EQ(res_col->size(), expected_size);
try {
for (size_t j = 0; j < expected_size; ++j) {
EXPECT_EQ(res_col->compare_at(j, permutation[j], column, -1), 0);
}
} catch (doris::Exception& e) {
LOG(ERROR) << "Exception: " << e.what();
// using field check
for (size_t j = 0; j < expected_size; ++j) {
Field r;
Field l;
column.get(permutation[j], r);
res_col->get(j, l);
EXPECT_EQ(r, l);
}
}
};
auto assert_column_vector_permute = [](MutableColumns& cols, size_t num_rows) {
for (const auto& col : cols) {
size_t expected_size = num_rows ? std::min(col->size(), num_rows) : col->size();
{
IColumn::Permutation permutation;
CommonColumnTest::stable_get_column_permutation(*col, true, col->size(), -1,
permutation);
check_permute(*col, permutation, num_rows, expected_size);
}
{
IColumn::Permutation permutation(col->size());
std::iota(permutation.begin(), permutation.end(), IColumn::Permutation::value_type(0));
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(permutation.begin(), permutation.end(), g);
check_permute(*col, permutation, num_rows, expected_size);
}
}
};

} // namespace doris::vectorized
Loading
Loading