check dynamic columns of part before its commit

This commit is contained in:
Anton Popov 2023-02-03 02:58:28 +00:00
parent 0c13870eb1
commit 8ca602a148
4 changed files with 40 additions and 0 deletions

View File

@ -3393,6 +3393,28 @@ void MergeTreeData::checkPartDuplicate(MutableDataPartPtr & part, Transaction &
}
}
void MergeTreeData::checkPartDynamicColumns(MutableDataPartPtr & part, DataPartsLock & /*lock*/) const
{
auto metadata_snapshot = getInMemoryMetadataPtr();
const auto & columns = metadata_snapshot->getColumns();
if (!hasDynamicSubcolumns(columns))
return;
const auto & part_columns = part->getColumns();
for (const auto & part_column : part_columns)
{
auto storage_column = columns.getPhysical(part_column.name);
if (!storage_column.type->hasDynamicSubcolumns())
continue;
auto concrete_storage_column = object_columns.getPhysical(part_column.name);
/// It will throw if types are incompatible.
getLeastCommonTypeForDynamicColumns(storage_column.type, {concrete_storage_column.type, part_column.type}, true);
}
}
void MergeTreeData::preparePartForCommit(MutableDataPartPtr & part, Transaction & out_transaction, bool need_rename)
{
part->is_temp = false;
@ -3427,6 +3449,7 @@ bool MergeTreeData::addTempPart(
checkPartPartition(part, lock);
checkPartDuplicate(part, out_transaction, lock);
checkPartDynamicColumns(part, lock);
DataPartPtr covering_part;
DataPartsVector covered_parts = getActivePartsToReplace(part->info, part->name, covering_part, lock);
@ -3467,6 +3490,7 @@ bool MergeTreeData::renameTempPartAndReplaceImpl(
part->assertState({DataPartState::Temporary});
checkPartPartition(part, lock);
checkPartDuplicate(part, out_transaction, lock);
checkPartDynamicColumns(part, lock);
PartHierarchy hierarchy = getPartHierarchy(part->info, DataPartState::Active, lock);

View File

@ -1417,6 +1417,7 @@ private:
/// Checking that candidate part doesn't break invariants: correct partition
void checkPartPartition(MutableDataPartPtr & part, DataPartsLock & lock) const;
void checkPartDuplicate(MutableDataPartPtr & part, Transaction & transaction, DataPartsLock & lock) const;
void checkPartDynamicColumns(MutableDataPartPtr & part, DataPartsLock & lock) const;
/// Preparing itself to be committed in memory: fill some fields inside part, add it to data_parts_indexes
/// in precommitted state and to transaction

View File

@ -0,0 +1 @@
{"b":"1","c":{"k1":[1,2]}}

View File

@ -0,0 +1,14 @@
SET allow_experimental_object_type = 1;
DROP TABLE IF EXISTS t_json_attach_partition;
CREATE TABLE t_json_attach_partition(b UInt64, c JSON) ENGINE = MergeTree ORDER BY tuple();
INSERT INTO t_json_attach_partition FORMAT JSONEachRow {"b": 1, "c" : {"k1": 1}};
ALTER TABLE t_json_attach_partition DETACH PARTITION tuple();
INSERT INTO t_json_attach_partition FORMAT JSONEachRow {"b": 1, "c" : {"k1": [1, 2]}};
ALTER TABLE t_json_attach_partition ATTACH PARTITION tuple(); -- { serverError TYPE_MISMATCH }
SELECT * FROM t_json_attach_partition FORMAT JSONEachRow;
DROP TABLE t_json_attach_partition;