mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
Failure: - wsrep_rec_get_foreign_key() returned DB_ERROR when a write set key exceeded WSREP_MAX_SUPPORTED_KEY_LENGTH; the caller does not know DB_ERROR and calls ib::fatal(). - wsrep_fk_key_space_left() needed two bytes for a NULL column instead of one; only the flag byte is ever written for NULL. - Cutting a whole number, float or double to fit the remaining buffer produces a different value, not a shorter one, and for a float or double not even a valid one: mach_float_read()/mach_double_read() read a fixed 4 or 8 bytes regardless, past an assertion in a debug build and past the buffer itself in a release one. - wsrep_store_key_val_for_row()'s equivalent fixed-length branch had the same unchecked copy, reachable only in theory given InnoDB's own index length limit, but inconsistent with every other branch in that function. - The same function normalized a VARCHAR column's collation weights up to 3072 bytes while wsrep_rec_get_foreign_key() normalized it up to 3500, so the two produced a different key for a value whose normalized form falls between the two limits. - wsrep_store_key_val_for_row() kept iterating columns after one did not fit, relying on every later branch clamping to zero rather than stopping outright. - MW-292 matched its two debug sync waiters by substring, not an exact match, independent of wait order. Fix: - wsrep_rec_get_foreign_key() now cuts the key the same way wsrep_store_key_val_for_row() does, reports the cut as a warning (ER_TOO_LONG_KEY under strict mode), and returns DB_TOO_BIG_RECORD. - wsrep_fk_key_space_left() takes a fixed_len flag: a whole number, float or double must fit in full or is left out of the key entirely, the same way a value that does not fit even one byte already was. - wsrep_store_key_val_for_row() applies the same all-or-nothing rule to its own fixed-length branch, reusing get_innobase_type_from_mysql_type() so both functions agree on which types that covers, and now stops storing further columns as soon as one does not fit, in every branch. - wsrep_store_key_val_for_row()'s VARCHAR branch normalizes up to WSREP_MAX_SUPPORTED_KEY_LENGTH, matching wsrep_rec_get_foreign_key(), with its buffer grown to match. Test: - galera_ws_datatypes.test and galera_ws_datatypes_plugin.test cover every MariaDB data type in a primary key, unique key, plain key and foreign key (referencing a primary or unique key), including NULL foreign key columns. - galera_ws_datatypes_fixed_length.test covers a foreign key column cut to fewer bytes than a whole number, float or double needs. - galera_ws_datatypes_varchar_cap.test covers a VARCHAR foreign key column whose normalized form falls between the two limits above. Assisted-by: https://mariadb.org/governance/governance-ai-policy/