mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-17 21:24:28 +00:00
AddingDefaultsBlockInputStream fixed types optimisation
This commit is contained in:
parent
c642e16ee1
commit
811b824b01
@ -1,19 +1,33 @@
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnsCommon.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/FilterDescription.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <Interpreters/evaluateMissingDefaults.h>
|
||||
#include <DataStreams/AddingDefaultsBlockInputStream.h>
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnsCommon.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/FilterDescription.h>
|
||||
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <DataTypes/DataTypeDate.h>
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypeEnum.h>
|
||||
#include <DataTypes/DataTypeUUID.h>
|
||||
#include <DataTypes/DataTypeString.h>
|
||||
#include <DataTypes/DataTypeFixedString.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
|
||||
extern const int TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
|
||||
@ -61,30 +75,25 @@ Block AddingDefaultsBlockInputStream::readImpl()
|
||||
continue;
|
||||
|
||||
size_t block_column_position = res.getPositionByName(column_name);
|
||||
const ColumnWithTypeAndName & column_read = res.getByPosition(block_column_position);
|
||||
|
||||
if (column_read.column->size() != column_def.column->size())
|
||||
throw Exception("Mismach column sizes while adding defaults", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
||||
|
||||
ColumnWithTypeAndName & column_read = res.getByPosition(block_column_position);
|
||||
const auto & defaults_mask = delayed_defaults.getDefaultsBitmask(block_column_position);
|
||||
|
||||
checkCalculated(column_read, column_def, defaults_mask.size());
|
||||
|
||||
if (!defaults_mask.empty())
|
||||
{
|
||||
MutableColumnPtr column_mixed = column_read.column->cloneEmpty();
|
||||
|
||||
for (size_t row_idx = 0; row_idx < column_read.column->size(); ++row_idx)
|
||||
/// TODO: FixedString
|
||||
if (isColumnedAsNumber(column_read.type) || isDecimal(column_read.type))
|
||||
{
|
||||
if (row_idx < defaults_mask.size() && defaults_mask[row_idx])
|
||||
{
|
||||
if (column_def.column->isColumnConst())
|
||||
column_mixed->insert((*column_def.column)[row_idx]);
|
||||
else
|
||||
column_mixed->insertFrom(*column_def.column, row_idx);
|
||||
}
|
||||
else
|
||||
column_mixed->insertFrom(*column_read.column, row_idx);
|
||||
MutableColumnPtr column_mixed = (*std::move(column_read.column)).mutate();
|
||||
mixNumberColumns(column_read.type->getTypeId(), column_mixed, column_def.column, defaults_mask);
|
||||
column_read.column = std::move(column_mixed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MutableColumnPtr column_mixed = mixColumns(column_read, column_def, defaults_mask);
|
||||
mixed_columns.emplace(block_column_position, std::move(column_mixed));
|
||||
}
|
||||
|
||||
mixed_columns.emplace(std::make_pair(block_column_position, std::move(column_mixed)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,4 +113,95 @@ Block AddingDefaultsBlockInputStream::readImpl()
|
||||
return res;
|
||||
}
|
||||
|
||||
void AddingDefaultsBlockInputStream::checkCalculated(const ColumnWithTypeAndName & col_read,
|
||||
const ColumnWithTypeAndName & col_defaults,
|
||||
size_t defaults_needed) const
|
||||
{
|
||||
size_t column_size = col_read.column->size();
|
||||
|
||||
if (column_size != col_defaults.column->size())
|
||||
throw Exception("Mismach column sizes while adding defaults", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
||||
|
||||
if (column_size < defaults_needed)
|
||||
throw Exception("Unexpected defaults count", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
||||
|
||||
if (col_read.type->getTypeId() != col_defaults.type->getTypeId())
|
||||
throw Exception("Mismach column types while adding defaults", ErrorCodes::TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
void AddingDefaultsBlockInputStream::mixNumberColumns(TypeIndex type_idx, MutableColumnPtr & column_mixed, const ColumnPtr & column_defs,
|
||||
const BlockMissingValues::RowsBitMask & defaults_mask) const
|
||||
{
|
||||
auto call = [&](const auto & types) -> bool
|
||||
{
|
||||
using Types = std::decay_t<decltype(types)>;
|
||||
using DataType = typename Types::LeftType;
|
||||
|
||||
if constexpr (!std::is_same_v<DataType, DataTypeString> && !std::is_same_v<DataType, DataTypeFixedString>)
|
||||
{
|
||||
using FieldType = typename DataType::FieldType;
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<FieldType>, ColumnDecimal<FieldType>, ColumnVector<FieldType>>;
|
||||
|
||||
auto col_read = typeid_cast<ColVecType *>(column_mixed.get());
|
||||
if (!col_read)
|
||||
return false;
|
||||
|
||||
typename ColVecType::Container & dst = col_read->getData();
|
||||
|
||||
if (auto const_col_defs = checkAndGetColumnConst<ColVecType>(column_defs.get()))
|
||||
{
|
||||
FieldType value = checkAndGetColumn<ColVecType>(const_col_defs->getDataColumnPtr().get())->getData()[0];
|
||||
|
||||
for (size_t i = 0; i < defaults_mask.size(); ++i)
|
||||
if (defaults_mask[i])
|
||||
dst[i] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (auto col_defs = checkAndGetColumn<ColVecType>(column_defs.get()))
|
||||
{
|
||||
auto & src = col_defs->getData();
|
||||
for (size_t i = 0; i < defaults_mask.size(); ++i)
|
||||
if (defaults_mask[i])
|
||||
dst[i] = src[i];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!callOnIndexAndDataType<void>(type_idx, call))
|
||||
throw Exception("Unexpected type on mixNumberColumns", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
MutableColumnPtr AddingDefaultsBlockInputStream::mixColumns(const ColumnWithTypeAndName & col_read,
|
||||
const ColumnWithTypeAndName & col_defaults,
|
||||
const BlockMissingValues::RowsBitMask & defaults_mask) const
|
||||
{
|
||||
size_t column_size = col_read.column->size();
|
||||
size_t defaults_needed = defaults_mask.size();
|
||||
|
||||
MutableColumnPtr column_mixed = col_read.column->cloneEmpty();
|
||||
|
||||
for (size_t i = 0; i < defaults_needed; ++i)
|
||||
{
|
||||
if (defaults_mask[i])
|
||||
{
|
||||
if (col_defaults.column->isColumnConst())
|
||||
column_mixed->insert((*col_defaults.column)[i]);
|
||||
else
|
||||
column_mixed->insertFrom(*col_defaults.column, i);
|
||||
}
|
||||
else
|
||||
column_mixed->insertFrom(*col_read.column, i);
|
||||
}
|
||||
|
||||
for (size_t i = defaults_needed; i < column_size; ++i)
|
||||
column_mixed->insertFrom(*col_read.column, i);
|
||||
|
||||
return column_mixed;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,12 @@ private:
|
||||
Block header;
|
||||
const ColumnDefaults column_defaults;
|
||||
const Context & context;
|
||||
|
||||
void checkCalculated(const ColumnWithTypeAndName & col_read, const ColumnWithTypeAndName & col_defaults, size_t needed) const;
|
||||
MutableColumnPtr mixColumns(const ColumnWithTypeAndName & col_read, const ColumnWithTypeAndName & col_defaults,
|
||||
const BlockMissingValues::RowsBitMask & defaults_mask) const;
|
||||
void mixNumberColumns(TypeIndex type_idx, MutableColumnPtr & col_mixed, const ColumnPtr & col_defaults,
|
||||
const BlockMissingValues::RowsBitMask & defaults_mask) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -512,6 +512,13 @@ inline bool isNumber(const T & data_type)
|
||||
return which.isInt() || which.isUInt() || which.isFloat();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool isColumnedAsNumber(const T & data_type)
|
||||
{
|
||||
WhichDataType which(data_type);
|
||||
return which.isInt() || which.isUInt() || which.isFloat() || which.isDateOrDateTime() || which.isUUID();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool isString(const T & data_type)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user