imporve multiif

This commit is contained in:
kevinyhzou 2023-12-11 19:43:56 +08:00
parent a0af0392cd
commit 14b8d8fb92
2 changed files with 66 additions and 3 deletions

View File

@ -238,7 +238,7 @@ public:
}
const auto & settings = context->getSettingsRef();
const WhichDataType which(result_type);
const WhichDataType which(removeNullable(result_type));
bool execute_multiif_columnar
= settings.allow_execute_multiif_columnar && !contains_short && (which.isInt() || which.isUInt() || which.isFloat());
@ -254,8 +254,17 @@ public:
if (which.is##TYPE()) \
{ \
MutableColumnPtr res = ColumnVector<TYPE>::create(rows); \
executeInstructionsColumnar<TYPE, INDEX>(instructions, rows, res); \
return std::move(res); \
if (!result_type->isNullable()) \
{ \
executeInstructionsColumnar<TYPE, INDEX>(instructions, rows, res); \
return std::move(res); \
} \
else \
{ \
MutableColumnPtr null_map = ColumnUInt8::create(rows); \
executeInstructionsColumnarForNullable<TYPE, INDEX>(instructions, rows, res, null_map); \
return ColumnNullable::create(std::move(res), std::move(null_map)); \
} \
}
#define ENUMERATE_NUMERIC_TYPES(M, INDEX) \
@ -373,6 +382,47 @@ private:
}
}
template<typename T, typename S>
static void executeInstructionsColumnarForNullable(std::vector<Instruction> & instructions, size_t rows, const MutableColumnPtr & res, const MutableColumnPtr & null_map)
{
PaddedPODArray<S> inserts(rows, static_cast<S>(instructions.size()));
calculateInserts(instructions, rows, inserts);
PaddedPODArray<T> & res_data = assert_cast<ColumnVector<T> &>(*res).getData();
PaddedPODArray<UInt8> & null_map_data = assert_cast<ColumnUInt8 &>(*null_map).getData();
std::vector<const ColumnVector<T> *> data_cols(instructions.size());
std::vector<const ColumnUInt8 *> null_map_cols(instructions.size());
for (size_t i = 0; i < instructions.size(); ++i)
{
if (instructions[i].source->isNullable())
{
const ColumnNullable * nullable_col;
if (!instructions[i].source_is_constant)
nullable_col = assert_cast<const ColumnNullable *>(instructions[i].source.get());
else
{
const ColumnPtr data_column = assert_cast<const ColumnConst *>(instructions[i].source.get())->getDataColumnPtr();
nullable_col = assert_cast<const ColumnNullable *>(data_column.get());
}
null_map_cols[i] = assert_cast<const ColumnUInt8 *>(nullable_col->getNullMapColumnPtr().get());
data_cols[i] = assert_cast<const ColumnVector<T> *>(nullable_col->getNestedColumnPtr().get());
}
else
{
null_map_cols[i] = nullptr;
data_cols[i] = assert_cast<const ColumnVector<T> *>(instructions[i].source.get());
}
}
for (size_t row_i = 0; row_i < rows; ++row_i)
{
auto & instruction = instructions[inserts[row_i]];
size_t index = instruction.source_is_constant ? 0 : row_i;
res_data[row_i] = data_cols[inserts[row_i]]->getData()[index];
null_map_data[row_i] = null_map_cols[inserts[row_i]]->getData()[index];
}
}
template <typename T, typename S>
static void executeInstructionsColumnar(std::vector<Instruction> & instructions, size_t rows, const MutableColumnPtr & res)
{

View File

@ -0,0 +1,13 @@
#!/usr/bin/env bash
# NOTE: this sh wrapper is required because of shell_config
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
$CLICKHOUSE_CLIENT -q "drop table if exists test_tbl"
$CLICKHOUSE_CLIENT -q "create table test_tbl (d Nullable(Int64)) engine=Memory"
$CLICKHOUSE_CLIENT -q "insert into test_tbl select * from numbers(5)"
$CLICKHOUSE_CLIENT -q "select multiIf(d > 0, 1, -1), multiIf(d > 1, d-1, -1), multiIf(d > 2, null, -1) from test_tbl"
$CLICKHOUSE_CLIENT -q "drop table test_tbl"