Merge pull request #73022 from ClickHouse/backport/24.9/72854

Backport #72854 to 24.9: Fix update of all columns in presence of `_block_number` column
This commit is contained in:
robot-clickhouse-ci-1 2024-12-10 17:13:07 +01:00 committed by GitHub
commit fe9098ce97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 5 deletions

View File

@ -63,7 +63,6 @@ namespace ErrorCodes
extern const int NO_SUCH_COLUMN_IN_TABLE; extern const int NO_SUCH_COLUMN_IN_TABLE;
extern const int CANNOT_UPDATE_COLUMN; extern const int CANNOT_UPDATE_COLUMN;
extern const int UNEXPECTED_EXPRESSION; extern const int UNEXPECTED_EXPRESSION;
extern const int THERE_IS_NO_COLUMN;
extern const int ILLEGAL_STATISTICS; extern const int ILLEGAL_STATISTICS;
} }
@ -593,10 +592,6 @@ void MutationsInterpreter::prepare(bool dry_run)
if (available_columns_set.emplace(name).second) if (available_columns_set.emplace(name).second)
available_columns.push_back(name); available_columns.push_back(name);
} }
else if (!available_columns_set.contains(name))
{
throw Exception(ErrorCodes::THERE_IS_NO_COLUMN, "Column {} is updated but not requested to read", name);
}
updated_columns.insert(name); updated_columns.insert(name);
} }
@ -1097,6 +1092,21 @@ void MutationsInterpreter::prepareMutationStages(std::vector<Stage> & prepared_s
} }
} }
auto storage_columns = metadata_snapshot->getColumns().getNamesOfPhysical();
/// Add persistent virtual columns if the whole part is rewritten,
/// because we should preserve them in parts after mutation.
if (prepared_stages.back().isAffectingAllColumns(storage_columns))
{
for (const auto & column_name : available_columns)
{
if (column_name == RowExistsColumn::name && has_filters && !deleted_mask_updated)
continue;
prepared_stages.back().output_columns.insert(column_name);
}
}
/// Now, calculate `expressions_chain` for each stage except the first. /// Now, calculate `expressions_chain` for each stage except the first.
/// Do it backwards to propagate information about columns required as input for a stage to the previous stage. /// Do it backwards to propagate information about columns required as input for a stage to the previous stage.
for (int64_t i = prepared_stages.size() - 1; i >= 0; --i) for (int64_t i = prepared_stages.size() - 1; i >= 0; --i)

View File

@ -171,7 +171,12 @@ private:
Source source; Source source;
StorageMetadataPtr metadata_snapshot; StorageMetadataPtr metadata_snapshot;
MutationCommands commands; MutationCommands commands;
/// List of columns in table or in data part that can be updated by mutation.
/// If mutation affects all columns (e.g. DELETE), all of this columns
/// must be returned by pipeline created in MutationsInterpreter.
Names available_columns; Names available_columns;
ContextPtr context; ContextPtr context;
Settings settings; Settings settings;
SelectQueryOptions select_limits; SelectQueryOptions select_limits;

View File

@ -0,0 +1,4 @@
2
3
2
3

View File

@ -0,0 +1,27 @@
DROP TABLE IF EXISTS t_block_number_mut;
SET mutations_sync = 2;
CREATE TABLE t_block_number_mut (n int) ENGINE = MergeTree ORDER BY tuple() SETTINGS enable_block_number_column = 1, min_bytes_for_wide_part = 0;
INSERT INTO t_block_number_mut VALUES (1) (2);
OPTIMIZE TABLE t_block_number_mut FINAL;
ALTER TABLE t_block_number_mut UPDATE n = n + 1 WHERE 1;
SELECT * FROM t_block_number_mut;
DROP TABLE IF EXISTS t_block_number_mut;
CREATE TABLE t_block_number_mut (n int) ENGINE = MergeTree ORDER BY tuple() SETTINGS enable_block_number_column = 1, min_bytes_for_wide_part = '1G';
INSERT INTO t_block_number_mut VALUES (1) (2);
OPTIMIZE TABLE t_block_number_mut FINAL;
ALTER TABLE t_block_number_mut UPDATE n = n + 1 WHERE 1;
SELECT * FROM t_block_number_mut;
DROP TABLE IF EXISTS t_block_number_mut;