* change picture to word * change picture to word * SHOW FULL TABLES WHERE Table_type != VIEW sql can not execute * change license description
742 lines
27 KiB
C++
742 lines
27 KiB
C++
// Copyright (c) 2017, Baidu.com, Inc. All Rights Reserved
|
|
|
|
// Licensed 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 <sstream>
|
|
|
|
#include "common/object_pool.h"
|
|
#include "exprs/expr.h"
|
|
#include "exprs/expr_context.h"
|
|
#include "olap/row_block.h"
|
|
#include "olap/olap_table.h"
|
|
#include "runtime/runtime_state.h"
|
|
#include "util/debug_util.h"
|
|
#include "util/logging.h"
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using std::endl;
|
|
using std::stringstream;
|
|
|
|
namespace palo {
|
|
void set_field_info(
|
|
FieldInfo& info,
|
|
const char* name,
|
|
FieldType type,
|
|
FieldAggregationMethod agg,
|
|
uint32_t length,
|
|
bool is_key) {
|
|
info.name = string(name);
|
|
info.type = type;
|
|
info.aggregation = agg;
|
|
info.length = length;
|
|
info.is_key = is_key;
|
|
}
|
|
|
|
static size_t g_row_length = 0;
|
|
static size_t g_row_length_mysql = 0;
|
|
|
|
void make_error_schema_array(vector<FieldInfo>& schema_array) {
|
|
schema_array.clear();
|
|
FieldInfo info;
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_UNKNOWN, OLAP_FIELD_AGGREGATION_SUM, 0, true);
|
|
schema_array.push_back(info);
|
|
}
|
|
|
|
// 生成一份FieldInfo array
|
|
void make_schema_array(vector<FieldInfo>& schema_array) {
|
|
schema_array.clear();
|
|
FieldInfo info;
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_INT, OLAP_FIELD_AGGREGATION_SUM, 4, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_BIGINT, OLAP_FIELD_AGGREGATION_SUM, 8, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_SMALLINT, OLAP_FIELD_AGGREGATION_SUM, 2, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_UNSIGNED_INT, OLAP_FIELD_AGGREGATION_MAX, 4, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_CHAR, OLAP_FIELD_AGGREGATION_REPLACE, 32, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_FLOAT, OLAP_FIELD_AGGREGATION_SUM, 4, false);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_CHAR, OLAP_FIELD_AGGREGATION_REPLACE, 64, false);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_DATE, OLAP_FIELD_AGGREGATION_MAX, 4, false);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_INT, OLAP_FIELD_AGGREGATION_SUM, 4, false);
|
|
schema_array.push_back(info);
|
|
|
|
g_row_length = sizeof(int) + sizeof(int64_t) + sizeof(int16_t) +
|
|
sizeof(uint32_t) + 32 + sizeof(float) + 64 + sizeof(int) + sizeof(int);
|
|
|
|
g_row_length_mysql = g_row_length - 1;
|
|
}
|
|
|
|
// 生成一份short FieldInfo array
|
|
void make_schema_array_short(vector<FieldInfo>& schema_array) {
|
|
schema_array.clear();
|
|
FieldInfo info;
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_INT, OLAP_FIELD_AGGREGATION_SUM, 4, true);
|
|
schema_array.push_back(info);
|
|
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_BIGINT, OLAP_FIELD_AGGREGATION_SUM, 8, true);
|
|
schema_array.push_back(info);
|
|
}
|
|
|
|
void make_string_array_short(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("123"));
|
|
string_array.push_back(string("456000"));
|
|
}
|
|
|
|
// 按照上面的schema构造各个column上的value
|
|
void make_string_array(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("123"));
|
|
string_array.push_back(string("456000"));
|
|
string_array.push_back(string("789"));
|
|
string_array.push_back(string("0"));
|
|
string_array.push_back(string("guping"));
|
|
string_array.push_back(string("123.0"));
|
|
string_array.push_back(string("olap"));
|
|
string_array.push_back(string("2012-5-8"));
|
|
string_array.push_back(string("100"));
|
|
}
|
|
|
|
void make_string_array_0(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("123"));
|
|
string_array.push_back(string("456000"));
|
|
string_array.push_back(string("789"));
|
|
string_array.push_back(string("1"));
|
|
string_array.push_back(string("guping"));
|
|
string_array.push_back(string("123.0"));
|
|
string_array.push_back(string("olap"));
|
|
string_array.push_back(string("2012-5-8"));
|
|
string_array.push_back(string("100"));
|
|
}
|
|
|
|
void make_string_array_1(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("123"));
|
|
string_array.push_back(string("456000"));
|
|
string_array.push_back(string("790"));
|
|
string_array.push_back(string("0"));
|
|
string_array.push_back(string("guping"));
|
|
string_array.push_back(string("123.0"));
|
|
string_array.push_back(string("olap"));
|
|
string_array.push_back(string("2012-5-8"));
|
|
string_array.push_back(string("100"));
|
|
}
|
|
void make_string_array_2(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("123"));
|
|
string_array.push_back(string("456001"));
|
|
string_array.push_back(string("789"));
|
|
string_array.push_back(string("0"));
|
|
string_array.push_back(string("guping"));
|
|
string_array.push_back(string("123.0"));
|
|
string_array.push_back(string("olap"));
|
|
string_array.push_back(string("2012-5-8"));
|
|
string_array.push_back(string("100"));
|
|
}
|
|
void make_string_array_3(vector<string>& string_array) {
|
|
string_array.clear();
|
|
string_array.push_back(string("124"));
|
|
string_array.push_back(string("456000"));
|
|
string_array.push_back(string("789"));
|
|
string_array.push_back(string("0"));
|
|
string_array.push_back(string("guping"));
|
|
string_array.push_back(string("123.0"));
|
|
string_array.push_back(string("olap"));
|
|
string_array.push_back(string("2012-5-8"));
|
|
string_array.push_back(string("100"));
|
|
}
|
|
|
|
// 测试成员函数在初始化、参数异常条件下的行为
|
|
class TestRowBlockSimple : public testing::Test {
|
|
protected:
|
|
void SetUp() {
|
|
make_schema_array(_tablet_schema);
|
|
_block_info.checksum = 12345678;
|
|
_block_info.row_num = 8;
|
|
_block_info.unpacked_len = 0;
|
|
}
|
|
void TearDown() {
|
|
}
|
|
vector<FieldInfo> _tablet_schema;
|
|
RowBlockInfo _block_info;
|
|
};
|
|
|
|
// 测试成员init方法
|
|
TEST_F(TestRowBlockSimple, test_init) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
ASSERT_EQ(row_block._buf_len, g_row_length * 8);
|
|
ASSERT_EQ(OLAP_ERR_INIT_FAILED, row_block.init(_block_info));
|
|
vector<FieldInfo> temp_schema = row_block.tablet_schema();
|
|
ASSERT_EQ(temp_schema.size(), _tablet_schema.size());
|
|
}
|
|
|
|
// 测试各成员函数在未初始化状态下的行为
|
|
TEST_F(TestRowBlockSimple, test_not_init) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_ERR_NOT_INITED, row_block.get_row_to_read(0, NULL));
|
|
RowCursor cursor;
|
|
ASSERT_EQ(OLAP_ERR_NOT_INITED, row_block.find_row(cursor, true, NULL));
|
|
ASSERT_EQ(OLAP_ERR_NOT_INITED, row_block.decompress(NULL, 0, OLAP_COMP_STORAGE));
|
|
ASSERT_EQ(OLAP_ERR_NOT_INITED, row_block.set_row(0, cursor));
|
|
ASSERT_EQ(OLAP_ERR_NOT_INITED, row_block.finalize(0));
|
|
}
|
|
|
|
// 测试各成员函数在输入参数错误情况下的行为
|
|
TEST_F(TestRowBlockSimple, test_err_param) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
RowCursor cursor;
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.get_row_to_read(100, NULL));
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.get_row_to_read(1, NULL));
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.get_row_to_read(1, &cursor));
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR,
|
|
row_block.find_row(cursor, false, NULL));
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.compress(
|
|
NULL, 0, NULL, OLAP_COMP_STORAGE));
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.decompress(
|
|
NULL, 0, OLAP_COMP_STORAGE));
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.set_row(100, cursor));
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.set_row(1, cursor));
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.finalize(100));
|
|
}
|
|
|
|
TEST_F(TestRowBlockSimple, test_invalid_schema) {
|
|
vector<FieldInfo> err_schema;
|
|
make_error_schema_array(err_schema);
|
|
RowBlock err_block(err_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, err_block.init(_block_info));
|
|
RowCursor cursor;
|
|
uint32_t row_index;
|
|
ASSERT_EQ(OLAP_ERR_INIT_FAILED, err_block.find_row(cursor, false, &row_index));
|
|
}
|
|
|
|
class TestRowBlock : public testing::Test {
|
|
public:
|
|
TestRowBlock() : test_index(0) {}
|
|
void SetUp() {
|
|
//LOG(INFO) << "test_index is " << test_index++ << endl;
|
|
make_schema_array(_tablet_schema);
|
|
_block_info.checksum = 12345678;
|
|
_block_info.row_num = 8;
|
|
for (uint32_t i = 0; i < _tablet_schema.size(); i++) {
|
|
_block_info.unpacked_len += _tablet_schema[i].length;
|
|
}
|
|
_block_info.unpacked_len *= _block_info.row_num;
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.init(_tablet_schema));
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.init(_tablet_schema));
|
|
make_schema_array_short(_tablet_schema_short);
|
|
make_string_array_short(string_array_short);
|
|
ASSERT_EQ(OLAP_SUCCESS, short_cursor.init(_tablet_schema_short));
|
|
ASSERT_EQ(OLAP_SUCCESS, short_cursor.from_string(string_array_short));
|
|
}
|
|
void TearDown() {
|
|
}
|
|
|
|
void SetRows(RowBlock& row_block) {
|
|
make_string_array_0(string_array);
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.set_row(0, other_cursor));
|
|
|
|
make_string_array_1(string_array);
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.set_row(1, other_cursor));
|
|
|
|
make_string_array_2(string_array);
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.set_row(2, other_cursor));
|
|
|
|
make_string_array_3(string_array);
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.set_row(3, other_cursor));
|
|
}
|
|
|
|
RowCursor cursor;
|
|
RowCursor other_cursor;
|
|
RowCursor short_cursor;
|
|
size_t test_index;
|
|
RowBlockInfo _block_info;
|
|
vector<FieldInfo> _tablet_schema;
|
|
vector<string> string_array;
|
|
vector<FieldInfo> _tablet_schema_short;
|
|
vector<string> string_array_short;
|
|
};
|
|
|
|
TEST_F(TestRowBlock, test_set_row) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
ASSERT_EQ(row_block._buf_len, g_row_length * 8);
|
|
SetRows(row_block);
|
|
|
|
// 尝试用get_row取出一行来进行比较
|
|
make_string_array_0(string_array);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(0, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(1, &other_cursor));
|
|
ASSERT_EQ(-1, cursor.cmp(other_cursor));
|
|
|
|
// 测试finalize
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.finalize(4));
|
|
ASSERT_EQ(size_t(4), row_block._info.row_num);
|
|
ASSERT_EQ(size_t(4 * g_row_length), row_block._used_buf_size);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(0, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
|
|
// 再次finalize,这次应该对存储内容没有改动
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.finalize(4));
|
|
ASSERT_EQ(size_t(4), row_block._info.row_num);
|
|
ASSERT_EQ(size_t(4 * g_row_length), row_block._used_buf_size);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(1, &other_cursor));
|
|
ASSERT_EQ(-1, cursor.cmp(other_cursor));
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(0, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
|
|
// 测试find_row
|
|
uint32_t index = 0;
|
|
// 使用全key进行测试
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(0, &other_cursor));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(other_cursor, false, &index));
|
|
ASSERT_EQ(uint32_t(0), index);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(other_cursor, true, &index));
|
|
ASSERT_EQ(uint32_t(1), index);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(3, &other_cursor));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(other_cursor, false, &index));
|
|
ASSERT_EQ(uint32_t(3), index);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(other_cursor, true, &index));
|
|
ASSERT_EQ(uint32_t(4), index);
|
|
// 构造一个短key进行测试
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(short_cursor, false, &index));
|
|
ASSERT_EQ(uint32_t(0), index);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.find_row(short_cursor, true, &index));
|
|
ASSERT_EQ(uint32_t(2), index);
|
|
|
|
// 测试clear函数
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.clear());
|
|
ASSERT_EQ((size_t)8, row_block._info.row_num);
|
|
ASSERT_EQ(size_t(8 * g_row_length), row_block._buf_len);
|
|
}
|
|
|
|
TEST_F(TestRowBlock, test_compress_decompress) {
|
|
RowBlock row_block(_tablet_schema);
|
|
_block_info.row_num = 4;
|
|
_block_info.unpacked_len = 0;
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
ASSERT_EQ(row_block._buf_len, g_row_length * 4);
|
|
LOG(INFO) << "before compression, size is " << g_row_length * 4;
|
|
SetRows(row_block);
|
|
LOG(INFO) << "row block adler32 is " << row_block._info.checksum << endl;
|
|
// 必须先finalize再compress
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.finalize(4));
|
|
LOG(INFO) << "row block adler32 is " << row_block._info.checksum << endl;
|
|
const size_t buf_len = 100 * 1024;
|
|
char* buf = new char[buf_len];
|
|
size_t written_len = 0;
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.compress(buf, buf_len, &written_len,
|
|
OLAP_COMP_STORAGE));
|
|
LOG(INFO) << "after compression, size is " << written_len << endl;
|
|
|
|
uint32_t checksum = row_block._info.checksum;
|
|
LOG(INFO) << "row block adler32 is " << row_block._info.checksum << endl;
|
|
|
|
// 新建一个rowblock,然后从刚才压出来的数据解压起来
|
|
RowBlock other_row_block(_tablet_schema);
|
|
_block_info.checksum = checksum;
|
|
_block_info.row_num = 4;
|
|
ASSERT_EQ(OLAP_SUCCESS, other_row_block.init(_block_info));
|
|
ASSERT_EQ(other_row_block._buf_len, g_row_length * 4);
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, other_row_block.decompress(buf,
|
|
written_len, OLAP_COMP_STORAGE));
|
|
// 在两个rowblock里面按行比对数据
|
|
for (size_t i = 0; i < 4; ++i) {
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &cursor));
|
|
ASSERT_EQ(OLAP_SUCCESS, other_row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
|
|
// 再建一个row_block,从错误的buf中decompress数据,测试异常场景,
|
|
// 分为三种异常场景:1. 待解压buf不正确 2. 内部buflen不够大 3. checksum不正确
|
|
buf[0]++;
|
|
ASSERT_EQ(OLAP_ERR_DECOMPRESS_ERROR, other_row_block.decompress(buf,
|
|
written_len, OLAP_COMP_STORAGE));
|
|
buf[0]--;
|
|
|
|
// 由于变长字符串的缘故,这里没法再检测接出来字符串不够的问题
|
|
// 靠checksum来校验好了, 这里测下内部buf不足的情况
|
|
other_row_block._buf_len--;
|
|
ASSERT_EQ(OLAP_ERR_DECOMPRESS_ERROR, other_row_block.decompress(buf,
|
|
written_len, OLAP_COMP_STORAGE));
|
|
other_row_block._buf_len++;
|
|
|
|
other_row_block._info.checksum++;
|
|
ASSERT_EQ(OLAP_ERR_CHECKSUM_ERROR, other_row_block.decompress(buf,
|
|
written_len, OLAP_COMP_STORAGE));
|
|
other_row_block._info.checksum--;
|
|
|
|
delete[] buf;
|
|
}
|
|
|
|
TEST_F(TestRowBlock, test_crc) {
|
|
unsigned int crc32 = 0xffffffff;
|
|
const char* buf1 = "abcdefg";
|
|
size_t len1 = strlen(buf1);
|
|
unsigned int v1 = crc32c_lut(buf1, 0, len1, crc32);
|
|
LOG(INFO) << "crc32c_lut:" << v1 << endl;
|
|
ASSERT_EQ(v1, 433589182);
|
|
if (1 == check_sse4_2()) {
|
|
unsigned int v2 = baidu_crc32_qw(buf1, crc32, len1);
|
|
LOG(INFO) << "baidu_crc32_qw" << v2 <<endl;
|
|
ASSERT_EQ(v1,v2);
|
|
}
|
|
|
|
const char* buf2 = "abcdefghijklmnopqrstuvwxtz";
|
|
size_t len2 = strlen(buf2);
|
|
ASSERT_EQ(crc32c_lut(buf2, 0, len2, crc32),2703567561);
|
|
if (1 == check_sse4_2()) {
|
|
ASSERT_EQ((unsigned int)baidu_crc32_qw(buf2, crc32, len2), 2703567561);
|
|
}
|
|
}
|
|
|
|
class TestRowBlockWithConjuncts : public testing::Test {
|
|
public:
|
|
TestRowBlockWithConjuncts() :
|
|
_object_pool(NULL), _runtime_state(NULL), _row_desc(NULL) {
|
|
}
|
|
|
|
void SetUp() {
|
|
_object_pool = new ObjectPool();
|
|
_runtime_state = _object_pool->add(new RuntimeState(""));
|
|
|
|
TDescriptorTable ttbl;
|
|
TTupleDescriptor tuple_desc;
|
|
tuple_desc.__set_id(0);
|
|
tuple_desc.__set_byteSize(8);
|
|
tuple_desc.__set_numNullBytes(0);
|
|
ttbl.tupleDescriptors.push_back(tuple_desc);
|
|
|
|
{
|
|
TSlotDescriptor slot_desc;
|
|
|
|
slot_desc.__set_id(0);
|
|
slot_desc.__set_parent(0);
|
|
// slot_desc.__set_slotType(TPrimitiveType::INT);
|
|
slot_desc.__set_slotType(gen_type_desc(TPrimitiveType::INT));
|
|
slot_desc.__set_columnPos(0);
|
|
slot_desc.__set_byteOffset(4);
|
|
slot_desc.__set_nullIndicatorByte(0);
|
|
slot_desc.__set_nullIndicatorBit(0);
|
|
slot_desc.__set_colName("col1");
|
|
slot_desc.__set_slotIdx(0);
|
|
slot_desc.__set_isMaterialized(true);
|
|
ttbl.slotDescriptors.push_back(slot_desc);
|
|
}
|
|
|
|
{
|
|
TSlotDescriptor slot_desc;
|
|
slot_desc.__set_id(1);
|
|
slot_desc.__set_parent(0);
|
|
slot_desc.__set_slotType(gen_type_desc(TPrimitiveType::BIGINT));
|
|
slot_desc.__set_columnPos(1);
|
|
slot_desc.__set_byteOffset(8);
|
|
slot_desc.__set_nullIndicatorByte(0);
|
|
slot_desc.__set_nullIndicatorBit(0);
|
|
slot_desc.__set_colName("col2");
|
|
slot_desc.__set_slotIdx(1);
|
|
slot_desc.__set_isMaterialized(true);
|
|
ttbl.slotDescriptors.push_back(slot_desc);
|
|
}
|
|
|
|
DescriptorTbl* desc_tbl = NULL;
|
|
ASSERT_TRUE(DescriptorTbl::create(_object_pool, ttbl, &desc_tbl).ok());
|
|
ASSERT_TRUE(desc_tbl != NULL);
|
|
_runtime_state->set_desc_tbl(desc_tbl);
|
|
|
|
std::vector<TTupleId> row_tuples;
|
|
row_tuples.push_back(0);
|
|
std::vector<bool> nullable_tuples;
|
|
nullable_tuples.push_back(false);
|
|
_row_desc = _object_pool->add(
|
|
new RowDescriptor(*desc_tbl, row_tuples, nullable_tuples));
|
|
|
|
make_schema_array(_tablet_schema);
|
|
_block_info.checksum = 12345678;
|
|
_block_info.row_num = 128;
|
|
for (uint32_t i = 0; i < _tablet_schema.size(); i++) {
|
|
_block_info.unpacked_len += _tablet_schema[i].length;
|
|
}
|
|
_block_info.unpacked_len *= _block_info.row_num;
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.init(_tablet_schema));
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.init(_tablet_schema));
|
|
}
|
|
|
|
void TearDown() {
|
|
if (_object_pool != NULL) {
|
|
delete _object_pool;
|
|
_object_pool = NULL;
|
|
}
|
|
}
|
|
|
|
Expr* create_expr(int value) {
|
|
TExpr exprs;
|
|
{
|
|
TExprNode expr_node;
|
|
expr_node.__set_node_type(TExprNodeType::BINARY_PRED);
|
|
// TColumnType type;
|
|
// type.__set_type(TPrimitiveType::INT);
|
|
expr_node.__set_type(gen_type_desc(TPrimitiveType::INT));
|
|
expr_node.__set_num_children(2);
|
|
expr_node.__isset.opcode = true;
|
|
// expr_node.__set_opcode(TExprOpcode::LT_INT_INT);
|
|
expr_node.__isset.vector_opcode = true;
|
|
// expr_node.__set_vector_opcode(
|
|
// TExprOpcode::FILTER_LT_INT_INT);
|
|
exprs.nodes.push_back(expr_node);
|
|
}
|
|
{
|
|
TExprNode expr_node;
|
|
expr_node.__set_node_type(TExprNodeType::SLOT_REF);
|
|
// TColumnType type;
|
|
// type.__set_type(TPrimitiveType::INT);
|
|
expr_node.__set_type(gen_type_desc(TPrimitiveType::INT));
|
|
expr_node.__set_num_children(0);
|
|
expr_node.__isset.slot_ref = true;
|
|
TSlotRef slot_ref;
|
|
slot_ref.__set_slot_id(0);
|
|
slot_ref.__set_tuple_id(0);
|
|
expr_node.__set_slot_ref(slot_ref);
|
|
expr_node.__isset.output_column = true;
|
|
expr_node.__set_output_column(0);
|
|
exprs.nodes.push_back(expr_node);
|
|
}
|
|
|
|
{
|
|
TExprNode expr_node;
|
|
expr_node.__set_node_type(TExprNodeType::INT_LITERAL);
|
|
//TColumnType type;
|
|
//type.__set_type(TPrimitiveType::INT);
|
|
expr_node.__set_type(gen_type_desc(TPrimitiveType::INT));
|
|
expr_node.__set_num_children(0);
|
|
expr_node.__isset.int_literal = true;
|
|
TIntLiteral int_literal;
|
|
int_literal.__set_value(value);
|
|
expr_node.__set_int_literal(int_literal);
|
|
exprs.nodes.push_back(expr_node);
|
|
}
|
|
|
|
//Expr* root_expr = NULL;
|
|
ExprContext* expr_content = NULL;
|
|
if (Expr::create_expr_tree(_object_pool, exprs, &expr_content).ok()) {
|
|
return expr_content->root();
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void make_schema_array(vector<FieldInfo>& schema_array) {
|
|
schema_array.clear();
|
|
FieldInfo info;
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_INT, OLAP_FIELD_AGGREGATION_NONE, 4, true);
|
|
schema_array.push_back(info);
|
|
set_field_info(info, "", OLAP_FIELD_TYPE_BIGINT, OLAP_FIELD_AGGREGATION_SUM, 8, false);
|
|
schema_array.push_back(info);
|
|
|
|
g_row_length = sizeof(int) + sizeof(int64_t);
|
|
g_row_length_mysql = g_row_length - 1;
|
|
}
|
|
|
|
void set_rows(RowBlock& row_block) {
|
|
vector<string> string_array;
|
|
for (int i = 0; i < _block_info.row_num; ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, other_cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.set_row(i, other_cursor));
|
|
}
|
|
}
|
|
|
|
void make_row(vector<string>& string_array, int value) {
|
|
string_array.clear();
|
|
stringstream s;
|
|
s << value;
|
|
string_array.push_back(s.str());
|
|
string_array.push_back(s.str());
|
|
}
|
|
|
|
RowCursor cursor;
|
|
RowCursor other_cursor;
|
|
RowCursor short_cursor;
|
|
size_t test_index;
|
|
RowBlockInfo _block_info;
|
|
vector<FieldInfo> _tablet_schema;
|
|
vector<FieldInfo> _tablet_schema_short;
|
|
vector<string> string_array_short;
|
|
private:
|
|
ObjectPool* _object_pool;
|
|
RuntimeState* _runtime_state;
|
|
RowDescriptor* _row_desc;
|
|
};
|
|
|
|
TEST_F(TestRowBlockWithConjuncts, simpleTest) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
ASSERT_EQ(row_block._buf_len, g_row_length * _block_info.row_num);
|
|
set_rows(row_block);
|
|
|
|
vector<string> string_array;
|
|
for (int i = 0; i < _block_info.row_num; ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
|
|
Expr* expr = create_expr(_block_info.row_num + 1);
|
|
ExprContent *expr_content = new ExprContent(expr);
|
|
ASSERT_TRUE(expr != NULL);
|
|
ASSERT_TRUE(expr->prepare(_runtime_state, *_row_desc, expr_content).ok());
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.eval_conjuncts(expr_content));
|
|
ASSERT_EQ(_block_info.row_num, row_block.row_num());
|
|
|
|
for (int i = 0; i < row_block.row_num(); ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
}
|
|
|
|
TEST_F(TestRowBlockWithConjuncts, simpleEvalTest) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
set_rows(row_block);
|
|
|
|
Expr* expr = create_expr(_block_info.row_num / 2);
|
|
ExprContent *expr_content = new ExprContext(expr);
|
|
ASSERT_TRUE(expr != NULL);
|
|
ASSERT_TRUE(expr->prepare(_runtime_state, *_row_desc, expr_content).ok());
|
|
|
|
// vector<ExprContent*> conjuncts;
|
|
// conjuncts.push_back(expr_content);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.eval_conjuncts(expr_content));
|
|
ASSERT_EQ(_block_info.row_num / 2, row_block.row_num());
|
|
|
|
vector<string> string_array;
|
|
for (int i = 0; i < row_block.row_num(); ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
}
|
|
|
|
TEST_F(TestRowBlockWithConjuncts, RestoreTest) {
|
|
RowBlock row_block(_tablet_schema);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.init(_block_info));
|
|
set_rows(row_block);
|
|
ASSERT_EQ(_block_info.row_num, row_block.row_num());
|
|
|
|
ASSERT_EQ(OLAP_ERR_INPUT_PARAMETER_ERROR, row_block.backup());
|
|
|
|
Expr* expr = create_expr(_block_info.row_num / 2);
|
|
ASSERT_TRUE(expr != NULL);
|
|
ASSERT_TRUE(expr->prepare(_runtime_state, *_row_desc).ok());
|
|
|
|
vector<Expr*> conjuncts;
|
|
conjuncts.push_back(expr);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.eval_conjuncts(conjuncts));
|
|
ASSERT_EQ(_block_info.row_num / 2, row_block.row_num());
|
|
|
|
vector<string> string_array;
|
|
for (int i = 0; i < row_block.row_num(); ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.backup());
|
|
|
|
expr = create_expr(_block_info.row_num / 4);
|
|
ExprContent *expr_content = new ExprContent(expr);
|
|
ASSERT_TRUE(expr != NULL);
|
|
ASSERT_TRUE(expr->prepare(_runtime_state, *_row_desc, expr_content).ok());
|
|
|
|
//conjuncts.push_back(expr);
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.eval_conjuncts(expr_content));
|
|
ASSERT_EQ(_block_info.row_num / 4, row_block.row_num());
|
|
|
|
for (int i = 0; i < row_block.row_num(); ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.restore());
|
|
ASSERT_EQ(_block_info.row_num / 2, row_block.row_num());
|
|
|
|
for (int i = 0; i < row_block.row_num(); ++i) {
|
|
make_row(string_array, i);
|
|
ASSERT_EQ(OLAP_SUCCESS, cursor.from_string(string_array));
|
|
ASSERT_EQ(OLAP_SUCCESS, row_block.get_row_to_read(i, &other_cursor));
|
|
ASSERT_EQ(0, cursor.cmp(other_cursor));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// @brief Test Stub
|
|
int main( int argc, char** argv ) {
|
|
std::string conffile = std::string(getenv("PALO_HOME")) + "/conf/be.conf";
|
|
if (!palo::config::init(conffile.c_str(), false)) {
|
|
fprintf(stderr, "error read config file. \n");
|
|
return -1;
|
|
}
|
|
palo::init_glog("be-test");
|
|
int ret = palo::OLAP_SUCCESS;
|
|
testing::InitGoogleTest(&argc, argv);
|
|
ret = RUN_ALL_TESTS();
|
|
google::protobuf::ShutdownProtobufLibrary();
|
|
return ret;
|
|
}
|