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 <Common/typeid_cast.h>
|
||||||
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Interpreters/ExpressionActions.h>
|
||||||
#include <Interpreters/evaluateMissingDefaults.h>
|
#include <Interpreters/evaluateMissingDefaults.h>
|
||||||
#include <DataStreams/AddingDefaultsBlockInputStream.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 DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
|
extern const int LOGICAL_ERROR;
|
||||||
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
|
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
|
||||||
|
extern const int TYPE_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -61,30 +75,25 @@ Block AddingDefaultsBlockInputStream::readImpl()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t block_column_position = res.getPositionByName(column_name);
|
size_t block_column_position = res.getPositionByName(column_name);
|
||||||
const ColumnWithTypeAndName & column_read = res.getByPosition(block_column_position);
|
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);
|
|
||||||
|
|
||||||
const auto & defaults_mask = delayed_defaults.getDefaultsBitmask(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())
|
if (!defaults_mask.empty())
|
||||||
{
|
{
|
||||||
MutableColumnPtr column_mixed = column_read.column->cloneEmpty();
|
/// TODO: FixedString
|
||||||
|
if (isColumnedAsNumber(column_read.type) || isDecimal(column_read.type))
|
||||||
for (size_t row_idx = 0; row_idx < column_read.column->size(); ++row_idx)
|
|
||||||
{
|
{
|
||||||
if (row_idx < defaults_mask.size() && defaults_mask[row_idx])
|
MutableColumnPtr column_mixed = (*std::move(column_read.column)).mutate();
|
||||||
{
|
mixNumberColumns(column_read.type->getTypeId(), column_mixed, column_def.column, defaults_mask);
|
||||||
if (column_def.column->isColumnConst())
|
column_read.column = std::move(column_mixed);
|
||||||
column_mixed->insert((*column_def.column)[row_idx]);
|
}
|
||||||
else
|
else
|
||||||
column_mixed->insertFrom(*column_def.column, row_idx);
|
{
|
||||||
}
|
MutableColumnPtr column_mixed = mixColumns(column_read, column_def, defaults_mask);
|
||||||
else
|
mixed_columns.emplace(block_column_position, std::move(column_mixed));
|
||||||
column_mixed->insertFrom(*column_read.column, row_idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mixed_columns.emplace(std::make_pair(block_column_position, std::move(column_mixed)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,4 +113,95 @@ Block AddingDefaultsBlockInputStream::readImpl()
|
|||||||
return res;
|
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;
|
Block header;
|
||||||
const ColumnDefaults column_defaults;
|
const ColumnDefaults column_defaults;
|
||||||
const Context & context;
|
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();
|
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>
|
template <typename T>
|
||||||
inline bool isString(const T & data_type)
|
inline bool isString(const T & data_type)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user