dbms: Server: fixes [#METR-19266]

This commit is contained in:
Alexey Arno 2016-10-21 16:14:41 +03:00
parent 88ddba2782
commit ef2dd96ee4
2 changed files with 56 additions and 5 deletions

View File

@ -142,6 +142,8 @@ protected:
/// the "arguments" parameter is replaced with its respective nested
/// column if it is nullable.
static Block createBlockWithNestedColumns(const Block & block, ColumnNumbers args);
/// Similar function as above. Additionally transform the result type if needed.
static Block createBlockWithNestedColumns(const Block & block, ColumnNumbers args, size_t result);
private:
/// Strategy to apply when executing a function.
@ -164,7 +166,8 @@ private:
/// If required by the specified strategy, process the given block, then
/// return the processed block. Otherwise return an empty block.
Block preProcessBlock(Strategy strategy, const Block & block, const ColumnNumbers & args);
Block preProcessBlock(Strategy strategy, const Block & block, const ColumnNumbers & args,
size_t result);
/// If required by the specified strategy, post-process the result column.
void postProcessResult(Strategy strategy, Block & block, const Block & processed_block,

View File

@ -259,7 +259,7 @@ void IFunction::getLambdaArgumentTypes(DataTypes & arguments) const
void IFunction::execute(Block & block, const ColumnNumbers & args, size_t result)
{
auto strategy = chooseStrategy(block, args);
Block processed_block = preProcessBlock(strategy, block, args);
Block processed_block = preProcessBlock(strategy, block, args, result);
if (strategy != RETURN_NULL)
{
@ -273,7 +273,7 @@ void IFunction::execute(Block & block, const ColumnNumbers & args, size_t result
void IFunction::execute(Block & block, const ColumnNumbers & args, const ColumnNumbers & prerequisites, size_t result)
{
auto strategy = chooseStrategy(block, args);
Block processed_block = preProcessBlock(strategy, block, args);
Block processed_block = preProcessBlock(strategy, block, args, result);
if (strategy != RETURN_NULL)
{
@ -307,7 +307,7 @@ IFunction::Strategy IFunction::chooseStrategy(const Block & block, const ColumnN
return DIRECTLY_EXECUTE;
}
Block IFunction::preProcessBlock(Strategy strategy, const Block & block, const ColumnNumbers & args)
Block IFunction::preProcessBlock(Strategy strategy, const Block & block, const ColumnNumbers & args, size_t result)
{
if (strategy == DIRECTLY_EXECUTE)
return {};
@ -317,7 +317,7 @@ Block IFunction::preProcessBlock(Strategy strategy, const Block & block, const C
{
/// Run the function on a block whose nullable columns have been replaced
/// with their respective nested columns.
return createBlockWithNestedColumns(block, args);
return createBlockWithNestedColumns(block, args, result);
}
else
throw Exception{"IFunction: internal error", ErrorCodes::LOGICAL_ERROR};
@ -389,5 +389,53 @@ Block IFunction::createBlockWithNestedColumns(const Block & block, ColumnNumbers
return res;
}
Block IFunction::createBlockWithNestedColumns(const Block & block, ColumnNumbers args, size_t result)
{
std::sort(args.begin(), args.end());
Block res;
size_t j = 0;
for (size_t i = 0; i < block.columns(); ++i)
{
const auto & col = block.unsafeGetByPosition(i);
bool is_inserted = false;
if (i == args[j])
{
++j;
if (col.column->isNullable())
{
auto nullable_col = static_cast<const ColumnNullable *>(col.column.get());
const ColumnPtr & nested_col = nullable_col->getNestedColumn();
auto nullable_type = static_cast<const DataTypeNullable *>(col.type.get());
const DataTypePtr & nested_type = nullable_type->getNestedType();
res.insert(i, {nested_col, nested_type, col.name});
is_inserted = true;
}
}
else if (i == result)
{
if (col.type->isNullable())
{
auto nullable_type = static_cast<const DataTypeNullable *>(col.type.get());
const DataTypePtr & nested_type = nullable_type->getNestedType();
res.insert(i, {nullptr, nested_type, col.name});
is_inserted = true;
}
}
if (!is_inserted)
res.insert(i, col);
}
return res;
}
}