Fixed ColumnWithDictionsry insert functions. Added insertFromFullColumn and insertRangeFromFullColumn.

This commit is contained in:
Nikolai Kochetov 2018-05-04 13:48:09 +03:00
parent 040c5acc35
commit 9c696f40b9
3 changed files with 31 additions and 18 deletions

View File

@ -72,12 +72,36 @@ public:
}
void insert(const Field & x) override { getIndexes()->insert(Field(UInt64(getUnique()->uniqueInsert(x)))); }
void insertFrom(const IColumn & src, size_t n) override { getIndexes()->insert(getUnique()->uniqueInsertFrom(src, n)); }
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override
void insertFromFullColumn(const IColumn & src, size_t n)
{
getIndexes()->insert(getUnique()->uniqueInsertFrom(src, n));
}
void insertFrom(const IColumn & src, size_t n) override
{
if (!typeid_cast<const ColumnWithDictionary *>(&src))
throw Exception("Expected ColumnWithDictionary, got" + src.getName(), ErrorCodes::ILLEGAL_COLUMN);
auto & src_with_dict = static_cast<const ColumnWithDictionary &>(src);
size_t idx = src_with_dict.getIndexes()->getUInt(n);
insertFromFullColumn(*src_with_dict.getUnique()->getNestedColumn(), idx);
}
void insertRangeFromFullColumn(const IColumn & src, size_t start, size_t length)
{
auto inserted_indexes = getUnique()->uniqueInsertRangeFrom(src, start, length);
getIndexes()->insertRangeFrom(*inserted_indexes, 0, length);
}
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override
{
if (!typeid_cast<const ColumnWithDictionary *>(&src))
throw Exception("Expected ColumnWithDictionary, got" + src.getName(), ErrorCodes::ILLEGAL_COLUMN);
auto & src_with_dict = static_cast<const ColumnWithDictionary &>(src);
auto & src_nested = src_with_dict.getUnique()->getNestedColumn();
auto inserted_idx = getUnique()->uniqueInsertRangeFrom(*src_nested, 0, src_nested->size());
auto idx = inserted_idx->index(src_with_dict.getIndexes()->cut(start, length), 0);
getIndexes()->insertRangeFrom(*idx, 0, length);
}
void insertData(const char * pos, size_t length) override
{

View File

@ -145,9 +145,7 @@ void DataTypeWithDictionary::deserializeImpl(
(dictionary_type.get()->*func)(*temp_column, istr, std::forward<Args>(args)...);
/// Note: Insertion into ColumnWithDictionary from it's nested column may cause insertion from column to itself.
/// Generally it's wrong because column may reallocate memory before insertion.
column_with_dictionary.insertFrom(*temp_column, 0);
column_with_dictionary.insertFromFullColumn(*temp_column, 0);
}
template <typename ColumnType, typename IndexType>

View File

@ -306,24 +306,15 @@ void PreparedFunctionImpl::execute(Block & block, const ColumnNumbers & args, si
executeWithoutColumnsWithDictionary(temp_block, temp_numbers, 0);
auto & temp_res_col = temp_block.getByPosition(0).column;
auto & res_col = block.getByPosition(result);
res_col.column = res_col.type->createColumn();
auto col_wit_dict_ptr = res_col.type->createColumn();
auto * col_with_dict = checkAndGetColumn<ColumnWithDictionary>(res_col.column.get());
auto * col_with_dict = typeid_cast<ColumnWithDictionary *>(col_wit_dict_ptr.get());
if (!col_with_dict)
throw Exception("Expected ColumnWithDictionary, got" + res_col.column->getName(),
ErrorCodes::LOGICAL_ERROR);
auto & mut_col_with_dict = const_cast<ColumnWithDictionary &>(*col_with_dict);
if (indexes)
{
auto new_ind = mut_col_with_dict.getUnique()->uniqueInsertRangeFrom(*temp_res_col, 0, temp_res_col->size());
mut_col_with_dict.setIndexes(new_ind->index(indexes, 0)->assumeMutable());
}
else
{
mut_col_with_dict.insertRangeFrom(*temp_res_col, 0, temp_res_col->size());
}
col_with_dict->insertRangeFromFullColumn(*temp_res_col, 0, temp_res_col->size());
res_col.column = indexes ? col_with_dict->index(indexes, 0) : std::move(col_wit_dict_ptr);
return;
}
}