fix: update: nested materialized columns: size check fixes

This commit is contained in:
Eliot Hautefeuille 2024-04-18 23:40:27 +02:00
parent 91a4d08a54
commit 520aa02059
No known key found for this signature in database
GPG Key ID: 12F5BC7AF4B43462
3 changed files with 56 additions and 1 deletions

View File

@ -508,6 +508,7 @@ static void validateUpdateColumns(
/// because their sizes couldn't change, since sizes of all nested subcolumns must be consistent. /// because their sizes couldn't change, since sizes of all nested subcolumns must be consistent.
static std::optional<std::vector<ASTPtr>> getExpressionsOfUpdatedNestedSubcolumns( static std::optional<std::vector<ASTPtr>> getExpressionsOfUpdatedNestedSubcolumns(
const String & column_name, const String & column_name,
NameSet affected_materialized,
const NamesAndTypesList & all_columns, const NamesAndTypesList & all_columns,
const std::unordered_map<String, ASTPtr> & column_to_update_expression) const std::unordered_map<String, ASTPtr> & column_to_update_expression)
{ {
@ -520,6 +521,10 @@ static std::optional<std::vector<ASTPtr>> getExpressionsOfUpdatedNestedSubcolumn
auto split = Nested::splitName(column.name); auto split = Nested::splitName(column.name);
if (isArray(column.type) && split.first == source_name && !split.second.empty()) if (isArray(column.type) && split.first == source_name && !split.second.empty())
{ {
// Materialized nested columns shall never be part of the update expression
if (affected_materialized.contains(column.name))
continue ;
auto it = column_to_update_expression.find(column.name); auto it = column_to_update_expression.find(column.name);
if (it == column_to_update_expression.end()) if (it == column_to_update_expression.end())
return {}; return {};
@ -655,7 +660,10 @@ void MutationsInterpreter::prepare(bool dry_run)
if (materialized_it != column_to_affected_materialized.end()) if (materialized_it != column_to_affected_materialized.end())
for (const auto & mat_column : materialized_it->second) for (const auto & mat_column : materialized_it->second)
affected_materialized.emplace(mat_column); affected_materialized.emplace(mat_column);
}
for (const auto & [column_name, update_expr] : command.column_to_update_expression)
{
/// When doing UPDATE column = expression WHERE condition /// When doing UPDATE column = expression WHERE condition
/// we will replace column to the result of the following expression: /// we will replace column to the result of the following expression:
/// ///
@ -689,7 +697,7 @@ void MutationsInterpreter::prepare(bool dry_run)
{ {
std::shared_ptr<ASTFunction> function = nullptr; std::shared_ptr<ASTFunction> function = nullptr;
auto nested_update_exprs = getExpressionsOfUpdatedNestedSubcolumns(column_name, all_columns, command.column_to_update_expression); auto nested_update_exprs = getExpressionsOfUpdatedNestedSubcolumns(column_name, affected_materialized, all_columns, command.column_to_update_expression);
if (!nested_update_exprs) if (!nested_update_exprs)
{ {
function = makeASTFunction("validateNestedArraySizes", function = makeASTFunction("validateNestedArraySizes",

View File

@ -0,0 +1,3 @@
5555 ['moto','hello'] ['chocolatine','croissant'] [3159487597665552601,10142490492830962361] [17245759883905314919,3957103312270590367]
5555 ['hello'] ['croissant'] [10142490492830962361] [3957103312270590367]
5555 ['hello'] ['croissant au chocolat'] [10142490492830962361] [6230099869648002788]

View File

@ -0,0 +1,44 @@
SET asterisk_include_materialized_columns = 1 ;
CREATE TABLE elements
(
`id` UInt32,
`nested.key` Array(String),
`nested.value` Array(String),
`nested.key_hashed` Array(UInt64) MATERIALIZED arrayMap(x -> sipHash64(x), nested.key),
`nested.val_hashed` Array(UInt64) MATERIALIZED arrayMap(x -> sipHash64(x), nested.value),
)
ENGINE = Memory ;
INSERT INTO elements (id,`nested.key`,`nested.value`) VALUES (5555, ['moto', 'hello'],['chocolatine', 'croissant']);
SELECT * FROM elements ;
ALTER TABLE elements
UPDATE
`nested.key` = arrayFilter(
(c, k, v) -> NOT (match(k, '.*') AND match(v, 'chocolatine')),
`nested.key`, `nested.key`, `nested.value`
),
`nested.value` = arrayFilter(
(c, k, v) -> NOT (match(k, '.*') AND match(v, 'chocolatine')),
`nested.value`, `nested.key`, `nested.value`
)
WHERE id = 5555 AND 1=1
SETTINGS mutations_sync = 1 ;
SELECT * FROM elements ;
ALTER TABLE elements
UPDATE
`nested.value` = arrayMap(x -> concat(x, ' au chocolat'), `nested.value`)
WHERE id = 5555 AND 1=1
SETTINGS mutations_sync = 1 ;
SELECT * FROM elements ;