Console View
|
Categories: connectors experimental galera main |
|
| connectors | experimental | galera | main | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rion Bora
223810819+GoldenEmperor1177@users.noreply.github.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40839 SET members from the 9th on lost on a pushed-down SELECT Type_handler_set::make_table_field() built the Field_set with get_enum_pack_length(), the ENUM rule (1 byte below 256 values), so a SET with more than 8 members got a 1-byte field in the temporary table of a select handler (used by the DuckDB engine and by FederatedX with federated_pushdown=1) and every member from the 9th on was cut off. Use get_set_pack_length(), as the other Type_handler_set functions already do. Tests: duckdb.set_wide_members and federated.federatedx_set_pushdown. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Nikita Malyavin
nikitamalyavin@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41238 mysqltest: add PS_bind_long command mysqltest gets a PS_bind_long command. It binds like PS_bind, but sends every value with mysql_stmt_send_long_data() before each PS_execute, so a test can reach a parameter in LONG_DATA_VALUE state. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Nikita Malyavin
nikitamalyavin@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41238 Bound parameters prevent condition pushdown into a grouped view, while CAST enables it Item_param::deep_copy() returned NULL, and every rewrite that copies a condition gives up on what it cannot copy. A conjunct holding a prepared statement parameter was therefore left out of: - pushdown into derived tables and views, including UNION branches and conditions on a derived table column whose expression holds a parameter; - pushdown from HAVING to WHERE, for the part extracted from an OR; - pushdown into a materialized IN subquery; - split materialization, which then found no split key; - the UPPER(col) IN (...) rewrite, which has skipped such conjuncts since MDEV-40006. When the derived table groups by an expression with a parameter, the condition was pushed into its HAVING instead of its WHERE. CAST(? AS ...) worked around this only by accident. Before the pushdown, constant propagation can replace a constant expression on one side of = with a literal. A bare parameter already counts as a basic constant, so propagation leaves it as it is. A client whose charset differs from the column's got the pushdown by a similar accident: the charset conversion replaces the parameter with a literal. Item_param::shallow_copy() now copies a parameter that holds a value, NULL included, and deep_copy() calls it, as in other leaf items. Every such copy is made while optimizing during EXECUTE, and the next EXECUTE makes a new one, so a copy always carries the value bound for the EXECUTE that made it. A copy that outlived its EXECUTE would keep an old value and point into a string buffer that the next binding may free, so shallow_copy() asserts that it does not allocate on the statement's arena. The copy is not added to m_clones. m_clones keeps the parameter's copies in CTE definitions updated with each new value for the whole life of the statement, while this copy lives for one execution. An unbound parameter, DEFAULT and IGNORE still have no copy. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fixup! 883556d1a77c1c0004d95f0b8ffdc66de2a029f8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Fix use-after-poison on BINLOG with a Query event in EXECUTE IMMEDIATE Query_log_event::do_apply_event() freed thd->mem_root, which inside a BINLOG statement also freed the statement's own memory, e.g. Items of EXECUTE IMMEDIATE freed later in THD::cleanup_after_query(). Free thd->mem_root only in replication/wsrep appliers, as Rows_log_event::do_apply_event() does. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
check for truncated packets when reading bound parameter values and clear the error flag on correct values |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-33843: Server crashes by stack-overflow with UPDATEXML Analysis: The stack size if insufficient and there is no stack overrun check. Fix: Add stack overrun check. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Khaled Riyad
khaled57.dev@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41470 Server crashes in check_grant / delete_precheck on 2nd execution of SP When a procedure changes a view that calls a stored function, the tables of that function are added to the statement's table list for prelocking. From the second call on, they are already in the list when the privilege precheck runs. `check_one_table_access()` took the first of them for a table of the view, and the check then walked past the end of the list and crashed. Stop in `check_one_table_access()` when no tables owned by the statement are left. The prelocking tables are checked when their routines run. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thirunarayanan Balathandayuthapani
thiru@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41282 Recursion in InnoDB FTS AST causes stack-overflow (fts_ast_free_node/fts_ast_free_list) Problem: ======= fts_ast_free_node() and fts_ast_free_list() called each other, so releasing the parse tree consumed one pair of thread stack frames for every level of the tree. sub_expr: '(' expr_lst ')' creates one FTS_AST_SUBEXP_LIST per pair of parentheses, so a boolean mode query with 2000 nested parentheses builds a chain of 4002 nodes, and fts_query_free() overflowed the thread stack while freeing it. fts_ast_visit() does not reach that depth, because fts_ast_visit_sub_exp() limits the sub-expression nesting to 32 levels and returns DB_OUT_OF_MEMORY. The parser has built the whole tree by then, and it still has to be freed. Solution: ======== fts_ast_free_node(): Free the sub-tree with an explicit stack instead of by recursion. The stack is threaded through the next pointer of the very nodes that are about to be freed, so it needs no extra memory and cannot fail to allocate. A node is only pushed once it has been detached from the tree. The children of a list are already chained to each other by next, so a whole list is spliced onto the stack in one step. fts_ast_free_list(): Removed, no longer needed. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Raghunandan Bhat
raghunandan.bhat96@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40836: Window function in ORDER BY split twice by split_sum_func() Problem: A window function inside an ORDER BY expression was split twice by `split_sum_func()` first in `setup_order()`, then again in `JOIN::prepare()`. Each split adds the item to `ref_pointer_array`, which resulted in overflow. The split in `setup_order()` was added by MDEV-28094 (8c34eab) to fix a crash in - SELECT EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()); `check_and_do_in_subquery_rewrites()` dropped the ORDER BY of that subquery, so `JOIN::prepare()` never split it. But its window function was still registered with the select and processed, causing the crash. Fix: - When check_and_do_in_subquery_rewrites() drops the ORDER BY, also remove its window functions from `SELECT_LEX::window_funcs`. - Remove the window function split from `setup_order()`, so it is done only once, in `JOIN::prepare()`. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Fix use-after-poison on BINLOG with a Query event in EXECUTE IMMEDIATE Query_log_event::do_apply_event() freed thd->mem_root, which inside a BINLOG statement also freed the statement's own memory, e.g. Items of EXECUTE IMMEDIATE freed later in THD::cleanup_after_query(). Free thd->mem_root only in replication/wsrep appliers, as Rows_log_event::do_apply_event() does. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
bsrikanth-mariadb
srikanth.bondalapati@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41293: FederatedX: connection state after a net_read_timeout Problem: When reading the reply of the remote server times out, the client library compiled into the server returns without closing the connection and without setting a client error. FederatedX took the raw ER_NET_READ_INTERRUPTED for an error of the remote server and went on using a connection that still had the reply of the failed statement to arrive. As a result: * the next statement on that connection failed in various ways, either with ER_QUERY_ON_FOREIGN_DATA_SOURCE ("Server has gone away") or with an error packet that mysqltest took for a malformed packet; * inside a transaction, the following statements continued on a new remote session in autocommit mode, so they were committed on the remote server one by one even though the local transaction was later rolled back. The savepoints of the lost session were also still remembered by FederatedX. The same happened when the connection was lost while reading the reply. Fix: * After a timeout FederatedX closes the connection, so that the next statement opens a new one. The client still gets the error of the timeout, ER_NET_READ_INTERRUPTED. * Whenever the connection is gone after a failed statement, timeout or not, the state of the lost session (autocommit mode, savepoints) is forgotten and the local transaction is marked to be rolled back, so a new connection starts the transaction again. This includes the case where the connection is lost while SET AUTOCOMMIT=0 is sent for the first statement of the transaction. The closed connection is also freed, which was leaked before. * Errors of the client library are reported as ER_QUERY_ON_FOREIGN_DATA_SOURCE by ha_federatedx::info() as well, the same way as by the pushed down multi-table UPDATE/DELETE. * The error state of ha_federatedx, read by info(), is initialized. Test: federatedx_pushdown_upd_del covers the timeout of a pushed down multi-table UPDATE and DELETE and of reading a result, the statements after it, the same inside a transaction, a connection killed in the middle of a statement, a connection lost while SET AUTOCOMMIT=0 is sent (also followed by a disconnect and a transaction in another session), client library errors in info(), and that an error of the remote server which merely has the code of ER_NET_READ_INTERRUPTED is not taken for a timeout. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
bsrikanth-mariadb
srikanth.bondalapati@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41243, MDEV-41273 Don't freeze mem_root after engine pushdown When a statement is pushed down to an engine, the once-per-statement part of the optimization (e.g. the first_cond_optimization part of JOIN::optimize(), or the whole of JOIN::optimize() for a pushed down UNION) is skipped. Re-executing the same prepared statement or stored routine without pushdown then allocated from a mem_root already marked ROOT_FLAG_READ_ONLY, hitting an assertion in alloc_root(). Add LEX::dont_freeze_mem_root, set by the pushdown_handler and derived_handler constructors so it covers every engine implementing them. Prepared_statement::execute_loop(), sp_head::execute() (through sp_head::dont_freeze_mem_root) and the SP instruction reparse path no longer freeze the mem_root of such statements. The flag is only declared and used in PROTECT_STATEMENT_MEMROOT builds. The flag is per execution for prepared statements: Prepared_statement::execute_loop() clears it after each execution, so the mem_root is frozen again after the first later execution that is not pushed down. For a stored routine the instruction's LEX keeps the flag, so once one instruction has been pushed down the routine's mem_root stays unfrozen, even if later executions are not pushed down, unless the routine is re-parsed into a new LEX. Add tests for prepared SELECT, UNION, UPDATE and DELETE, prepared EXPLAIN of a pushed UNION, derived tables, stored procedures, functions, triggers, cursors and metadata-invalidation reparse, with pushdown switched on and off. Most prepared statement and routine tests check the statements received by the remote server, or EXPLAIN, to verify that pushdown actually happened. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41652 SIGFPE in get_next_time/Event_queue_element::compute_next_execution_time get_next_time() took the interval value as int, so converting it to seconds or months could overflow, e.g. 268435456 HOUR wrapped to 0 and the months branch divided by zero. Pass the interval as longlong and reject month counts that do not fit INTERVAL::month (32-bit on Windows). Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39306 fix race in versioning.rpl_row The slave created table t before the master's previous DROP TABLE t was replicated. Sync the slave after the drops. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39306 fix race in versioning.rpl_row The slave created table t before the master's previous DROP TABLE t was replicated. Sync the slave after the drops. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-14992/MDEV-38362/MDEV-39092 BACKUP SERVER The following SQL statements will be introduced: BACKUP SERVER TO '/path/to/directory' [ 1 CONCURRENT ]; BACKUP SERVER WITH [ 1 CONCURRENT ] 'command'; In place of the 1, any positive number of threads may be specified. For the first variant, '/path/to' must exist and '/path/to/directory' must not exist; that is where the backup will be written to. For BACKUP SERVER WITH, the string mariadb-backup- will be prepended to the specified command and quoted. Path separators or quotes are not allowed in command. We expect the mariadb-backup-command to be in the search PATH of the mariadbd process. For now, we distribute no such script or program; the user has to write one, something like this: exec zstdmt|ssh [email protected] "exec cat > $1.tar.zstd" The standard input of that command will be in a format compatible with GNU tar --format=oldgnu (and also BSD tar variants that are also part of Microsoft Windows and Apple macOS). The command is expected to optionally compress and encrypt the stream and redirect it to a file on a local or a remote server. The BACKUP SERVER WITH will append an additional argument, a positive base-ten number in ASCII, starting with 1, to identify the current thread. In this way, there can be multiple concurrent streams. The InnoDB write-ahead log will be streamed near the end, because the stream format requires the file sizes to be declared upfront. In BACKUP SERVER TO ... 2 CONCURRENT or more, one thread will be responsible for copying the InnoDB write-ahead log from the beginning of the backup, running InnoDB_backup::log_track(). Other files will be copied by other threads. Note: In single-threaded BACKUP SERVER TO, the parameter innodb_log_recovery_start that is written out to backup.cnf is STRICTLY NECESSARY TO AVOID CORRUPTION during recovery! By default, InnoDB crash recovery starts from the latest available log checkpoint. However, for restoring a backup, recovery must start from the checkpoint that was the latest when the backup was started. Starting recovery from a possible later checkpoint will result in a corrupted database! The backup or the first stream will contain a file backup.cnf, which includes parameters needed for restoring the backup. Currently, these are innodb_log_recovery_start and innodb_log_recovery_target. If innodb_log_recovery_target>0, InnoDB will be in read-only mode, not allowing any writes to persistent files other than via the log application. To restore a streaming backup made with BACKUP SERVER WITH, an empty directory needs to be created and all streams be extracted there using the standard tar utility of the operating system, optionally after undoing any encryption or compression that had been added by the backup command. Then, the backup is prepared or MariaDB server started up on the extracted directory, similar to as if the BACKUP SERVER TO statement had been used. The following will be implemented separately: MDEV-39061 mariadb-backup compatible wrapper script for BACKUP SERVER MDEV-40163 Partial backup and restore MDEV-39091 Back up ENGINE=RocksDB MDEV-40333 Concurrent DDL for Aria tables in BACKUP SERVER The implementation introduces a basic multi-threaded driver Sql_cmd_backup, storage engine interfaces, and basic copying of the storage engines InnoDB, Aria, MyISAM, MERGE (MyISAM), Archive, CSV. backup_target: A structured data type to represent a target directory. On Microsoft Windows, we must use directory paths because there is no variant of CopyFileEx() that would work on file handles. backup_sink: Wraps a per-thread output stream as well as storage engine specific context. The member "id" identifies the thread, between 0 and CONCURRENT-1. backup_context: Process-wide BACKUP SERVER context. Handles the directory traversal and copying of files for built-in storage engines that do not implement this backup interface. backup_target_stage: Wrap backup_context. backup_target_stage::step(), backup_context::step(): Process a file from a directory scan, or by invoking handlerton::backup_step(). handlerton::backup_file(): Check if a file should be included in the backup. Implemented for ENGINE=Aria in maria_backup_file(). handlerton::backup_start(), handlerton::backup_end(): Invoked at the start or end of a backup phase, in the thread that executes a BACKUP SERVER statement. handlerton::backup_step(): A backup step that can be invoked from multiple threads concurrently, between the execution of the corresponding handlerton::backup_start() and handlerton::backup_end() of the same phase. copy_entire_file(): A file copying service for POSIX systems. copy_file_range_try(): A wrapper for Linux copy_file_range(2), which may fail with EOPNOTSUPP or EXDEV and thus require a fallback to backup::copy(). backup::copy(): A partial or sparse file-copying service. On other platforms than FreeBSD or Microsoft Windows, there are shortcut alternatives to this. Note: On Linux we never invoke sendfile(2) for copying between files, because can be much slower than the alternatives. backup::copy_or_stream(): Copy or stream a file. backup_stream_append_plain(): A wrapper of backup::append(), which is the streaming equivalent of backup::copy(). backup_stream_zeropad(): Zero-pad the last tar block if needed. backup_stream_append_async(): A variant of backup_stream_append_plain() where the source file region is guaranteed to be immutable after the call returns. Zero-copy Linux sendfile(2) is inherently risky for copying data files that may be modified in place, because it could introduce a race condition between a page write that runs concurrently with a child process that is reading the data from the pipe. This could be improved with io_uring later. pread_write(): Allocate a buffer of up to 4 MiB. This is the "slow path" of copying or streaming files. maria_backup_start(): Copy ENGINE=Aria log files. (FIXME: currently single-threaded and race condition prone!) InnoDB_backup::init(): Wait for a possible previous BACKUP SERVER operation to reach the very end of InnoDB_backup::context::cleanup() so that the context can be safely reused. InnoDB_backup::queue: Collection of tablespace IDs and payload sizes at the start of the backup, and the log_sys.first_lsn of log files that have to be included in the backup. If any data file is created or extended while the backup is executing, we must have the corresponding write-ahead-log entries that we are copying since the latest checkpoint that was completed when the backup started. If any tablespaces are deleted during the backup, we may or may not copy them, and the application of a FILE_DELETE record will remove them. Similarly, applying FILE_RENAME or FILE_CREATE records will rename or create files during recovery as needed. InnoDB_backup::context::tracked: Log file queue for the dedicated log-copying task InnoDB_backup::log_track(). innodb_backup_log_tracking(): Determine if log-tracking backup is active, which blocks concurrent changes of innodb_log_file_buffering and innodb_log_file_write_through. log_sys.backup: Whether BACKUP SERVER is in progress. The purpose of this is to make BACKUP SERVER prevent the concurrent execution of SET GLOBAL innodb_log_archive=OFF or SET GLOBAL innodb_log_file_size when innodb_log_archive=OFF. log_sys.archived_checkpoint: Keep track of the earliest available checkpoint, corresponding to log_sys.archived_lsn. This reflects SET GLOBAL innodb_log_recovery_start (which is settable now), for incremental backup. fil_system.have_all_spaces: Whether all tablespace metadata is guaranteed to be known. To speed up startup, InnoDB does not normally open all tablespace files. fil_space_t::create_lsn: Change to Atomic_relaxed and use this to indicate tablespace creation LSN, in addition to indicate undo tablespace rebuild LSN. fil_space_t::backup_end: The first page number that is not being backed up (by default 0, to indicate that no backup is in progress). fil_space_t::BACKUP_BATCH_SIZE: The number of preceding pages that will be covered by fil_space_t::backup_end. This is the unit of "page range locking" during InnoDB backup. fil_node_t::backup_name: A snapshot of the file name, sampled in InnoDB_backup::init(). For backing up any files that were created before the backup start checkpoint LSN, these names will be written to the backup. On restore, the files will be renamed or deleted as needed, by applying FILE_RENAME or FILE_DELETE records. fil_node_t::rename(), fil_node_t::set_backup_name(), fil_node_t::get_backup_name(), fil_node_t::~fil_node_t(), fil_node_t::clear_backup_name(): Deal with fil_node_t::backup_name. buf_page_t::write_fix_try(), buf_page_t::write_unfix_try(): Try to set or unset a fake "write fix" on a page, to prevent concurrent flush() during a backup batch. The atomic operations may run concurrently with set_reinit() and set_freed(). The fake "write fix" does not prevent any concurrent read or write of the page data in the buffer pool; it only blocks writes to the underlying data file. buf_page_t::flush(): Atomically test and set write fix, and skip the operation if the fake "write fix" was set. buf_page_t::set_freed(), buf_page_t::set_reinit(): Employ a compare-and-exchange loop to accommodate for the "write fix". innodb_backup_batch_wait(): Look up any pages that we are about to back up. For any dirty pages, invoke buf_page_t::write_fix_try() to try to set a fake "write fix" lock-free. If the page is currently write-fixed between buf_page_t::flush() and buf_page_t::write_complete(), acquire and release a page U-latch to wait for the conflicting write to complete. InnoDB_backup::backup_batch_start(), InnoDB_backup::backup_batch_stop(): Adjust fil_space_t::backup_end and fake "write fix" of dirty pages to protect the copying of a range of pages from the underlying file. InnoDB_backup::commit(): Enqueue the remaining log to be copied. InnoDB_backup::checkpoint_complete(): If backup is running and commit() has not been called, add each completed innodb_archive_log=ON file to the queue. Else, skip or delete, as appropriate. InnoDB_backup::archive_create(), innodb_backup_archive_create(): Hook for log_t::archive_create(). log_t::backup_start(): If we were running with innodb_log_archive=ON, ensure that the latest file is a valid recovery starting point. That is, wait for the latest log checkpoint to be within the file. buf_flush_list_space(): Check for concurrent backup before writing each page. This is inefficient, but this function may be invoked from multiple threads concurrently, and it cannot be changed easily, especially for fil_crypt_thread(). fil_ibd_create(): Set fil_space_t::create_lsn after the file has been created. dict_load_tablespaces(): Determine the size of each file if upgrade==true. Backup depends on that. buf_dblwr_t::begin(), buf_dblwr_t::end(), buf_dblwr_t::size(): Accessors to allow BACKUP SERVER to skip the contents of the doublewrite buffer in the system tablespace. It is only useful for crash recovery in case a data page had been incompletely written by the time the server was killed. If the server is killed during a backup, the backup will be incomplete and unusable anyway. Furthermore, the page range locking makes page writes and backup mutually exclusive. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleg Smirnov
olernov@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-24684 Quadratic time for MIN/MAX/STD/VARIANCE as window functions Rename variables and add comments for better readability |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
bsrikanth-mariadb
srikanth.bondalapati@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41293: FederatedX: connection state after a net_read_timeout Problem: When reading the reply of the remote server times out, the client library compiled into the server returns without closing the connection and without setting a client error. FederatedX took the raw ER_NET_READ_INTERRUPTED for an error of the remote server and went on using a connection that still had the reply of the failed statement to arrive. As a result: * the next statement on that connection failed in various ways, either with ER_QUERY_ON_FOREIGN_DATA_SOURCE ("Server has gone away") or with an error packet that mysqltest took for a malformed packet; * inside a transaction, the following statements continued on a new remote session in autocommit mode, so they were committed on the remote server one by one even though the local transaction was later rolled back. The savepoints of the lost session were also still remembered by FederatedX. The same happened when the connection was lost while reading the reply. Fix: * After a timeout FederatedX closes the connection, so that the next statement opens a new one. The client still gets the error of the timeout, ER_NET_READ_INTERRUPTED. * Whenever the connection is gone after a failed statement, timeout or not, the state of the lost session (autocommit mode, savepoints) is forgotten and the local transaction is marked to be rolled back, so a new connection starts the transaction again. The closed connection is also freed, which was leaked before. * Errors of the client library are reported as ER_QUERY_ON_FOREIGN_DATA_SOURCE by ha_federatedx::info() as well, the same way as by the pushed down multi-table UPDATE/DELETE. * The error state of ha_federatedx, read by info(), is initialized. Test: federatedx_pushdown_upd_del covers the timeout of a pushed down multi-table UPDATE and DELETE and of reading a result, the statements after it, the same inside a transaction, a connection killed in the middle of a statement, client library errors in info(), and that an error of the remote server which merely has the code of ER_NET_READ_INTERRUPTED is not taken for a timeout. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thirunarayanan Balathandayuthapani
thiru@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41281 Unbounded Recursion in InnoDB FTS Boolean-Mode causes Stack-Overflow fts_ast_visit expr_lst: expr_lst sub_expr wrapped the expression list parsed so far in a newly created FTS_AST_LIST for every sub-expression, so a query such as '(word)' repeated N times built N nested lists. fts_ast_visit() recurses once per FTS_AST_LIST and overflowed the thread stack; the default thread_stack was exhausted at about 2300 repetitions. Append the sub-expression to the list that is already being built, and create a list only when there is none yet, the way the neighbouring expr_lst: expr_lst expr rule has always done. The sub-expressions now become siblings of a single list and the depth no longer grows. This also corrects '+term (subexpr)'. The FTS_EXIST pass used to run to completion in the inner list before the sub-expression was unioned at the outer level, so rows that matched only the sub-expression were returned. Based on mysql/mysql-server@e46e9db484a051db6ffb0abd2b06d3b38ef71a35 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-23500: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed in Diagnostics_area::set_ok_status upon multi-table update Analysis: When NULL field from internal temporary table is copied to NOT-NULL so there is error about truncation but this error is not reported so we get the failure. Fix: Return the error state. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41822 mariadb-binlog ASAN crash on corrupted binlog 1. verify that the null bitmap length doesn't overshoot row event end 2. pass the buffer length to calc_field_size(), so that it'd never read beyond the end |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Lawrin Novitsky
lawrin.novitsky@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fix in the cppmini submodule | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Kristian Nielsen
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41433: Infinite IO error on a binlog-in-engine master When the master uses binlog-in-engine, the slave is required to connect with GTID enabled, and an error is thrown in the dump thread if not. However, the error thrown was a custom error code, this is not handled correctly by the slave and resulted in the IO thread looping infinitely, reconnecting and immediately getting error about requiring GTID mode. Signed-off-by: Kristian Nielsen <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
nada
nadaelsayed163@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-37214 CREATE OR REPLACE USER must not drop the existing account on failure CREATE OR REPLACE USER used to DROP the existing account before validating the new definition, so a failure after the DROP (e.g. an unknown auth plugin) permanently deleted the account without writing anything to the binlog, diverging master and replicas. Validate and prepare the new account first; only wipe the account's privileges from the non-user grant tables once all checks pass, immediately before updating mysql.user/mysql.global_priv in place. A failure now leaves the existing account untouched. - CREATE OR REPLACE USER/ROLE now builds the replacement from a default row (as for a new account) instead of updating the old row field by field, so password, resource limits, SSL options and lock status do not survive the replace. - Orphan privileges (grant-table rows with no mysql.user row) are also removed. - Rebuild the role/user cross-reference arrays after a successful replace; without this, SHOW GRANTS could crash on an account that had been granted a role. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Fix use-after-poison on BINLOG with a Query event in EXECUTE IMMEDIATE Query_log_event::do_apply_event() freed thd->mem_root, which inside a BINLOG statement also freed the statement's own memory, e.g. Items of EXECUTE IMMEDIATE freed later in THD::cleanup_after_query(). Free thd->mem_root only in replication/wsrep appliers, as Rows_log_event::do_apply_event() does. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39306 fix race in versioning.rpl_row The slave created table t before the master's previous DROP TABLE t was replicated. Sync the slave after the drops. Reviewed by [email protected] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Kristian Nielsen
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41562: Old slave with semi-sync and binlog-in-engine master With binlog-in-engine, semi-sync replication is supported only when the slave (and the master) is at least MariaDB 13.2. So make sure to give an error if an old slave connects to a master with binlog-in-engine enabled and the slave has semi-sync enabled. Signed-off-by: Kristian Nielsen <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Raghunandan Bhat
raghunandan.bhat96@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40836: Window function in ORDER BY split twice by split_sum_func() Problem: A window function inside an ORDER BY expression was split twice by `split_sum_func()` first in `setup_order()`, then again in `JOIN::prepare()`. Each split adds the item to `ref_pointer_array`, which resulted in overflow. The split in `setup_order()` was added by MDEV-28094 (8c34eab) to fix a crash in - SELECT EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()); `check_and_do_in_subquery_rewrites()` dropped the ORDER BY of that subquery, so `JOIN::prepare()` never split it. But its window function was still registered with the select and processed, causing the crash. Fix: - When check_and_do_in_subquery_rewrites() drops the ORDER BY, also remove its window functions from `SELECT_LEX::window_funcs`. - Remove the window function split from `setup_order()`, so it is done only once, in `JOIN::prepare()`. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-23500: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed in Diagnostics_area::set_ok_status upon multi-table update Analysis: When NULL field from internal temporary table is copied to NOT-NULL so there is error about truncation but this error is not reported so we get the failure. Fix: Return the error state. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-22675: Assertion `offset < table->s->reclength' failed in dump_leaf_key Analysis: The reclength depends on the size of each field of the temporary table plus the null_bytes. Since null_bytes is 0 (because we’re in non-strict mode and the source table fields can never be null), there is no need to keep track of null values. Hence the total record length is just the sum of the sizes of both fields. The second field will always have size 0 because its value will always be an empty string. Hence it starts exactly where the first field ends which equal to reclength. Hence the assertion failure. Fix: If pack_length() is 0 (which means the size of field is 0) so assigning the result as empty string directly, the assertion is not valid in that case. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-22675: Assertion `offset < table->s->reclength' failed in dump_leaf_key Analysis: The reclength depends on the size of each field of the temporary table plus the null_bytes. Since null_bytes is 0 (because we’re in non-strict mode and the source table fields can never be null), there is no need to keep track of null values. Hence the total record length is just the sum of the sizes of both fields. The second field will always have size 0 because its value will always be an empty string. Hence it starts exactly where the first field ends which equal to reclength. Hence the assertion failure. Fix: If pack_length() is 0 (which means the size of field is 0) so assigning the result as empty string directly, the assertion is not valid in that case. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-36653: main.mysql_upgrade-28915 test case timeout Analysis: Concurrent execution of mysql_upgrade and the event scheduler causes a metadata locking (MDL) deadlock between ALTER TABLE on system tables and the initial loading/caching of the event table. Fix: Disable the event scheduler via 'SET GLOBAL event_scheduler=OFF' prior to running the upgrade in the test case. This prevents concurrent conflicts and allows the test to run reliably. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41761: SIGSEGV in sp_head::bind_input_param when trigger passes NEW/OLD row as OUT parameter to CALL Analysis: When passing Item_trigger_row trigger (NEW) to an OUT parameter, bind_input_param called get_item_splocal(). Because it returned a valid pointer, the engine attempted to access rcontext_handler(), which is null for trigger rows, causing a segmentation fault. Fix: Overriding get_item_splocal() in Item_trigger_row to return nullptr ensures the engine safely skips the invalid context handler lookup, preventing the crash. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| update C/C | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rucha Deodhar
rucha.deodhar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41760: SIGSEGV in Field_iterator_table::set_table on re-prepare of trigger SET NEW = (subquery) after DDL on referenced table Analysis Item_trigger_row items were not having proper setup and list tracking, so they were not getting saved or restored during expression re-parsing. So when table alteration happened the row items lost their correct table resulting in assertion failure. Fix Added setup function and tracking lists for row items to properly handle and re-bind items. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||