mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
EXCHANGE PARTITION fails with ERROR 1736 (Tables have different definitions) when tables contain generated columns with AND/OR conditions, even when the expressions are logically equivalent. This occurs because when expressions are re-parsed (e.g., via CREATE TABLE ... LIKE), the order of arguments in AND/OR conditions may change, but the comparison was order-sensitive. The Item_cond::eq() method was implemented to perform set-based comparison for commutative AND/OR operations. The set-based comparison algorithm ensures that two Item_cond expressions are considered equal if they contain the same set of equivalent arguments, regardless of order. Added comprehensive test case covering: - Generated columns with OR conditions - Generated columns with AND conditions - Multiple generated columns with different AND/OR combinations - Nested AND/OR conditions The fix allows EXCHANGE PARTITION to succeed when expressions are logically equivalent but have different argument ordering, which is correct behavior since AND/OR operations are commutative. MDEV-38757 Limit unordered vcol condition comparison to EXCHANGE PARTITION Review follow-up to the previous commit, which made Item_cond::eq() compare AND/OR argument lists as sets for every caller. That changed equality semantics globally and broke main.derived_cond_pushdown, where conditions that eq() started reporting as equal were dropped from attached_condition. Reordering AND/OR operands also changes evaluation order, which is observable when operands are functions, so the relaxed comparison must not be the default. Item::Eq_config gains an unordered_conditions flag, defaulting to false, next to the existing binary_cmp and omit_table_names flags. Item_cond::eq() compares its argument lists as sets only when that flag is set, and otherwise reports two distinct Item_cond objects as unequal, as it did before this patch series. The flag is threaded through Virtual_column_info::is_equal() and a new mysql_compare_tables() parameter, and only Sql_cmd_alter_table_exchange_partition passes it as true, so the relaxed comparison stays confined to the EXCHANGE PARTITION metadata check. The set comparison tests containment in both directions rather than comparing element counts, so an expression also matches a form that repeats one of its terms, for example col1 > 10 and col2 < 100 or col3 > 50 col3 > 50 or col1 > 10 and col2 < 100 or col3 > 50 Test 5 of parts.partition_exchange_generated_columns covers that case.
9.6 KiB
9.6 KiB