1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

5019 Commits

Author SHA1 Message Date
Kristian Nielsen
ffaba7b55c Merge branch 'knielsen_log_event_read_validation_base_11.8' into 12.3
This merges the	patch series that fixes	a lot of missing validation
checks for read_log_event(). The merge includes a few added fixes that
are needed in new code introduced in 12.3.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-10-22 12:23:06 +02:00
Marko Mäkelä
7ba156d52e Merge 11.4 into 11.8 2026-10-16 09:25:49 +03:00
Sergei Golubchik
50dd408f81 Merge branch '10.11' into 11.4 2026-10-15 20:25:34 +02:00
Marko Mäkelä
8136047738 Merge 11.4 into 11.8 2026-10-15 07:47:24 +03:00
Oleksandr Byelkin
155a970264 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 <noreply@anthropic.com>
2026-10-14 15:21:15 +02:00
Sergei Golubchik
e03abdfec3 take old_mode and deprecation.h changes from 11.8-13.0
cherry-pick commits 9ecec1f730, 24fd8c7856, 3e97105975

* make it easier to add more old-mode values
* update deprecation.h to match changes in versioning
2026-10-13 16:43:20 +02:00
Sergei Golubchik
b2bc6c2f70 Merge branch '11.8' into 12.3 2026-10-07 22:10:46 +02:00
Vladislav Vaintroub
31c38a542d MDEV-41008: Fix X509 issuer/subject comparison for OpenSSL 3
OpenSSL 3 escapes '/' and '+' in X509_NAME_oneline() output; OpenSSL 1.1
and WolfSSL don't. A REQUIRE ISSUER/SUBJECT grant from one library can
stop matching after switching to another.

Default comparison stays strcmp(). old_mode=X509_LENIENT_COMPARE opts
into falling back to an escape-aware compare, applied to whichever side
the currently-linked library's own escaping affects, at the cost of
reopening the ambiguity a crafted certificate could exploit to
impersonate another identity.

Adds regression tests against a real certificate with an ambiguous CN

Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:13:28 +02:00
Dave Gosselin
db8ec28147 MDEV-40573: Crash on multi-table DELETE with an impossible WHERE
A DELETE containing a single table, an index hint, an impossible WHERE
condition, and a window function will take the multi-delete code path
but never initialize tables for deletion, leading to a crash.  Such
a statement would never delete rows from the target table.  Record in the
multi_delete whether it was ever initialized for execution, and don't
attempt to delete anything if it wasn't initialized.

The index hint forces the single table DELETE to take the multi-table
codepath.  Since this case has an impossible WHERE condition, we set
subq_exit_fl which later causes JOIN::optimize_stage2 to skip the
multi-delete table initialization.  It's not safe to attempt
initialization when trying to find a "tableless" subquery plan, so
defend against this case with the new multi-delete flag added by
this commit.
2026-09-25 10:49:28 -04:00
Oleksandr Byelkin
f860f2a937 Merge branch '11.8' into 12.3 2026-08-20 08:27:14 +02:00
Oleksandr Byelkin
3b8db45403 Merge branch '11.4' into 11.8 2026-08-19 11:28:01 +02:00
Oleksandr Byelkin
170b1d7073 Merge branch '10.11' into 11.4 2026-08-19 08:40:05 +02:00
Sergei Golubchik
1a572838e2 MDEV-40554 KILL checks user (not priv_user) and doesn't verify hostname
The "is it my own thread" check compared the login user name
(Security_context::user) and ignored the host, so u1@localhost could see
and kill threads of u1@'127.0.0.1'.

Compare the authenticated account instead:

* all comparisons are done in sctx->is_priv_user() now
* change user_matches() to priv_user_matches(), which uses is_priv_user()
* use it in KILL, KILL USER, SHOW PROCESSLIST, I_S.PROCESSLIST,
  COM_PROCESS_INFO and SHOW EXPLAIN/ANALYZE FOR.
* all the remaining places use is_priv_user() directly instead
  of doing strcmp: SHOW GRANTS, SHOW CREATE PROCEDURE, I_S.VIEWS,
  the DEFINER clause, optimizer trace and change_security_context().

Assisted-by: Claude:claude-5-opus
2026-08-01 19:44:19 +02:00
Sergei Golubchik
20d2217afa MDEV-40337 store user vars in a dedicated memroot
user_var_entry objects and their names have a connection lifetime,
they exist until the connection ends (or is reset), and then they're
all deleted at once. This is exactly the use case for MEM_ROOT,
let's store them there.

Additionally, let's set MY_ROOT_USE_VMEM flag to keep this memroot
off the general heap where user_var_entry values are stored
and where heap buffer overflows can happen.

The latter makes memory allocations for the MEM_ROOT about 10x more
expensive, so let's always start with an empty memroot (= zero overhead
if no user variables are used) and on THD cleanup let's retain one
memroot block (= zero overhead if the next connection takes THD from the
cache and uses user variables up to one block size).

Assisted-By: Claude:claude-4.8-opus
2026-07-29 13:05:09 +02:00
forkfun
867d16cea7 Merge branch '11.4' into '11.8' 2026-06-23 12:52:39 +02:00
forkfun
bbd558c386 Merge branch '10.11' into '11.4' 2026-06-22 12:26:09 +02:00
Oleksandr Byelkin
0d59c434fa Merge branch '10.6' into 10.11 2026-06-21 15:32:20 +02:00
Kristian Nielsen
fcc5fc8916 Merge 11.8 to 12.3
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 16:53:03 +02:00
Kristian Nielsen
420e28ce28 Merge 11.4 to 11.8
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 15:15:10 +02:00
Kristian Nielsen
85ec122c15 Merge 10.11 to 11.4
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 12:50:45 +02:00
Kristian Nielsen
40d6228811 Fix inconsistent terminology
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 10:43:23 +02:00
Dave Gosselin
0cd55af869 MDEV-39870: macOSB Build Warning on Typecast
On THD::reset, typecast the result of query_start_sec_part() to
tv_usec in a more portable way.  Previously, we assumed that the
left hand side was always long-compatible but that isn't the case
on mac.
2026-06-08 09:02:32 -04:00
Oleksandr Byelkin
9f98f82b14 Merge branch '11.8' into 12.3 2026-05-26 21:15:58 +02:00
Sergei Golubchik
6b35f1748d Merge branch '11.4' into 11.8 2026-05-23 21:43:50 +02:00
Sergei Golubchik
b4a80422bf Merge branch '10.11' into 11.4 2026-05-23 16:59:15 +02:00
Sergei Golubchik
197f92bee0 Merge branch '10.6' into 10.11 2026-05-23 16:55:50 +02:00
Sergei Golubchik
fe3039eef7 MDEV-39673 group_concat ignores max_allowed_packet
GROUP_CONCAT is limited by group_concat_max_len,
but also, as a string function it must respect max_allowed_packet.

Let's introduce THD::gconcat_max_len() helper to simplify checks.

Also:
* make max group_concat_max_len value the same as max max_allowed_packet
* use the same MY_MIN((ulonglong) ..., UINT_MAX32) in
  Item_func_json_objectagg as in Item_func_group_concat
* use overflow-safe type for lengths in Item_func_quote
  (MAX_MAX_ALLOWED_PACKET is 1G so uint cannot overflow yet, but it's
  a fragile assumption)
2026-05-20 22:49:21 +02:00
Daniel Black
509e40e706 MDEV-30518: JSON functions cannot be killed on big-endian
The json_engine killed_ptr was of type uchar however the enum
in the server is dependant on the architecture. On big-endian
architectures like IBM Z, retreiving a uchar* retreived the
unmodifed part of the THD->kill enum location and was always 0.

As C++11 allows enums to inherit a type, used uint32_t as the base
class of killed_state type in the server and used uint32_t in the
json library.

reload_acl_and_cache required an expression change to avoid
the compile error:
sql/sql_reload.cc:472:24: error: enumerated and non-enumerated
type in conditional expression [-Werror=enum-conversion]
  472 |  return result || (thd ? thd->killed : 0);

Added the kill_ptr assignment the following functions can be
killed:
* Item_func_json_depth::val_int
* Item_func_json_type::val_str
* Item_func_json_length::val_int

Item_func_json_array_append::val_str, check_killed() only applied
to json_error: label and not return_null.

Item_func_json_overlaps::val_bool ensure check_killed() is called.

Item_func_json_format::val_str(), corresponding to the SQL,
json_compact, json_detailed, json_loose - add debug instrumentation
for the func_json_notembedded test.

MDEV-26726 (fcd345de48) added a json_pause_execution sync point
however the test case used debug_max_statement_time, which doesn't
exist. Fix the sync point name in the test.
2026-05-14 08:44:01 +10:00
Michael Widenius
7828fb475b MDEV-32745 Add a simple MySQL to MariaDB upgrade helper
The tool is named mariadb-migrate-config-file.
The main purpose of the tool is to change MySQL option
files to work both for MySQL and MariaDB.
There are options to do the changes in the options file inline,
or at-end-of-file. One can also remove or comment unknown options.

The list of supported options is generated compile time from
mariadbd --help. All server options, including compiled plugins, are
supported.

The bulk of the code comes from Väinö.
Monty has updated it with a lot of extra options.
Wlad helped with cmake integration

Other things:
- Fixed a memory leak in sql_plugin.cc
- plugin-load will now in case of errors try to load all given plugins
  before aborted
- If silent-startup is used, plugin-load will not give errors for
  plugins it cannot load or warnings about plugin marturity level.
- my_rm_tree() will now delete symlinks, not the actual file, if
  MY_NOSYMLINK flag is used.
- my_stat() will now give data for symlink if MY_NOSYMLINKS is used.
- Added 'number of lines' option to mysqltest --cat_file

@Authors: Väinö Mäkelä <vaino.makela@iki.fi>,monty@mariadb.com
2026-05-01 15:14:06 +03:00
Sergei Golubchik
35f65007b7 cleanup: change sql_command_flags from uint to cf_flags_t
introduce a dedicated enum type for sql_command_flags
to simplify debugging:

(gdb) p sql_command_flags[SQLCOM_SELECT]
$2 = (CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | CF_PREOPEN_TMP_TABLES | CF_CAN_BE_EXPLAINED | CF_OPTIMIZER_TRACE)
2026-04-30 21:55:42 +02:00
Alexander Barkov
edb2e5467a MDEV-33830 Support for cursors on prepared statements
Adding support for cursors on prepared statements.

- SQL Standard way:
    DECLARE c CURSOR FOR stmt;
    PREPARE stmt FROM 'SELECT ?';
    OPEN c USING 1;

- Oracle-style way with SYS_REFCURSOR variables:
    DECLARE
      c SYS_REFCURSOR;
    BEGIN
      OPEN c FOR 'SELECT ?' USING 1;
2026-02-09 15:28:24 +04:00
Sergei Golubchik
4456eb1a5e Merge branch '12.2' into 12.3 2026-02-07 22:12:32 +01:00
Sergei Golubchik
6e086ce2a3 remove Sql_path_stack and Sql_path_push
don't create a permanent stack of paths on the heap and in THD.

Do it on the stack like for sql_mode, sctx, abort_on_warning, and
other THD properties that often need to be changed temporarily.

Fix Sql_path constructor.
2026-02-06 17:46:51 +01:00
Sergei Golubchik
0cac216e4f merge ErrConvMDQName into ErrConvDQName
and remove incorrect thd->db behavior
2026-02-06 17:46:50 +01:00
sts-kokseng.wong
19fd3c79b0 MDEV-34391 SET PATH statement
Definition
==========
Implement the SET PATH statement.
```
SET PATH 'schema1, schema2, schema3';
```

Function
--------
In MariaDB, the SQL-path will also be used to lookup packages in
package routine invocations, so the following script:

  SET PATH 'sys';
  SELECT UTL_ENCODE.BASE64_DECODE('data');

invokes SYS.UTL_ENCODE.BASE64_DECODE('data'), i.e. the function
BASE64_DECODE() in the packge UTL_ENCODE in the database SYS
(if such package and package routine exist).

MariaDB implementation details
------------------------------
The ticket's requirement stated the grammar should support delimited
identifiers with backticks or double quotes within the string quote,
ie: the single tick. A simple parser was implemented to handle this
requirement in Sql_path::from_text.

Only 16 schemas are supported per session - we do not want too many
schemas in the path anyway since it will impact performance. This also
means that the path cache is a simple static array for easier memory
management.
2026-02-06 17:46:50 +01:00
Sergei Golubchik
d653fcb564 Merge branch '11.8' into 12.2 2026-02-03 14:53:15 +01:00
Sergei Golubchik
9bfea48ce1 Merge branch '11.4' into 11.8 2026-01-31 14:08:54 +01:00
Sergei Golubchik
40f7084661 Merge branch '10.11' into 11.4 2026-01-28 21:52:18 +01:00
Monty
be237b3b0e MDEV-36290: Improved support of replication between tables of different structure
One can have data loss in multi-master setups when 1) both masters
update the same table, 2) ALTER TABLE is run on one master which
re-arranges the column ordering, and 3) transactions are binlogged
in ROW binlog_format.

This is because the slave assumes that all columns are in the same
order on the master and slave and all columns on the master also
exists on the slave. This happens even if binlog_row_metadata=FULL is
used.  If this is not the case, this will lead to silent data loss.

A new option for slave_type_conversions bit field,
ERROR_IF_MISSING_FIELD, has been added, along with a new error,
ER_SLAVE_INCOMPATIBLE_TABLE_DEF. This allows the user to define if
the slave should abort replication if it is missing some field that
existed on the master. The option is off by default to keep things
compatible with earlier versions.
If a field is missing on the slave and log_warnings >= 1, a warning
will be logged to the error log.

This patch fixes this, when binlog_row_metadata=FULL is used on the
master, by mapping fields with identical names on the master and slave.
If slave has fields that does not exist in the row event, these will
be set to their default value.

The main idea is that we added two conversion tables:
m_tabledef.master_to_slave_map[master_column_index] -> slave_column_index
and m_tabledef.master_to_slave_error[master_column_index] which contains
an error number if the master_column does not exist on the slave or
it is not possible to convert the master data to the slave column.
master_to_slave_error[#] contains 0 if the column exists and is compatible.

General code changes:
- Instead of looping over row fields in the order of slave table
  we are instead looping over fields in the order of the binary log.
- We are using table->write_set to know which fields should be updated
  on the slave. This is reflected in unpack_row
- We are calling TABLE::mark_columns_per_binlog_row_image() to ensure
  that rpl_write_set is properly set. This is needed if the slave also
  is doing binary logging.
- Before replication aborted if the master and slave tables were too
  different.  Now replication is only aborted if the row actually uses
  columns that does not exists on the slave (and ERROR_IF_MISSING_FIELD
  is used) or uses columns that cannot be converted.
  - Instead of giving errors in compatible_with(), used when table is
    accessed by first the row event, we are instead giving errors
    when we examine a row event and notice that it is accessing
    a not existing or not compatible field.

Other code changes:
- Removed conv_table argument from compatible_with() and store it
  directly in RPL_TABLE_LIST->m_conv_table
- table_def::compatible_with() returns now 1 on error (not 0).
- Remove m_width and skip arguments from prepare_record() as we are
  now using table->write_set() to check which elements need a default
  value.
- Moved DBUG_ENTER() to it's proper place (after variable
  declarations) in a few functions.
- Some changes in unpack_row():
  - Replaced null_mask and null_ptr with an indexed bit check for
    simplicity.
  - Removed check of rgi == null and table_found which never worked.
  - Updated comments to reflect current code.
  - Indentation changes as the code now uses 'continue' instead of
    'if-else' in the main loop.
  - The code to throw away 'extra master fields' is not needed as we
    are now looping over fields in binary log, not over fields in
    slave table.
- Simplified get_table_data(TABLE *table_arg) by returning found
  table_list.
- Errors for row events are now initialized in compatible_with(),
  checked in check_wrong_column_usage() and reported in
  give_compatibility_error().

Co-authored-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
2026-01-27 12:59:30 -07:00
Kristian Nielsen
7081f2a58e Binlog-in-engine: New binlog implementation integrated in InnoDB
Implement an improved binlog implementation that is integrated into
the storage engine. The new implementation is enabled with the
--binlog-storage-engine option. Initially the InnoDB storage engine
implements the binlog.

Integrating the binlog in the storage engine improves performance,
since it makes the InnoDB redo log the single source of truth and
avoids the need for expensive two-phase commit between binlog and
engine. It also makes it possible to disable durability (set
--innodb-flush-log-at-trx-commit=0) to further improve performance,
while still preserving the ability to recover the binlog and database
into a consistent state after a crash.

The new binlog implementation also greatly improves the internal
design and implementation of the binlog, and enables future
enhancements for replication.

This is a squash of the original 11.4-based patch series.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-01-23 03:21:03 +01:00
Oleg Smirnov
850d901b98 MDEV-35880: Fix incorrect error message when MAX_EXECUTION_TIME was exceeded
The error message shown when MAX_EXECUTION_TIME hint causes a timeout
incorrectly referred to "max_statement_time", which is a different
variable with different units (seconds vs milliseconds). This could
confuse users.

Before: "Query execution was interrupted (max_statement_time exceeded)"
After:  "Query was interrupted: execution time limit 1.5 sec exceeded"

The new message is neutral and accurate for both max_statement_time
system variable and MAX_EXECUTION_TIME optimizer hint, displaying the
actual timeout value that was exceeded.
2026-01-21 00:22:06 +07:00
Monty
0513a4a974 MDEV-38019 Send ok packet to client earlier
Send ok packet earlier for SELECT queries that does not have any updates.
This is done in select_send::send_eof()

Axel's select benchmarks shows that this has a notable speed improvement:
1  Thread:  28% TPS speedup
8  Threads: 23%
64 Threads  6%

This was meassured with t_oltp_point_select With InnoDB running the client
over sockets.

Other things:
- Moved error reporting of LIMIT ROWS EXAMINED from handle_select() to
  check_limit_rows_examined(). This is to ensure that the error is
  reported before send_eof() is called.
- Removed duplicate "Query execution was interrupted" messages for the
  same query. killed_for_exceeding_limit_rows_warning_given was introduced
  for this purpose. We cannot use 'killed' flag in
  killed_for_exceeding_limit_rows() to detect if we already have produced
  a warning as the 'killed' in this case is reset for each union.

Reviewer: Sergei Golubchik <serg@mariadb.org>
2026-01-14 19:07:38 +02:00
Alexander Barkov
4de773e90c MDEV-38451 SHOW FUNCTION CODE package_func crashes on the second execution
Routine name resolution performed on a temporary memory root
during execution. So on the second execution LEX::spname members
pointed to a cleared memory.

Fixing to peform the resolution to parse time, like the CALL statement does.
During the execution time LEX::spname members now stay untouched.
2026-01-13 15:37:08 +04:00
Oleg Smirnov
0397e4e4dc MDEV-27027 Atomic DDL: Assertion failed upon unsuccessful multi-RENAME TABLE
When executing an atomic sequence of RENAME operations, such as:
    RENAME TABLE t1 TO t2, t3 TO t4, ...
any failure in the sequence triggers a rollback of previously completed
renames to preserve atomicity.

However, when an error occurs, `my_error()` is invoked immediately, which
sets the `thd->is_error()` flag. This premature flag setting causes
the rollback logic to misinterpret the thread state, leading to incorrect
reversion behavior and assertion failures.

To address this, the errors are now not emitted immediately but captured
and postponed. A new class `Postponed_error_handler` is introduced for
this purpose. Only after all operations are completed (including
possible DDL reversion), the captured errors are emitted.
2026-01-09 20:17:35 +07:00
Sergei Golubchik
27c98794bb Merge branch '11.8' into 12.2 2026-01-08 12:02:45 +01:00
Sergei Golubchik
c1fcedf443 Merge branch '11.4' into 11.8 2026-01-05 20:34:44 +01:00
Marko Mäkelä
678ff03ee7 Merge 10.11 into 11.4 2026-01-02 11:53:09 +02:00
Aleksey Midenkov
10643cffe9 MDEV-37325 Incorrect results for INTERSECT ALL in ORACLE mode
Oracle mode has no priority between set-operators but the current
implementation with disable_index_if_needed() can not work with
arbitrary mix of distinct/non-distinct set-operators as the algorithm
is tied to the properly wrapped version of expression. Index can be
disabled only once and cannot be reenabled afterwards.

To adapt Oracle mode for the aforementioned implementation we
prioritize each set operator with parens in the order of
appearance. So the expression:

  S1 op1 S2 op2 S3 op3 S4

will be rewritten like this:

  (((S1 op1 S2) op2 S3) op3 S4).

The rewritten expression is valid for both Oracle and default mode and
renders the same result. Prioritizing is done with
create_priority_nest() but it was tweaked to work with derived to be
the first operand. Originally create_priority_nest() could wrap only
second operand, like this:

  S1 op1 S2 op2 S3 -> S1 op1 (S2 op2 S3).

Now this behaviour is kept by non-NULL attach_to argument. With NULL
attach_to argument it produces this transformation:

  S1 op1 S2 -> (S1 op1 S2), but to be strict it will look like this:
  SELECT .. FROM (S1 op1 S2).

This expression is treated as the first one in the select list, so
nothing to "attach to".

On importance of not making fake_select_lex after
create_priority_nest() in parsed_select_expr_start(). This will fail
nastily in Protocol::valid_handler() check in store_longlong() for
EXPLAIN. This happens because select_options are inherited from newly
made fake_select_lex but without SELECT_DESCRIBE flag which is meant
to be assigned by mysql_explain_union() but union_needs_tmp_table() is
false (because now top-level unit has no set-operator, it is just
select from derived), so SELECT_DESCRIBE assignment is
skipped. Depending on that flag send_result_set_metadata() is
conditionally executed in JOIN::exec_inner(). And originally it is
done via select_describe() branch for top-level select when there is
no set operator (it is select from derived as explained above), not
via direct send_result_set_metadata().

On IS_OR_WAS_ORACLE. Sql_mode_save_for_frm_handling removes MODE_ORACLE
when view is registered or opened. We cannot return it back as this
conflicts with MDEV-12478 (tested by compat/oracle.func_concat). So we
are temporarily adding WAS_ORACLE flag instead. WAS_MODE_ORACLE is for
testing both WAS_ORACLE and MODE_ORACLE simultaneously.
2025-12-23 14:02:55 +03:00
Andrei Elkin
f3a5d38fa7 Revert "MDEV-37686 rpl.create_or_replace_mix2 fails in MDEV-35915 branch"
This reverts commit 3241798214.
Due to MDEV-38212.
2025-12-04 19:26:40 +02:00
Sergei Petrunia
8647354f6b MDEV-38164: Fix the estimates reported by TABLE::key_storage_length()
(Cherry-pick into 12.2: the fix is enabled by default,
 control via @@new_mode=FIX_INDEX_LOOKUP_COST is removed)

They were based on the maximum possible length key length, which
can be much larger than the actual data.

The return value is used by handler::keyread_time(), which is used
to estimate the cost of range access.
This could cause range access not to be picked, even if it uses
the clustered PK and reads about 8% of the table.

The fix is to add KEY::stat_storage_length (next to KEY::rec_per_key) and
have the storage engine fill it in handler::info(HA_STATUS_CONST).

Currently, only InnoDB fills this based on its internal statistics:
index->stat_index_size and ib_table->stat_n_rows.

Also changed:
- In handler::calculate_costs(), use ha_keyread_clustered_time() when
  computing clustered PK read cost, not ha_keyread_time().
2025-12-02 15:13:02 +02:00