EXPORT PARTITION with position matching + extra columns in source - #2111
EXPORT PARTITION with position matching + extra columns in source#2111k-morozov wants to merge 7 commits into
Conversation
0d6a23a to
267e79f
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
All current CI failures on this PR are pre-existing / unrelated to this PR's changes:
No failure traces back to the changes in this PR. |
| enum class MergeTreePartExportSchemaMismatchMode : uint8_t | ||
| { | ||
| strict, | ||
| ignore_extra_source_columns_by_position, |
There was a problem hiding this comment.
I think name is confusing.
I expect that I can say "ignore columns at positions 3, 5 and 7", but actually it ignores last columns.
May be something like ignore_trailing_extra_columns?
/I'm not good in naming anyway/
There was a problem hiding this comment.
I thought to use 2 modes: ignore_extra_source_columns_by_position and ignore_extra_source_columns_by_name (in the future). Thank you for the example — I agree that the current naming is really confusing.
In the current name, the _by_position suffix meant that all columns from the prefix are matched 1-to-1, and the rest are ignored. I like the name ignore_trailing_extra_columns as the base. I'll suggest adding information that this is about the source. But I also wanted to convey that the columns in the prefix are matched sequentially:
ignore_trailing_extra_source_columns_match_by_sequence
There was a problem hiding this comment.
I think it must be a table property in case with several different politics. If you accidentally export one partition with one politic and another partition with different, you get a lot of pain, because same Iceberg column will contain different real data.
And a big question here is wat to do with hybrid tables. When different politics are possible, hybrid must have a knowledge about used to join results from MergeTree and Iceberg tables correctly.
There was a problem hiding this comment.
I think it must be a table property in case with several different politics. If you accidentally export one partition with one politic and another partition with different, you get a lot of pain, because same Iceberg column will contain different real data.
With the current two modes this cannot corrupt data: both strict and ignore_extra_source_columns_by_position build the exact same positional prefix mapping - destination column N always receives source column N. The only difference is whether the export is allowed at all when the column counts diverge. So exporting one partition under strict and another under ignore_extra yields consistent data in the shared columns. Also note the mode is already pinned in the partition-export manifest, so it cannot change mid-operation.
There was a problem hiding this comment.
And a big question here is wat to do with hybrid tables. When different politics are possible, hybrid must have a knowledge about used to join results from MergeTree and Iceberg tables correctly.
Hybrid doesn't need to know the export policy: it validates that every segment provides all columns of the declared schema at CREATE/ATTACH and throws BAD_ARGUMENTS (missing column ...) otherwise. So there is no silent-mismerge failure mode - either the schemas are reconcilable (Hybrid reads by name, with auto-cast) or it's a hard error. I've added an integration test test_export_part_ignore_extra_column_breaks_hybrid_over_source_and_destination covering the full lifecycle.
There was a problem hiding this comment.
I mean not two current modes, but plans to add third variant.
Anyway, this question can be solved in future, when different modes have been implemented.
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
e74a863 to
80b30c4
Compare
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
|
PR CI Triage Stateless, integration, and S3 export regression all passed. The only substantive red job is Iceberg_2; SQLLogic / Grype / FinishCI are infra noise. Root Cause Analysis
Looks good from a CI perspective. |
|
Added auto tests in https://github.com/Altinity/clickhouse-regression/blob/main/iceberg/tests/export_partition/settings.py. No issues found so far. LGTM |
Closes: #1717
Problem.
EXPORT PART/EXPORT PARTITIONmatched source and destination columns positionally, exactly likeINSERT INTO dest SELECT * FROMsrc, and required the column count to match exactly. This is unnecessarily strict for a commonreal scenario: a MergeTree table's schema grows over time (new trailing columns added), but older partitions still need to be exported to an external table (Iceberg/object storage) whose schema was fixed when it was created. Such exports were rejected outright with
NUMBER_OF_COLUMNS_DOESNT_MATCH, with no way to just drop the newer columns and export the rest.Solution. Added the export_merge_tree_part_schema_mismatch_mode setting (default strict, preserving the old behavior). The new ignore_extra_source_columns_by_position mode allows the source to have more columns than the destination: the extra trailing source columns (by declared/readable position, the same order
INSERT SELECTuses) are dropped, both at synchronous validation time (verifyExportSchemaCastable, so a real mismatch still fails immediately atALTER TABLE ... EXPORTtime) and at actual data-export time (ExportPartTask::addExportConvertingActions, via a projection step before the existing positional CAST). The reverse direction — destination has more columns than source — is still always rejected in both modes.Known follow-up. Ignored columns are still fully read and decompressed from disk before being discarded in the projection step, so no I/O is saved. Skipping the read up front isn't safe as a naive truncation: a kept
ALIAS/MATERIALIZED column can legally forward-reference an ignored one, so it would need a real dependency-graph walk instead. Left as a possible future optimization
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Added the export_merge_tree_part_schema_mismatch_mode setting. With ignore_extra_source_columns_by_position (default: strict), EXPORT PART/EXPORT PARTITION allows a source table with extra trailing columns — they are simply
ignored instead of failing with NUMBER_OF_COLUMNS_DOESNT_MATCH.
Documentation entry for user-facing changes
...
CI/CD Options
Exclude tests:
Regression jobs to run: