Home - Waterfall Grid T-Grid Console Builders Recent Builds Buildslaves Changesources - JSON API - About

Console View


Categories: connectors experimental galera main
Legend:   Passed Failed Warnings Failed Again Running Exception Offline No data

connectors experimental galera main
Kristian Nielsen
Semi-sync: Clean up incorrect file/pos comparisons

The semi-sync code has a number of places where it compares pairs of
(filename,offset) for which is larger than the other.

The filename comparisons are done using strcmp(), which is wrong. Filenames
will compare wrong when they wrap from eg. bin-999999 to bin-1000000, and
user can also rename log files which can likewise break comparisons.

Further, the comparisons are completely unnecessary, as all the transactions
to be waited for are already stored in a linear list in order _and_ in a
hash table. So the code can simply use the existing hash table look and list
traversal to determine status and sequence of the waited-for transactions.

So this patch removes all the comparisons for larger/smaller, leaving only
comparisons for equality and effectively making the (filename,offset) pairs
just opaque transaction identifiers. And also removes a few other related
pieces of dead/unnecessary code.

Signed-off-by: Kristian Nielsen <[email protected]>
Khaled Riyad
MDEV-40377 Change Server source code to point to new docs (12.3 part)

Replace the remaining Knowledge Base links with their MariaDB
Documentation equivalents, including the 838 URLs in the help tables.
Only URLs change in fill_help_tables.sql.

fill_help_tables.sql conflicts on merge upward; keep the target
branch's version.
Oleg Smirnov
InnoDB: fix unlatched right-move in the parallel scan partitioner
drrtuy
feat: MDEV-40672 implement basic support for the pluggable aggregate functions
Alexey (Holyfoot) Botchkov
MDEV-40394 XML schema fails on self-referencing type.

Copy XMLSchema_user_type information when the type is used recursively.
Copies that were once created are stored in m_c_free and then reused
later to avoid memory issues.
XMLSchema_item::is_validate_done() replaced with ::end_validation().
XMLSchema_group_def::check_type() now checks for circular groups.
Oleg Smirnov
Extract parallel logic from ha_innobase to separate files
Kristian Nielsen
Semi-sync: Implement support for using GTID in semi-sync ACKs

Implement the necessary logic in class Repl_semi_sync_master_gtid and
related code, so that the semi-sync master can request the slave to put the
GTID in the reply ACK packet, instead of the filename/offset.

In GTID mode, when a slave connects (which it should do using a GTID start
position), the latest GTID in the starting position (if any), as determined
by the list of transactions pending acks, is used as the point at which to
implicit ACK anything pending.

The semi-sync logic is otherwise unchanged, in GTID mode it just uses the
GTID as the transaction identifier instead of the file/pos of the end of the
event group.

This patch only enables the GTID-based semisync for binlog-in-engine, but
the mode works with old binlog implementation as well, and passes all tests
(if enabled by code change).

Signed-off-by: Kristian Nielsen <[email protected]>
Sergei Golubchik
debian, again
Brandon Nesterenko
Disable rpl_parallel_multi_domain_xa

MDEV-34104 describes why this test fails. It was filed 2 years ago, but
the fix is complex, and we keep this failing test around hurting all
other devs. The fix is planned, once finished, we can re-enable this
test.

Signed-off-by: Brandon Nesterenko <[email protected]>
Khaled Riyad
MDEV-40377 Change Server source code to point to new docs (10.11 part)

Replace the remaining Knowledge Base links with their MariaDB
Documentation equivalents, and fix the 14 help table URLs pointing at
/README pages that do not exist. Only URLs change in
fill_help_tables.sql.

fill_help_tables.sql conflicts on merge upward; keep the target
branch's version.
Dave Gosselin
MDEV-15066:  Filter geometry parts by bounding box before the scan

Implements a pre-filtering step to limit the polygons considered by
ST_Intersects and ST_Disjoint to those whose bounding box overlaps the
other operand.

The probe polygon overlaps the bounding box of seven rows in a table
of 239 country outlines.  Four of those rows are multipolygons of 346,
213, 120 and 21 polygons but not one of those 700 polygons overlaps
with the probe.  Yet, ST_Intersects stored all 700 into the scan.

A polygon whose bounding box does not overlap the other operand cannot
intersect it, yet the cost of the scan grows with the number of
polygons considered.  ST_Intersects and ST_Disjoint now leave such
polygons out.  Multipoint, multilinestring, multipolygon and geometry
collection each count the parts that pass the filter and store only
those.  A geometry of one part is unchanged.

Co-Authored-By: Claude Opus 5 <[email protected]>
Oleg Smirnov
Incorporate a pointer to the coordinator into worker context
Khaled Riyad
MDEV-40377 Change Server source code to point to new docs (11.4 part)

Replace the remaining Knowledge Base links with their MariaDB
Documentation equivalents, including the 838 URLs in the help tables.
Only URLs change in fill_help_tables.sql.

fill_help_tables.sql conflicts on merge upward; keep the target
branch's version. .github/pull_request_template.md is deleted in 12.3;
keep the deletion there.
Thirunarayanan Balathandayuthapani
- Make dict_table_t::query_cache as Atomic_relaxed because it is written on every table open
and read by FOREIGN KEY cascades running on other connections.
- Set it also in innobase_copy_frm_flags_from_create_info(), so that
SQL_CACHE=0 is honoured after CREATE TABLE, TRUNCATE TABLE and ALTER TABLE ... ALGORITHM=COPY,
and set it outside of innodb_copy_stat_flags(), which skips temporary tables.
- trx_t::commit_tables(): skip query_cache_inv_trx_id, and the
trx_sys.get_max_trx_id() read, for tables the query cache cannot use.
Oleg Smirnov
Refactor for better object names and more accurate comments
Monty
More query cache optimizations

- Added query_cache_type == ALWAYS_OFF to turn of query cache permanently
  for new open tables. Without this option storage engines has to call
  query cache for all update querys and invalidate used tables that has
  a small overhead. When running benchmarks without query cache, this
  is the option to use!
- Updated MyISAM, Aria, MYISAM_MRG and InnoDB to support ALWAYS_OFF.
- Setting query_cache_size in a config file will not automatically enable
  the query cache.
- Added query_cache_available() that functions can check if query cache
  can be used or if it is permanently disabled.
- Moved things around in Query_cache::store_query() to get more work done
  outside of query cache mutex.
- Same for Query_cache::send_result_to_client()

Co-author: Thirunarayanan Balathandayuthapani <[email protected]>
- ÃŒnnoDB changes reviewed and improved
Oleg Smirnov
Rename Parallel_coordinator, some other refactorings and clean-up
Brandon Nesterenko
Disable rpl_parallel_multi_domain_xa

MDEV-34104 describes why this test fails. It was filed 2 years ago, but
the fix is complex, and we keep this failing test around hurting all
other devs. The fix is planned, once finished, we can re-enable this
test.

Signed-off-by: Brandon Nesterenko <[email protected]>
Kristian Nielsen
Implement support for semi-sync with --binlog-storage-engine

Call report_binlog_update() when semi-synchronous replication is enabled and
using --binlog-storage-engine.

Only AFTER_COMMIT is available. The AFTER_SYNC in legacy binlog has the
property that changes in a committing transaction does not get visible to
other transactions until the slave has acknowledged, avoiding phantom reads
if the master fails permanently just after. This requires the two-phase
commit between binlog and storage engine so that the binlog is written
before the transaction is engine-committed. However, the whole point of
--binlog-storage-engine is to avoid the expensive two-phase commit.

(The ability to avoid phantom reads could be later implemented as an
AFTER_PREPARE option, which would send binlog to slave and await ack before
it is written/committed into the engine).

Some existing semi-synchronous replication tests are adapted to also run in
the binlog_in_engine suite.

Signed-off-by: Kristian Nielsen <[email protected]>
ParadoxV5
MDEV-40996 Support `--sync_with_master 0, $variable` in mysqltest

`--sync_with_master` uses `get_string()`,
which has `$variable` support, but it only uses the read buffer,
which is written with the unexpanded string and not the variable value.

Reviewed-by: KhaledR57 <[email protected]>
Dave Gosselin
MDEV-15066:  Filter geometry parts by bounding box before the scan

Implements a pre-filtering step to limit the polygons considered by
ST_Intersects and ST_Disjoint to those whose bounding box overlaps the
other operand.

The probe polygon overlaps the bounding box of seven rows in a table
of 239 country outlines.  Four of those rows are multipolygons of 346,
213, 120 and 21 polygons but not one of those 700 polygons overlaps
with the probe.  Yet, ST_Intersects stored all 700 into the scan.

A polygon whose bounding box does not overlap the other operand cannot
intersect it, yet the cost of the scan grows with the number of
polygons considered.  ST_Intersects and ST_Disjoint now leave such
polygons out.  Multipoint, multilinestring, multipolygon and geometry
collection each count the parts that pass the filter and store only
those.  A geometry of one part is unchanged.

Co-Authored-By: Claude Opus 5 <[email protected]>
drrtuy
MDEV-41001: cpack now skips data path that brings symbolic links to fix Windows build.
Monty
Added query_cache_use_rw_lock to allow concurrent query cache lookups

The query cache protected all operations with one exclusive lock
(m_cache_lock_status, guarded by structure_guard_mutex). This
serialized every lookup, even though a lookup mainly reads the
query cache structures.

Added a new global variable, query_cache_use_rw_lock (default OFF).
When set, send_result_to_client() takes a shared (read) lock instead
of an exclusive one, which allows lookups to run concurrently. Having
it as an option makes it possible to benchmark both alternatives with
the same binary and then decide which one to keep.

Implementation:
- try_lock() has a new 'read_lock' argument. The new inline function
  try_read_lock() sets it from query_cache_use_rw_lock.
- Readers are counted in m_readers and leave m_cache_lock_status as
  UNLOCKED. Writers wait until m_readers is 0 and are counted in
  m_waiting_writers. Waiting writers have priority over new readers,
  which ensures that invalidations are not starved by cache hits.
- Readers wait on the new COND_cache_read_lock. wake_up_waiters()
  wakes one waiting writer, or all waiting readers if there is none.
- unlock() is split into unlock() and unlock_internal(). The kind of
  lock to release is deduced from m_cache_lock_status, so none of the
  unlock() callers had to be changed.
- send_result_to_client() updates the query list and the statistics
  under structure_guard_mutex when it only holds a read lock. With a
  write lock this is done as before, without taking the mutex.
- If an engine requests invalidation during a lookup done with a read
  lock, the table key is copied and the invalidation is done after
  the lock is released, as invalidation requires a write lock.
- Added the DEBUG_SYNC point "in_query_cache_hit" used by the new test.

With query_cache_use_rw_lock=0 the code works as before.

Did a simple sysbench run with 64 threads and 200000 simple select queries,
all served from query cache. query_cache_use_rw_lock=1 gave a 2.25x
speedup. The difference to an unmodied MariaDB version for the same
test is 2.3 x faster.

Co-Authored-By: Claude Opus 5 <[email protected]>
sjaakola
MDEV-41012 Galera appliers hang with foreign key of types UUID, INET4, INET6

For direct row writes, the certification key for MYSQL_TYPE_STRING and
MYSQL_TYPE_VARSTRING is built by collating the column value and taking the
collation from Field::charset().

The data types implemented on Field_fbt - UUID, INET6 and INET4
report MYSQL_TYPE_STRING, and their charset() is my_charset_numeric,
which is latin1. Their values are however plain binary and accordingly
innodb maps them to DATA_FIXBINARY. Their keys were therefore run through
latin1_swedish_ci, which folds them. That corrupts the key in two ways:

1. A key mismatch for the same row. The FK constraint's referenced key
that is appended for the parent of a child INSERT is
built from the InnoDB record and is not collated, and it does not match
the primary key appended due to the parent row's direct write.
Certification saw no dependency between a child INSERT and a concurrent
parent UPDATE, and two appliers could apply them in parallel causing
a hang or crash.

2. A key collision between distinct rows. The folding is many to one, so
different values collapse onto one key, Certification compares keys byte
for byte, so unrelated rows were treated as the same row. Concurrent
transactions on them certified as a conflict and one was aborted with
ER_LOCK_DEADLOCK.

Fix is for  wsrep_store_key_val_for_row() to skip the collation for
fields that InnoDB stores as binary, using the same condition as
get_innobase_type_from_mysql_type(). This is a no-op for the types that
worked before.

This change requires to bump the application protocol version to level 5.

The commit has also two mtr tests for regression testing.
Dave Gosselin
MDEV-35845:  Propagate a constant into an IN predicate

SELECT * FROM t1 WHERE v IN ('a','b') AND v = 'b' kept both conjuncts
when v is a string column, while the equivalent form written with OR
was simplified to v = 'b'.

Two mechanisms can perform a rewrite.  Multiple equalities handle it
when check_simple_equality() builds an Item_equal, which it does only
if the field's charset allows constant propagation.  Up through 10.5 the
default character set was latin1 whose collation handler supports
constant propagation.  MDEV-19123 made utf8mb4 the default in 11.6, and
the utf8 collation handlers report that they do not support constant
propagation.

The other mechanism is propagate_cond_constants(), which rewrote
the OR form under every collation.  It descends through
change_cond_ref_to_const(), which returns on any node whose
eq_cmp_result() is COND_OK.  Item_func_in inherits that value, so the
IN predicate was skipped.

Implement an optimization in change_cond_ref_to_const() that replaces
the predicant of an IN predicate with the constant from an equality at
the same AND level.  The predicant is compared against every value of
the list, so the existing per-operand test from MDEV-7152 is applied
once for each of them.

Only a predicant whose arguments were all aggregated to one comparison
data type is replaced.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Kristian Nielsen
Fix hang on master when disabling semi-sync

There is a global variable global_ack_signal_fd used to signal the receiver
thread to wake up when disabling semi-sync. This variable was cleared to -1
in the Ack_listener destructor, which ran at the end of the
Ack_receiver::run() function without any locking. If the thread was delayed
at that point, it could end up overwriting the new value set by a new
receiver thread. This would leave the server in a state with an invalid
global_ack_signal_fd and could cause a subsequent disable of semisync to
fail due to the wakeup not arriving at the receiver thread.

This was seen as a sporadic failure of the test case
rpl.rpl_semi_sync_cond_var_per_thd.

Fix by not modifying the global in constructor/destructor; instead set and
clear the global explicitly, allowing to clear the fd with proper locking
while the mutex is still being held.

Also fix a missing pthread_join(), which would leak thread descriptors and
allow to start a new receiver thread before the old one shut down fully.

(Either of these two changes fix the hang bug).

Signed-off-by: Kristian Nielsen <[email protected]>
Sergei Golubchik
fix mariadb-plugin-defines.cmake for multi-config
Alexey (Holyfoot) Botchkov
MDEV-40394 XML schema fails on self-referencing type.

Copy XMLSchema_user_type information when the type is used recursively.
Copies that were once created are stored in m_c_free and then reused
later to avoid memory issues.
XMLSchema_item::is_validate_done() replaced with ::end_validation().
XMLSchema_group_def::check_type() now checks for circular groups.
Jacob Williams
MDEV-38757 Fix EXCHANGE PARTITION with generated columns containing AND/OR conditions

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.
Monty
More query cache optimizations

- Added query_cache_type == ALWAYS_OFF to turn of query cache permanently
  for new open tables. Without this option storage engines has to call
  query cache for all update querys and invalidate used tables that has
  a small overhead. When running benchmarks without query cache, this
  is the option to use.
- Setting query_cache_size in a config file will not automatically enable
  the query cache.
- Added query_cache_available() that functions can check if query cache
  can be used or if it is permanently disabled.
Raghunandan Bhat
MDEV-40422: use-of-uninitialized-value in my_convert

Problem:
  CAST(expr AS CHAR) has nothing to convert when the argument already
  has the requested character set, so it returns a String that reuses
  the argument's buffer. `Item_copy_string::copy()` compares String
  objects and not their buffers, so it does not see re-usage of buffer
  and copies the buffer onto itself. `String::copy()` needs one byte
  more for the terminating '\0' and adjusting it frees the old buffer
  before allocating the new one, so the copy reads freed memory.

Fix:
  Make sure the source owns the data before copying it into the
  destination.
Kristian Nielsen
Semi-sync: Refactor in preparation for using GTID in semi-sync acks

This is a refactor patch that contains no/little logic changes but a lot of
mostly mechanic code changes to prepare for allowing to use either old-style
filename/offset or new-style GTID to identify an event group in the
semi-sync ack.

The idea is to replace all explicit filename/offset function arguments with
a generic Repl_semi_sync_trx_info *inf to identify an event group (aka
"transaction"). This object can then be used to look up in the semi-sync
hash table by either file/pos or by GTID.

The classes Active_tranx and Repl_semi_sync_master are sub-classed into
Active_tranx_file_pos/Active_tranx_gtid and
Repl_semi_sync_master_file_pos/Repl_semi_sync_master_gtid. Virtual functions
are implemented in each for comparing identifiers and for calculating hash
keys, using either the file/pos or the GTID as appropriate. This way, the
existing logic can now be used with either (only file/pos is actually used
in this patch; adding GTID is for a subsequent patch).

For the binlog writing side, report_binlog_update(), wait_after_sync(), and
THD::semisync_info are extended to also take the GTID of the event group,
which is already available in the calling code.

For the dump thread / slave connection side, update_sync_header() is
extended to take also the GTID. The dump thread code is extended to keep
track of the GTID of the current event group (slightly extending the logic
already there to keep track of event groups). Also, the dump thread now only
passes the last event of an event group into the semisync layer (the other
events are redundant, as they are never semi-sync ack'ed, saving needless
semisync locking and hash lookups).

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
mysqltest: Implement --enable_sync_gtid option

The --enable_sync_gtid option switches to use GTID-based
--sync_slave_with_master (eg. using MASTER_GTID_WAIT() instead of
MASTER_POS_WAIT()).

This is useful to run adapt existing test cases for use with
--binlog-storage-engine. But it is also useful in general for replication
using GTID (which is the default).

The option is off by default to not randomly break existing tests.

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Semi-sync: Some few after-review fixes

Signed-off-by: Kristian Nielsen <[email protected]>
Khaled Riyad
MDEV-40377 Change Server source code to point to new docs (11.8 part)

Replace the remaining Knowledge Base links with their MariaDB
Documentation equivalents, including the 838 URLs in the help tables.
Only URLs change in fill_help_tables.sql.

fill_help_tables.sql conflicts on merge upward; keep the target
branch's version.
Brandon Nesterenko
MDEV-40906: rpl.rpl_gtid_thread_id assert_grep.inc failed

rpl.rpl_gtid_thread_id could fail sporadically due to a
non-deterministic slave state during an assert. The test asserted that
a certain number of transaction's exist in the slave's binary log file;
however, there was no sync between the master and slave after the last
transaction executed on the master. This means the slave's binary log
could be checked before the transaction ever was sent to/committed on
the slave.

The fix is to simply sync the master and slave before checking the
slave's binary log.

Signed-off-by: Brandon Nesterenko <[email protected]>
Jacob Williams
MDEV-38757 Fix EXCHANGE PARTITION with generated columns containing AND/OR conditions

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.
Luke Lu
MDEV-35732 Failed ALTER TABLE leaves cached table metadata corrupted

A failed ALTER TABLE ... RENAME INDEX ... ALGORITHM=INSTANT changed the
outcome of a subsequent, unrelated ALTER TABLE ... ADD FOREIGN KEY. A
failed statement must have no side effects, but here the second statement
wrongly succeeded where on a fresh table it correctly fails with
ER_DUP_KEYNAME.

Root cause: while rebuilding the key list, mysql_prepare_alter_table()
handled a RENAME INDEX request by clearing HA_GENERATED_KEY in place on
key_info->flags. key_info points into the (possibly cached) TABLE object
that is reused across statements. The ALGORITHM=INSTANT incompatibility is
only detected later, after mysql_prepare_alter_table() has returned, so the
statement fails with ER_ALTER_OPERATION_NOT_SUPPORTED with the cleared flag
never restored. The cached generated FK-support index (fk1) was thus left
permanently marked as user-defined.

That corrupted flag flips the de-duplication tie-break in the next ALTER:
adding FOREIGN KEY ind1 (b) creates a generated support index on column b
that prefix-matches fk1(b). Normally fk1 (generated) is dropped and the new
ind1 survives, colliding by name with the existing user index ind1(a) and
raising ER_DUP_KEYNAME. With fk1 no longer marked generated, the new ind1
is dropped instead, so no name collision is reached and the ADD FOREIGN KEY
silently succeeds.

Fix: do not mutate the cached key_info->flags. Track the "renamed => no
longer generated" decision in a per-key local variable (generated_key),
initialised from the flag, set to false on rename, and passed to the Key
constructor. This preserves the in-statement behaviour while leaving the
cached TABLE metadata untouched, so a failed ALTER has no lingering effect.

All new code of the whole pull request, including one or several files that
are either new files or modified ones, are contributed under the BSD-new
license. I am contributing on behalf of my employer Amazon Web Services, Inc.
Sergei Golubchik
fix the build for -G "Ninja Multi-Config"