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
Mohammad Tafzeel Shams
MDEV-40404 : Assertion '!lock.is_locked_or_waiting()' failed in buf_page_t::init()

A locking read on a SPATIAL INDEX collects the matching records into a
shadow block matched_rec_t::block. sel_set_rtr_rec_lock() holds page.lock
on that block while it locks the records, because lock_rec_lock() asserts
that the block of the record being locked is latched. If a lock request
has to wait, the records are collected again after the wait, and
rtr_init_match() re-initializes the block by buf_page_t::init(), which
asserts that the block is not latched.

The assertion is about a latch that would be a leftover from the previous
identity of the block. It does not apply to rtr_init_match(), where the
block is in buf_page_t::MEMORY state, private to the current thread, which
is holding page.lock on it on purpose.

Changes:

- buf_page_t::init(): Tolerate a latch that the current thread is holding
on a block that is being initialized in buf_page_t::MEMORY state.
Khaled Riyad
MDEV-41150 mariadb client: Ctrl-C does not interrupt tab separated result output

Ctrl-C sets interrupted_query and sends KILL QUERY to the server, but the
result is already fetched into the client by then, so killing the query
cannot stop the output. Only the printing loop can, by checking
interrupted_query.

print_table_data(), print_table_data_html(), print_table_data_xml() and
print_table_data_vertically() check it, print_tab_data() did not, so the
output of -s, -N and -B could not be interrupted.

Add the same check to print_tab_data().

No test case: the suite drives the client through a pty with socat, where
0x03 is not turned into a signal, and there is no other way in the suite to
signal a client while it is printing.
forkfun
MDEV-29510 ASAN errors upon updating a BLOB column twice in one UPDATE

UPDATE t SET a='x', b=a, a='foobarqux' makes b alias a's value buffer
(field_conv_memcpy() copies the blob pointer while copy_blobs is off).
Storing a again frees that buffer, and b is left dangling. The same
happens in INSERT ... ON DUPLICATE KEY UPDATE.

fill_record(update=true) now stores a blob by value, unless the source is
a plain same-type blob column still in engine memory: nothing frees that,
so aliasing stays safe and cheap.

Field_blob::store_field() copies such blobs verbatim, skipping the
charset check.

INSERT ... ON DUPLICATE KEY UPDATE keeps the inserted row's blob pointers
in insert_values, pointing into Field_blob::value. Keep those buffers
aside while the UPDATE clause runs, so that storing into a column does
not overwrite what VALUES() reads later.
DerZc
MDEV-39969: Incorrect result of JSON_TABLE with BIT

Problem: JSON_TABLE maps JSON numbers [0,1] to BIT(1) values [1,1].
The scalar helper passes decimal text to BIT's binary-string store,
so the byte for '0' is 48 and is clipped to 1.

Fix: Add Field::store_numeric() for number literals serialized as text,
including fractions and exponents, and use it for JSON_TABLE numbers.
BIT parses these literals as rounded unsigned integers and applies its
existing range checks. Other fields retain their existing conversion;
JSON strings and booleans retain their existing storage paths.
Preserve the existing distinction between conversion warnings and JSON
structural errors, so numeric overflow does not invoke ON ERROR.
Extend json.json_table to cover BIT widths, unsigned boundaries,
fractions, exponents, boolean/string/null inputs, other field types,
conversion warnings and ON ERROR responses.

Assisted-by: OpenAI Codex:gpt-6
Sergei Golubchik
take old_mode and deprecation.h changes from 11.8-13.0

cherry-pick commits 9ecec1f7302, 24fd8c7856e, 3e971059757

* make it easier to add more old-mode values
* update deprecation.h to match changes in versioning
Sergei Petrunia
Remove unused LEX::create_view_select

The member was never set or read. The create_view_select in
LEX::parsed_create_view() is a local variable that merely shadowed it.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Oleksandr Byelkin
MDEV-41405 ASAN stack-buffer-overflow TDBXML::Initialize/TDBXML::OpenDB after insert into CONNECT table

XmlDB was copied with strcpy/strcat into a 64-byte stack buffer to
build the XPath. Tabname used the same buffer with snprintf, silently
truncating the XPath.

Build the XPath in a buffer allocated by its real length.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Andrei Elkin
MDEV-41214 PURGE BINARY LOGS does not delete non-active binlog files

PURGE BINARY LOGS could end with a warning instead of deleting files, as
the test below shows when run on the base of this commit. The warning
names a wrong reason. It follows an automatic purge that was refused by
the slave guard, slave_connections_needed_for_purge: the automatic purge
does not delete a binlog while it might still be needed by a slave, not
necessarily a connected one, that is while fewer than the variable's
number of slaves are connected.
Since MDEV-34504 the manual PURGE is meant to ignore the guard.
Yet it still protects a binlog that a slave is reading.

Technically this was possible because the automatic and the manual purge
share a code path, can_purge_log(), which cached the refusal and replayed
it, under the reason of the first arm below, to any later purge:

  if (is_active(name) ||
      (!is_relay_log && waiting_for_slave_to_change_binlog &&
      purge_sending_new_binlog_file == sending_new_binlog_file &&
      !strcmp(name, purge_binlog_name)))
    reason= "it is the current active binlog";

So "active" had to be read as "active or busy". The fix removes this
duality too: the two arms are now separate and have their own reasons.

The main issue is fixed by narrowing the busy arm with an additional
`!interactive &&` conjunct, so that a manual PURGE never consults the
cached refusal.

Running the test below on an unfixed 11.4 server (source tree at commit
42038e1145d) fails with "Result length mismatch" and, in part 2, this
diff against the recorded result:

  PURGE BINARY LOGS TO 'master-bin.000006';
  +Warnings:
  +Note 1375 Binary log 'master-bin.000003' is not purged because it is the current active binlog
  SHOW WARNINGS;
  Level Code Message
  +Note 1375 Binary log 'master-bin.000003' is not purged because it is the current active binlog
  show binary logs;
  Log_name File_size
  +master-bin.000003 #
  +master-bin.000004 #
  +master-bin.000005 #
  master-bin.000006 #
  master-bin.000007 #
  master-bin.000008 #

Test binlog.binlog_purge_stale_refusal_cache: the test sets
slave_connections_needed_for_purge=1, binlog_expire_logs_seconds=0 and
max_binlog_total_size=0 first and restores them at the end. It starts
with RESET MASTER so that the binlog names, 000003 and so on, do not depend
on the tests run before it in the same mtr environment. Part 1 is a control with
nothing cached; part 2 makes an automatic purge refuse 000003 (the files
must be older than binlog_expire_logs_seconds, hence --real_sleep 2 before
the rotation) and then runs PURGE BINARY LOGS TO 'master-bin.000006',
which must remove 000003..000005.

As a workaround, a PURGE could work if the following settings are made
before it, in this order:

  SET GLOBAL binlog_expire_logs_seconds=0, slave_connections_needed_for_purge=0;

The second setting invalidates the cached refusal. The first one keeps
the purge that this setting triggers from refusing and caching again.
Note that both settings change the server's policy, not only this one
PURGE: the time-based expiry and the slave guard are off until they are
restored.
Pekka Lampio
MDEV-40018: SHOW SLAVE STATUS allocates ~1.7 MB per call due to oversized VARCHAR columns

SHOW SLAVE STATUS / SHOW ALL SLAVES STATUS / INFORMATION_SCHEMA.SLAVE_STATUS
are all served from the ST_FIELD_INFO array slave_status_info[]. Thirteen of
its columns (Replicate_Do_DB, Replicate_Ignore_DB, Replicate_Do_Table,
Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table,
Replicate_Ignore_Server_Ids, Gtid_IO_Pos, Replicate_Do_Domain_Ids,
Replicate_Ignore_Domain_Ids, Slave_SQL_Running_State, Replicate_Rewrite_DB,
and Gtid_Slave_Pos) used the no-argument Varchar() helper, which defaults to
MAX_FIELD_VARCHARLENGTH/3 characters. With utf8mb3, that reserves 65532
bytes per column in the temporary table's record buffer regardless of the
actual value size, and the record is allocated twice, accounting for the
reported ~1.7 MB allocated on every call.

Change these columns to Blob(MAX_FIELD_VARCHARLENGTH), which keeps the same
maximum capacity but stores only a pointer and length in the record. Values,
NULL-ability, and column order are unchanged; the client-visible column type
for these columns changes from VARCHAR to BLOB.

mysql-test/suite/funcs_1/r/is_columns_is.result is updated to match, since
it asserts on INFORMATION_SCHEMA.COLUMNS metadata for these columns.

Assisted-By: Claude AI
Hemant Dangi
MDEV-40501: Assertion `info->type == READ_CACHE || info->type == WRITE_CACHE' failed in reinit_io_cache upon CHANGE MASTER

Issue:
CHANGE MASTER ... FOR CHANNEL with a channel name within
MAX_CONNECTION_NAME can still overflow the OS file name limit once
escaped into the relay log file name. Relay_log_info::init() then
fails to open the relay log, leaving its index file unopened, but
Master_info_index::remove_master_info() unconditionally calls
reset_logs() on it during CHANGE MASTER's error cleanup, which hits
the assertion in reinit_io_cache().

Solution:
Guard the reset_logs() call in remove_master_info() with is_open(),
so a relay log that was never opened is never passed to it. Also use
MY_SAFE_PATH in open_index_file() so an over-length name fails
deterministically instead of silently falling back to a mangled one.
andrelkin
Merge branch '11.4' into bb-11.4-andrei
iff-sal
MDEV-40296: SELECT @@GLOBAL.replicate_do_db ignores default_master_connection

When querying replication filter system variables without specifying a
connection name qualifier (e.g., SELECT @@GLOBAL.replicate_do_db),
Sys_var_rpl_filter::global_value_ptr() previously passed the unspecified
base_name directly to get_master_info(), which resolved to the default
connection (empty_clex_str) rather than respecting
@@SESSION.default_master_connection.

Fix by falling back to thd->variables.default_master_connection when
base_name->str is NULL in Sys_var_rpl_filter::global_value_ptr().

Add regression test in suite/multi_source/rpl_filter_default_master.test
covering explicit named connection, unspecified connection falling back
to default, and explicit unnamed connection with empty backticks.
Oleg Smirnov
MDEV-32412 Pushdown from HAVING: Item_func is immutable while arguments are not

Fix-up for commit e97560eac03 (MDEV-28958), which made set_extraction_flag()
ignore basic constants so that the read-only Item_true/Item_false singletons
are never written to. Because of that, the callers that mark a subtree with
MARKER_IMMUTABLE before pushing a condition from HAVING into WHERE cannot
mark basic constants inside it.

Item::cleanup_excluding_immutables_processor() did not know about this
exception and cleaned such items up, unfixing them while their marked parents
stayed fixed. fix_fields() does not descend into fixed items, so the constant
was left unfixed and Item_direct_view_ref::used_tables() later dereferenced a
NULL null_ref_table. Skip basic constants there too.
Alexander Barkov
MDEV-41530 Assoc array element field as OUT parameter crashes the server

A field of an element of an associative array of RECORDs, passed to
an OUT or INOUT parameter of a stored routine, crashed the server:

  CREATE PROCEDURE p1(a OUT INT) AS BEGIN a:= 7; END;
  DECLARE
    TYPE rec_t IS RECORD (i INT, s VARCHAR(10));
    TYPE tab_t IS TABLE OF rec_t INDEX BY INT;
    t tab_t:= tab_t(1 => rec_t(0, 'x'));
  BEGIN
    p1(t(1).i);
  END;

There were three problems:

- Item_splocal_assoc_array_element_field inherited set_value() of
  Item_splocal_row_field_by_name, which treated the associative array
  variable as a ROW variable (assertion failure in
  sp_rcontext::virtual_tmp_table_for_row()). Added
  Item_splocal_assoc_array_element_field::set_value(), which stores the
  value into the field of the element.
- Before the call, sp_head::bind_input_param() destructed the whole
  variable for an OUT argument, even if the argument was only a part of
  the variable (a ROW field, an assoc array element or its field), so
  the other elements of the array were lost: after p1(a0(2)), the array
  a0(1), a0(2), a0(3) had only one element left. Added
  Item_splocal::is_part_of_variable().
- sp_head::bind_output_param() evaluated the actual argument in the
  context of the callee. For arguments like t(i) or t(i).field this
  resolved the variables t and i in a wrong context. Now the argument
  is evaluated in the context of the caller.

The second problem also affected a SYS_REFCURSOR field of a ROW variable
passed as an OUT argument: the cursors in the other fields of the ROW
variable were closed. Now they are kept.

Known limitations, not changed by this fix:
- The actual OUT argument is evaluated when the value is copied back,
  not when the routine is called. If an earlier OUT argument of the same
  call changes the variable used as the key, as in CALL p(i, a0(i)), the
  new value of the key is used.
- For an OUT argument which is a part of a variable (a ROW field, an
  assoc array element or its field), only the destruct of the whole
  variable is skipped, the part itself is not destructed. A
  SYS_REFCURSOR field of a ROW stays open during the call and is
  released when the new value is copied back.

Tests: sp-assoc-array (OUT and INOUT elements and fields of elements,
NULL key, element deleted by the callee, ROW and RECORD fields) and
type_sys_refcursor-type_row-debug (SYS_REFCURSOR fields of a ROW
variable).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Hemant Dangi
MDEV-35812: generate-ssl-certs.sh: remove bashism

Issue:
generate-ssl-certs.sh is a /bin/sh script but uses process substitution
(<(printf ...)) for -extfile, which fails with plain sh.

Solution:
Write the extensions to a file in gcadir/ and pass it to -extfile.
Dmitry Shulga
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }

Core implementation

- Extended the sql grammar to support creation of system triggers
  on startup/shutdown
- System triggers metadata is loaded from the table mysql.event
- Events and system triggers share the same name space since both are stored
  in the table mysql.event declared with the PRIMARY KEY (`db`,`name`).
  In result, attempt to create an event with the same name as existent
  trigger and vice versa results in failure with the new error
  ER_TRG_EVENT_CONFLICTS_NAME
- System triggers can be created only by users with the SUPER privilege
- Added the option --sys_triggers for mysqldump to dump system triggers.
  The option is turned off by default.
Marko Mäkelä
Merge 10.11 into 11.4
Jan Lindström
MDEV-39056 : sporadic test failures with galera.galera_toi_ddl_nonconflicting

The test sent

  ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000);

from node_2 as a single --send. Nothing ordered that INSERT against the
CREATE UNIQUE INDEX issued from node_1, so the second DDL could reach node_2
while the INSERT was still executing there and BF-abort it. The automatic
autocommit retry then replicated with last_seen_seqno behind the seqno of the
DDL and failed certification against its exclusive key on test.t1. As
wsrep_retry_autocommit defaults to 1 there was no second retry and the client
got ER_LOCK_DEADLOCK.

Send only the ALTER TABLE and execute the INSERT after both DDL statements
have completed on both nodes.

Waiting for the second DDL by polling INFORMATION_SCHEMA.PROCESSLIST did not
prove that it had been ordered either: wsrep_TOI_begin() sets the
"Waiting to execute in isolation" stage before it replicates the writeset, so
that state can be observed before the DDL has reached total order. Wait on
node_2 for the new index to appear instead, which happens only once the DDL
has been ordered behind the parked ALTER TABLE, and record on node_1 that
neither DDL has been applied there while the first one is still parked.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Jan Lindström
MDEV-41505 : Sql_cmd_show_routine_code::execute does not call wsrep_sync_wait()

There was no wsrep_sync_wait on Sql_cmd_show_routine_code::execute.
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]>
Sergei Petrunia
Remove unused LEX::backup_dir

The member was never set or read.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Aleksey Midenkov
MDEV-40821 Wrong result after DELETE HISTORY or PORTION OF (10.11)

The parser assigned versioning conditions of DELETE HISTORY ... BEFORE
SYSTEM_TIME and period conditions of DELETE ... FOR PORTION OF to the
table pointed by last_table(). When the BEFORE SYSTEM_TIME or FOR
PORTION OF expression references another table (e.g. via a subquery or
a sequence function), last_table() is already switched to that table,
and the DELETE target gets no conditions.

DELETE HISTORY then deletes current rows permanently instead of
history, keeps the history it had to purge, and is checked for DELETE
privilege instead of DELETE HISTORY. DELETE HISTORY from a
non-versioned table is not rejected with ER_VERS_NOT_VERSIONED.
DELETE ... FOR PORTION OF deletes all rows of the table, ignoring the
period.

The fix assigns the conditions to the TABLE_LIST returned by
delete_single_table, i.e. the DELETE target itself, regardless of
tables added later in the statement.

DBUG_ASSERT in TABLE::vers_switch_partition() is removed. It checked
delete_history on last_table() and assumed no other table is opened
for write by DELETE HISTORY, which is false for the underlying table
of a view or a table locked by SELECT ... FOR UPDATE in the history
point. The DELETE HISTORY target is already skipped there by its own
delete_history check.
Marko Mäkelä
Merge 10.11 into 11.4
DerZc
MDEV-39194: Fix DISTINCT bit and hex aggregation

Problem: SUM(DISTINCT b'1100') returns 9 instead of 12. The hybrid
hex/bit literal handler uses the default DOUBLE temporary field, so
its byte length becomes a DOUBLE(M,0) display width and clips the
numeric value.

Fix: Override numeric DISTINCT field construction for hybrid hex and
bit literals to allocate an unsigned Field_longlong directly. Preserve
argument-based field selection for other types so DISTINCT retains the
input expression's precision and scale, including decimal AVG inputs.
Extend main.sum_distinct to cover bit and hex literals, zero, byte and
unsigned 64-bit boundaries, duplicates, AVG, COUNT and decimal scale.

Recreated-by: Georgi "Joro" Kodinov <[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.
Sergei Golubchik
extend copilot review insttructions with AI attribution policy
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.
Alexander Barkov
MDEV-41530 Assoc array element field as OUT parameter crashes the server

A field of an element of an associative array of RECORDs, passed to
an OUT or INOUT parameter of a stored routine, crashed the server:

  CREATE PROCEDURE p1(a OUT INT) AS BEGIN a:= 7; END;
  DECLARE
    TYPE rec_t IS RECORD (i INT, s VARCHAR(10));
    TYPE tab_t IS TABLE OF rec_t INDEX BY INT;
    t tab_t:= tab_t(1 => rec_t(0, 'x'));
  BEGIN
    p1(t(1).i);
  END;

There were three problems:

- Item_splocal_assoc_array_element_field inherited set_value() of
  Item_splocal_row_field_by_name, which treated the associative array
  variable as a ROW variable (assertion failure in
  sp_rcontext::virtual_tmp_table_for_row()). Added
  Item_splocal_assoc_array_element_field::set_value(), which stores the
  value into the field of the element.
- Before the call, sp_head::bind_input_param() destructed the whole
  variable for an OUT argument, even if the argument was only a part of
  the variable (a ROW field, an assoc array element or its field), so
  the other elements of the array were lost: after p1(a0(2)), the array
  a0(1), a0(2), a0(3) had only one element left. Added
  Item_splocal::is_part_of_variable().
- sp_head::bind_output_param() evaluated the actual argument in the
  context of the callee. For arguments like t(i) or t(i).field this
  resolved the variables t and i in a wrong context. Now the argument
  is evaluated in the context of the caller.

The second problem also affected a SYS_REFCURSOR field of a ROW variable
passed as an OUT argument: the cursors in the other fields of the ROW
variable were closed. Now they are kept.

Known limitations, not changed by this fix:
- The actual OUT argument is evaluated when the value is copied back,
  not when the routine is called. If an earlier OUT argument of the same
  call changes the variable used as the key, as in CALL p(i, a0(i)), the
  new value of the key is used.
- For an OUT argument which is a part of a variable (a ROW field, an
  assoc array element or its field), only the destruct of the whole
  variable is skipped, the part itself is not destructed. A
  SYS_REFCURSOR field of a ROW stays open during the call and is
  released when the new value is copied back.

Tests: sp-assoc-array (OUT and INOUT elements and fields of elements,
NULL key, element deleted by the callee, ROW and RECORD fields) and
type_sys_refcursor-type_row-debug (SYS_REFCURSOR fields of a ROW
variable).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Dmitry Shulga
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }

Extended the system table mysql.event to support creation of
system triggers (startup, shutdown, logon, logoff) and ddl triggers.

The system table mysql.event is extended with three columns
  `kind`, `when`, `ddl_type`.
For the task MDEV-30645 only the column `kind` is required,
the other two columns are required for the tasks
  MENT-2355, MENT-2291
but since it is better to reduce a number of times the system table
is changed and as a consequences a number of upgrades to be run,
the entire set of columns is added at once.

Type of the columns `kind` and `ddl_type` are specified as SET to allow
storing of triggers that handle several events.
Dmitry Shulga
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }

Core implementation

- Extended the sql grammar to support creation of system triggers
  on startup/shutdown
- System triggers metadata is loaded from the table mysql.event
- Events and system triggers share the same name space since both are stored
  in the table mysql.event declared with the PRIMARY KEY (`db`,`name`).
  In result, attempt to create an event with the same name as existent
  trigger and vice versa results in failure with the new error
  ER_TRG_EVENT_CONFLICTS_NAME
- System triggers can be created only by users with the SUPER privilege
- Added the option --sys_triggers for mysqldump to dump system triggers.
  The option is turned off by default.
Thirunarayanan Balathandayuthapani
MTR: dump core if the server hangs during startup

If mariadbd does not finish starting up, for example it hangs in a
restart done by a test, mtr only killed it, so there was no way to
see where it was stuck.

When a test fails and a server is still running but has not created
its pid file, send it SIGABRT before killing it. The server then
writes a stack trace to its error log and dumps core, and the log
is added to the failure report.

MTR_DUMP_CORE_TIMEOUT (default 120 seconds) sets how long mtr waits
for the core dump. Nothing is done when the server runs under a
debugger.
Aleksey Midenkov
MDEV-40821 Wrong result after PORTION OF with subquery (11.4)

Single-table DELETE converted to multi-table (when a subquery
references the target table) skipped FOR PORTION OF row splitting and
the constant expression check, so it deleted whole rows instead of the
portion.

The fix prohibits processing DELETE ... FOR PORTION OF as multi-table,
like DELETE ... RETURNING.
Dmitry Shulga
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }

Extended the system table mysql.event to support creation of
system triggers (startup, shutdown, logon, logoff) and ddl triggers.

The system table mysql.event is extended with three columns
  `kind`, `when`, `ddl_type`.
For the task MDEV-30645 only the column `kind` is required,
the other two columns are required for the tasks
  MENT-2355, MENT-2291
but since it is better to reduce a number of times the system table
is changed and as a consequences a number of upgrades to be run,
the entire set of columns is added at once.

Type of the columns `kind` and `ddl_type` are specified as SET to allow
storing of triggers that handle several events.
Sergei Petrunia
Remove unused LEX::next_is_main and LEX::next_is_down

The members were only declared and reset in LEX::start(); nothing read them.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Oleksandr Byelkin
MDEV-32401 expression cache lead to crash if table of wrong type created and the cache switched off

1) take into account TMP_TABLE_ALL_COLUMNS when
  we are modifying agg_item->result_field
2) remove unused now "bool materialized_subquery;"

Co-Authored-By: Claude Opus 5.5 <[email protected]>
GoldenEmperor1177
MDEV-31225 Crash converting IN with a nested ROW into IN subquery

What was wrong:
With in_predicate_conversion_threshold set low enough, an IN predicate
with a nested ROW, e.g.

  ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL)))

crashed the server. Before an IN list is converted into an IN subquery
over a table value constructor, cmp_row_types() checks every column
with subquery_type_allows_materialization(). With a nested ROW the
column is a ROW itself, and for a ROW that function must not be called.

How it is fixed:
A table value constructor cannot have a ROW as a column, so such a
predicate cannot be converted anyway. cmp_row_types() now reports the
columns as not comparable when either of them is a ROW, and the IN
predicate is evaluated without the conversion.

How it is tested:
Added a test to main.opt_tvc with IN and NOT IN over nested ROWs. It
crashes the server without the fix.
Sergei Petrunia
Remove unused LEX::escape_used

The flag was set by the parser but never read. Item_func_like keeps its own
escape_used_in_parsing member, which is unaffected.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>