dbms: better [#METR-19266]

This commit is contained in:
Alexey Arno 2016-08-11 03:17:30 +03:00
parent 6bd84296d1
commit 87f330627e
3 changed files with 21 additions and 23 deletions

View File

@ -141,7 +141,7 @@ protected:
/// Returns the copy of a given block in which each column specified in /// Returns the copy of a given block in which each column specified in
/// the "arguments" parameter is replaced with its respective nested /// the "arguments" parameter is replaced with its respective nested
/// column if it is nullable. /// column if it is nullable.
static Block extractNonNullableBlock(const Block & block, const ColumnNumbers & arguments); static Block extractNonNullableBlock(const Block & block, const ColumnNumbers args);
private: private:
/// Internal method used for implementing both the execute() methods. /// Internal method used for implementing both the execute() methods.

View File

@ -208,22 +208,22 @@ void FunctionMultiIf::executeImpl(Block & block, const ColumnNumbers & args, siz
{ {
/// Keep track of which columns are nullable. /// Keep track of which columns are nullable.
std::vector<UInt8> nullable_cols_map; std::vector<UInt8> nullable_cols_map;
nullable_cols_map.reserve(args.size()); nullable_cols_map.resize(args.size());
for (const auto & arg : args) for (const auto & arg : args)
{ {
const auto & col = block.unsafeGetByPosition(arg).column; const auto & col = block.unsafeGetByPosition(arg).column;
bool may_have_null = col->isNullable(); bool may_have_null = col->isNullable();
nullable_cols_map.push_back(static_cast<UInt8>(may_have_null)); nullable_cols_map[arg] = may_have_null ? 1 : 0;
} }
/// Keep track of which columns are null. /// Keep track of which columns are null.
std::vector<UInt8> null_cols_map; std::vector<UInt8> null_cols_map;
null_cols_map.reserve(args.size()); null_cols_map.resize(args.size());
for (const auto & arg : args) for (const auto & arg : args)
{ {
const auto & col = block.unsafeGetByPosition(arg).column; const auto & col = block.unsafeGetByPosition(arg).column;
bool has_null = col->isNull(); bool has_null = col->isNull();
null_cols_map.push_back(static_cast<UInt8>(has_null)); null_cols_map[arg] = has_null ? 1 : 0;
} }
auto null_map = std::make_shared<ColumnUInt8>(row_count); auto null_map = std::make_shared<ColumnUInt8>(row_count);

View File

@ -11,20 +11,20 @@ namespace DB
namespace namespace
{ {
void createNullValuesByteMap(Block & block, size_t result) void createNullValuesByteMap(Block & block, const ColumnNumbers & args, size_t result)
{ {
ColumnNullable & res_col = static_cast<ColumnNullable &>(*block.unsafeGetByPosition(result).column); ColumnNullable & res_col = static_cast<ColumnNullable &>(*block.unsafeGetByPosition(result).column);
for (size_t i = 0; i < block.columns(); ++i) for (const auto & arg : args)
{ {
if (i == result) if (arg == result)
continue; continue;
const ColumnWithTypeAndName & elem = block.unsafeGetByPosition(i); const ColumnWithTypeAndName & elem = block.unsafeGetByPosition(arg);
if (elem.column && elem.column.get()->isNullable()) if (elem.column && elem.column.get()->isNullable())
{ {
const ColumnNullable & concrete_col = static_cast<const ColumnNullable &>(*elem.column); const ColumnNullable & nullable_col = static_cast<const ColumnNullable &>(*elem.column);
res_col.updateNullValuesByteMap(concrete_col); res_col.updateNullValuesByteMap(nullable_col);
} }
} }
} }
@ -198,19 +198,19 @@ void IFunction::getLambdaArgumentTypes(DataTypes & arguments) const
getLambdaArgumentTypesImpl(arguments); getLambdaArgumentTypesImpl(arguments);
} }
Block IFunction::extractNonNullableBlock(const Block & block, const ColumnNumbers & arguments) /// Return a copy of a given block in which the specified columns are replaced by
/// their respective nested columns if they are nullable.
Block IFunction::extractNonNullableBlock(const Block & block, const ColumnNumbers args)
{ {
std::sort(args.begin(), args.end());
Block non_nullable_block; Block non_nullable_block;
ColumnNumbers args2 = arguments;
std::sort(args2.begin(), args2.end());
size_t pos = 0;
for (size_t i = 0; i < block.columns(); ++i) for (size_t i = 0; i < block.columns(); ++i)
{ {
const auto & col = block.unsafeGetByPosition(i); const auto & col = block.unsafeGetByPosition(i);
bool found = std::binary_search(args2.begin(), args2.end(), pos) && col.column && col.type; bool found = std::binary_search(args.begin(), args.end(), i) && col.column && col.type;
if (found && col.column.get()->isNullable()) if (found && col.column.get()->isNullable())
{ {
@ -220,12 +220,10 @@ Block IFunction::extractNonNullableBlock(const Block & block, const ColumnNumber
auto nullable_type = static_cast<const DataTypeNullable *>(col.type.get()); auto nullable_type = static_cast<const DataTypeNullable *>(col.type.get());
DataTypePtr nested_type = nullable_type->getNestedType(); DataTypePtr nested_type = nullable_type->getNestedType();
non_nullable_block.insert(pos, {nested_col, nested_type, col.name}); non_nullable_block.insert(i, {nested_col, nested_type, col.name});
} }
else else
non_nullable_block.insert(pos, col); non_nullable_block.insert(i, col);
++pos;
} }
return non_nullable_block; return non_nullable_block;
@ -249,8 +247,8 @@ void IFunction::perform(Block & block, const ColumnNumbers & arguments, size_t r
ColumnWithTypeAndName & dest_col = block.getByPosition(result); ColumnWithTypeAndName & dest_col = block.getByPosition(result);
dest_col.column = std::make_shared<ColumnNullable>(source_col.column); dest_col.column = std::make_shared<ColumnNullable>(source_col.column);
ColumnNullable & nullable_col = static_cast<ColumnNullable &>(*dest_col.column); ColumnNullable & nullable_col = static_cast<ColumnNullable &>(*dest_col.column);
nullable_col.getNullValuesByteMap() = std::make_shared<ColumnUInt8>(dest_col.column->size()); nullable_col.getNullValuesByteMap() = std::make_shared<ColumnUInt8>(dest_col.column->size(), 0);
createNullValuesByteMap(block, result); createNullValuesByteMap(block, arguments, result);
} }
else else
performer(block, arguments, result); performer(block, arguments, result);