Skip to content

Export partition - Positional column matching might lead to incorrect partitioning - #2134

Open
k-morozov wants to merge 6 commits into
antalya-26.3from
bugfix/antalya/26.3/export-incorect-order
Open

Export partition - Positional column matching might lead to incorrect partitioning#2134
k-morozov wants to merge 6 commits into
antalya-26.3from
bugfix/antalya/26.3/export-incorect-order

Conversation

@k-morozov

@k-morozov k-morozov commented Jul 30, 2026

Copy link
Copy Markdown

Closes: #2123

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Fixed ALTER TABLE ... EXPORT PART / EXPORT PARTITION silently writing values into the wrong destination columns when the source and destination tables declared the same PARTITION BY expression but with the partition key columns at different physical positions in the schema. The export now validates that partition key columns occupy the same position in both tables and is rejected with BAD_ARGUMENTS otherwise.

Documentation entry for user-facing changes

...

CI/CD Options

Exclude tests:

  • Fast test
  • Integration Tests
  • Stateless tests
  • Stateful tests
  • Performance tests
  • Aarch64 tests
  • All with ASAN
  • All with TSAN
  • All with MSAN
  • All with UBSAN
  • All with Coverage
  • All Regression
  • Disable CI Cache

Regression jobs to run:

  • Fast suites (mostly <1h)
  • Aggregate Functions (2h)
  • Alter (1.5h)
  • Benchmark (30m)
  • ClickHouse Keeper (1h)
  • Iceberg (2h)
  • LDAP (1h)
  • OAuth (5m)
  • Parquet (1.5h)
  • RBAC (1.5h)
  • SSL Server (1h)
  • S3 (2h)
  • S3 Export (2h)
  • Swarms (30m)
  • Tiered Storage (2h)

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

Workflow [PR], commit [faef463]

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>
@k-morozov
k-morozov force-pushed the bugfix/antalya/26.3/export-incorect-order branch from 9e63fd6 to 5322e48 Compare July 31, 2026 15:11
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
@k-morozov k-morozov changed the title [WIP] Export partition - Positional column matching might lead to incorrect partitioning Export partition - Positional column matching might lead to incorrect partitioning Aug 3, 2026
@k-morozov
k-morozov marked this pull request as ready for review August 3, 2026 12:54
@k-morozov

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faef463617

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

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".

Comment on lines +690 to +693
auto partition_key_columns = source_metadata->getColumnsRequiredForPartitionKey();
const std::unordered_set<String> partition_key_column_set(
std::make_move_iterator(partition_key_columns.begin()),
std::make_move_iterator(partition_key_columns.end()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize subcolumns before checking partition positions

When PARTITION BY references a subcolumn such as t.a, getColumnsRequiredForPartitionKey returns the subcolumn name, while source_columns contains only the top-level readable column t; consequently, this set never matches and the new positional check is skipped. For example, source columns (t Tuple(a UInt32), u Tuple(a UInt32)) and destination columns (u Tuple(a UInt32), t Tuple(a UInt32)), both partitioned by t.a, have positionally compatible types and pass validation, but export source u into destination t while constructing the partition from source t.a, silently mispartitioning the data. Map required subcolumns back to their top-level storage columns before constructing this set.

Useful? React with 👍 / 👎.

const auto & source_column = source_columns[i];
const auto & destination_column = destination_columns[i];

if (partition_key_column_set.contains(source_column.name) && source_column.name != destination_column.name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if partitioning is for several columns, and destination has same columns but in different order?
Both have columns 'a' and 'b', in same order, but source with partition by a,b, and destination partition by b,a.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or when destination has more columns in partition list than source.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the tests for simular cases:

What if partitioning is for several columns, and destination has same columns but in different order?
https://github.com/Altinity/ClickHouse/pull/2134/changes#diff-28d3e30160a3442e2b9ef01e3bf0b10b4c27de6a39efea3175ccec0a3f2d8949R1786

Or when destination has more columns in partition list than source.
https://github.com/Altinity/ClickHouse/pull/2134/changes#diff-28d3e30160a3442e2b9ef01e3bf0b10b4c27de6a39efea3175ccec0a3f2d8949R1799


namespace
{
std::optional<String> getDateTimeTimeZoneName(const DataTypePtr & type)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found method getExplicitTimeZoneOfDateTimeArgument like this.
And fragment from method extractTimeZoneNameFromFunctionArguments.
May be possible to reuse something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export partition - Positional column matching might lead to incorrect partitioning

2 participants