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

3029 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
Marko Mäkelä
7ee06258b5 Merge 10.11 into 11.4 2026-10-13 07:04:14 +03:00
PranavKTiwari
5e1d303aa6 MDEV-38839: Assertion (thd->state_flags & Open_tables_state::BACKUPS_AVAIL) || !thd->has_pending_row_events() failed in close_thread_tables on CREATE TABLE
Problem:
CREATE TABLE ... SELECT ... FOR UPDATE involving a MyISAM temporary table can trigger an assertion in close_thread_tables() when binary logging is enabled in MIXED mode.

Cause:
MyISAM temporary tables do not support row-level locking, so SELECT ... FOR UPDATE acquires a write lock even when the access is read-only. This causes the table to be incorrectly classified as a write operation, preventing binlog_truncate_trx_cache() from running and eventually triggering the assertion.

Fix:
Update decide_logging_format() to use tbl->updating to distinguish actual table modifications from read-only accesses. For read-only access to temporary non-transactional tables, mark the statement as STMT_READS_TEMP_NON_TRANS_TABLE instead of treating it as a write operation. This prevents incorrect write classification and avoids the assertion failure.
2026-10-10 18:04:57 +05:30
Rex Johnston
060012b3b7 MDEV-41225 Parse the ORDER BY tail of a wrapped parenthesized query in the wrapping select
A parenthesized query expression that already has its own ORDER BY or
LIMIT and is followed by another ORDER BY, e.g.

  (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY <expr> LIMIT 1

is wrapped into a derived table, and the outer ORDER BY/LIMIT is attached
to the wrapping select.  The grammar pushed the inner select before
parsing the tail, and add_tail_to_query_expression_body_ext_parens()
created the wrapper only after the tail had been parsed.  Anything that
is attached to the current select while the tail is being parsed was
therefore attached to the inner select, while the ORDER BY list itself
was moved to the wrapper:

- Window functions and their window specs were added to the inner
  select's window_funcs/window_specs.  The same Item_window_func was then
  in the wrapper's ORDER BY and in the inner select's window function
  list, which triggers the original assertion reported in MDEV-41225.

  (SELECT 1 FROM t1 LIMIT 1)
    ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER();

  The function is computed by the inner select over the rows before its
  LIMIT, so the outer ORDER BY sorts on wrong values
  (e.g. COUNT(*) OVER () returned 3 for a 2-row result).

- Subqueries were registered as units of the inner select.  An
  uncorrelated subquery in the tail crashed the server with SIGSEGV when
  it was executed by the outer filesort.  A correlated one resolved its
  outer references in the inner select (t1.c1) instead of the derived
  table.

The decision to wrap depends only on whether the inner select already
has a tail and on whether the outer tail has ORDER BY.  LIMIT and locking
clauses cannot contain window functions or subqueries.
We replace query_expression_tail with
query_expression_tail_with_order and query_expression_tail_no_order
so the mid-rule action knows whether an ORDER BY follows.
The new LEX::push_select_for_ext_parens_tail() creates the wrapper before
an ORDER BY tail is parsed when wrapping is required, and pushes it instead
of the inner select.  The tail's items are then created in the wrapper's
context, and window functions and subqueries are attached to the wrapper.
add_tail_to_query_expression_body_ext_parens() takes the pushed select and
skips wrapping when it has already happened; the other cases keep the
previous logic.  The grammar has the same number of conflicts as before.

A subquery in such a tail can no longer refer to the tables of the wrapped
query expression (e.g. t1.c1 above) and gets ER_BAD_FIELD_ERROR,
as those tables are not visible outside the derived table.

This commit was prepared with Claude Code (Opus 5.5). It traced the
wrong-result and crash cases to the parse-time registration of window
functions and subqueries in the inner select, tested the grammar split
with bison, wrote the code change and the brackets test.
2026-10-07 13:30:32 +13:00
KhaledR57
abd14722f2 MDEV-37167 Nested BEGINs (4600+) cause a segmentation fault
Each nested BEGIN adds one sp_pcontext. Two walks over the finished
tree recursed once per nesting level and overran the thread stack.

~sp_pcontext() freed its children recursively. sp_head now threads a
single linked list through the contexts and frees them iteratively, so
teardown depth is constant and a context no longer frees its children.

retrieve_field_definitions() descends the children to build the
run-time frame. It emits them in run-time offset order, so it stays
recursive, but it now checks the stack and returns an error instead
of crashing.
2026-09-10 17:00:23 +03:00
forkfun
33240f3c96 Merge branch '11.8' into '12.3' 2026-07-30 11:41:55 +02:00
forkfun
eaca80bf32 Merge branch '11.4' into '11.8' 2026-07-29 12:27:46 +02:00
forkfun
08eeb6a417 Merge branch '10.11' into '11.4' 2026-07-28 13:14:38 +02:00
forkfun
9d8ed0c0a2 MDEV-39522 Query with UNION fails in Oracle sql_mode with ER_BAD_FIELD_ERROR/ER_UNKNOWN_TABLE
MDEV-37325 unconditionally wrapped union subqueries in derived tables,
breaking name resolution of outer-scope/correlated references inside
the unions (producing ER_UNKNOWN_TABLE errors).

Delay the wrap until a following operator has a different linkage.
In Oracle mode all set operators share one priority and bind
left-to-right, so wrapping the accumulated prefix on each operator
change enforces it. This also corrects the row multiplicity of mixed
set operations toward left-to-right order.

create_priority_nest(): when the nest covers the whole prefix, point
the wrapper's first_nested at itself. Cut the prefix with
cut_next() before wrapping and re-register it on the outer unit;

Aleksey Midenkov:

In Oracle mode optimize_bag_operation() returns early, so union_distinct is
never recomputed and the stale value reaches execution.
Register the wrapper first, then run fix_distinct(): reset_distinct() now
scans the new outer chain (the wrapper alone) and correctly leaves
union_distinct NULL; a following DISTINCT operand re-establishes it.
2026-07-27 12:55:17 +02:00
Sergei Golubchik
2f92126946 Revert "MDEV-17677: Keywords followed by .number parsed as identifiers"
This reverts commit 895b28d672.
2026-07-24 17:06:40 +02:00
Dmitry Shulga
b5aa486a1c MDEV-36481: Abnormal server termination on second execution of stored routine that runs a cursor after table metadata in the query was changed
On parsing the statement 'DECLARE var1,...,varN TYPE OF cur DEFAULT value'
an instance of the class Item_splocal that created on handling the clause
'DEFAULT value' is shared between two classes sp_instr_cursor_copy_struct and
sp_instr_set. In result, in case metadata changed and cursor has to be re-parsed,
items associated with the SP instruction sp_instr_cursor_copy_struct
are deallocated and one of deallocated items is the one representing the value
the `DEFAULT value` clause. On the other hand, the data member
sp_instr_set::m_value still references the deallocated item. It leads to server
abnormal termination on second run of a stored routine containing the statement
'DECLARE ... TYPE OF ... DEFAULT value'

To fix the issue pass owning of an instance of the class Item_splocal to
the class sp_instr_cursor_copy_struct and deallocated it explicitly on
closing the stored routine.
2026-07-20 14:12:21 +02:00
bsrikanth-mariadb
c0f4063df3 MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE
"NOT column" rewrites itself into "column = 0" in fix_fields().
However the rewrite is not done when the "column" is wrapped in an Item_ref.

Later, pushdown_from_having_into_where() will strip the Item_ref object
and will call
  Item_func_not(Item_field())->fix_fields(thd, ref=NULL);
This call will attempt the rewrite and crash when writing into NULL pointer.

Fixed this in two places:
* Make Item_func_not::fix_fields() use real_item() and so recognize fields
  wrapped in Item_ref-like objects.

* Make pushdown_from_having_into_where() pass the right pointer as
  fix_fields() argument.
2026-07-15 19:25:30 +05:30
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
e7374f2ae7 Revert "MDEV-17677: Keywords followed by .number parsed as identifiers"
This reverts commit 895b28d672.
2026-05-21 16:15:35 +02:00
Oleksandr Byelkin
9cb70f0220 Merge branch '11.4' into 11.8 2026-05-08 08:11:03 +02:00
Oleksandr Byelkin
7598e4e95d Merge branch '10.11' into 11.4 2026-05-08 08:00:01 +02:00
Raghunandan Bhat
beb2015d5e MDEV-37491: Assertion (mem_root->flags & 4) == 0 failed in void *alloc_root(MEM_ROOT *, size_t)
Problem:
  Server crashes when a procedure with default parameter is executed and
  default value for the parameter is evaluated after the procedure's
  first execution. For example:

  CREATE PROCEDURE p(x INT DEFAULT (SELECT 1)) ...
  CALL p(1); -- first exec, marks mem_root read-only
  CALL p(); -- tries to allocate on locked when executing DEFAULT

Fix:
  Temporarily clear the read-only flag on the statement memory root to
  allow the allocation. Also adds a debug hook to verify allocation
  happens not more than once per prepared statement and per internal
  table added to the list.
2026-04-27 17:00:50 +05:30
Mahmoud Khaled
895b28d672 MDEV-17677: Keywords followed by .number parsed as identifiers
Problem:for example SELECT.1 treated as identifier instead of keyword + 0.1
     from starting identifiers after dot
2026-04-24 11:40:37 +03:00
Aleksey Midenkov
024bf19d89 MDEV-36362 MariaDB crashes when parsing fuzzer generated PARTITION
Function calls in INTERVAL expression of DDL have little
sense. SETVAL() fails because sequences require opened tables and
vers_set_interval() is called at earlier stage.

The fix throws ER_SUBQUERIES_NOT_SUPPORTED for sequence functions
SETVAL(), NEXTVAL(), LASTVAL() when the context does not allow
subselect (determined by clause_that_disallows_subselect).
2026-04-22 15:04:34 +03:00
Dave Gosselin
7f8dc5004d MDEV-39209: use iterative cleanup for merged units to avoid stack overflow
Query optimization can merge derived tables (VIEWs being a type of derived
table) into outer queries, leaving behind stranded  st_select_lex_unit objects
("stranded units") for post-query cleanup.

Previously, these were cleaned up recursively. For queries with many merged
derived tables, the deep recursion over the list of stranded units could
exhaust the stack. This change replaces the recursive cleanup with an
iterative loop to prevent stack overflows.
2026-04-20 09:34:09 -04:00
Abhishek Bansal
c79060ad79 MDEV-38474: ASAN heap-use-after-free in st_select_lex_unit::cleanup
cleanup_stranded_units() was added at the start of
st_select_lex_unit::cleanup() by 34a8209d66. This causes a
use-after-free when nested subqueries are merged into their parent
unit. With nested subqueries like:

  SELECT * FROM t1
  WHERE a IN (SELECT b FROM t2
              WHERE a IN (SELECT c FROM t3 WHERE FALSE HAVING c < 0));

the stranded_clean_list chains the units as: Unit1 -> Unit2 -> Unit3.
Because cleanup_stranded_units() was called first, Unit1->cleanup()
would recursively trigger Unit2->cleanup(), which in turn would
trigger Unit3->cleanup(). Unit3's cleanup frees its heap-allocated
join structures. But since Unit3 was merged into Unit2, Unit2 still
holds references to Unit3's structures (e.g., st_join_table). When
control returns to Unit2 for its own local cleanup, it accesses
already-freed memory.

Fix: move cleanup_stranded_units() to the end of cleanup(). This way,
each unit completes its own local cleanup first—clearing its
references to any child structures—before triggering cleanup of its
stranded (child) units. This enforces a parent-first cleanup order.
2026-04-20 09:34:09 -04:00
Yuchen Pei
3a7f7ce521 Merge branch '11.4' into 11.8 2026-04-20 13:16:55 +10:00
Sergei Golubchik
e95d77c18d MDEV-39154 wrong OOM handling in collect_grouping_fields()
correct (and document) the return values for collect_grouping_fields()
2026-04-19 11:36:16 +02:00
Yuchen Pei
c6fadc6e33 Merge branch '10.11' into 11.4 2026-04-16 11:28:26 +10:00
Sergei Petrunia
ba774a0a90 Fix in condition pushdown code: don't pass List<Field_pair> by value.
Affected functions:
  find_matching_field_pair(Item *item, List<Field_pair> pair_list)
  get_corresponding_field_pair(Item *item, List<Field_pair> pair_list)

Both only traverse the pair_list.
They use List_iterator so we can't easily switch to using const-reference.
2026-04-09 12:33:00 +03:00
Marko Mäkelä
55b3dced05 Merge 11.8 into 12.3 2026-04-02 09:15:17 +03:00
Marko Mäkelä
1a144f713a Merge 11.4 into 11.8 2026-04-01 15:03:59 +03:00
Marko Mäkelä
7c5cac0d51 Merge 10.11 into 11.4 2026-04-01 10:49:05 +03:00
Aleksey Midenkov
e955e6c8ea MDEV-28619 Server crash and UBSAN null-pointer-use in Window_funcs_sort::setup
Optimization in st_select_lex_unit::prepare() removes ORDER BY for
certain subqueries. That excludes ORDER BY items from being fixed, but
sl->window_funcs still contains window function items and those
related to optimized out ORDER BY are unfixed. The error about missing
window spec is thrown when the item is fixed. Hence we get redundant
processing of window function items without checking window spec
existence.

The fix removes the related window function items when ORDER BY is
optimized out. ORDER accumulates window_funcs at parser stage which
are then removed from SELECT_LEX::window_funcs. The fix also updates
similar optimization in mysql_make_view().
2026-03-28 23:27:41 +03:00
Marko Mäkelä
02aedc1065 Merge 11.8 into 12.3 2026-03-24 09:49:17 +02:00
Marko Mäkelä
e6b8cacfb9 Merge 11.4 into 11.8 2026-03-23 11:57:44 +02:00
Alexander Barkov
734670b962 MDEV-39115 FUNCTION does not exist error on package body assoc array variable
Problem:
When parsing `a.b()`, LEX::make_item_func_or_method_call() could not find
a package body variable 'a'.

Fix:
When searching for a variable, search not only in the current parse context,
but also in the parent package body context (if exists).
2026-03-19 12:38:20 +04:00
Abhishek Bansal
e0edd07c75 MDEV-38474: ASAN heap-use-after-free in st_select_lex_unit::cleanup
cleanup_stranded_units() was added at the start of
st_select_lex_unit::cleanup() by 34a8209d66. This causes a
use-after-free when nested subqueries are merged into their parent
unit. With nested subqueries like:

  SELECT * FROM t1
  WHERE a IN (SELECT b FROM t2
              WHERE a IN (SELECT c FROM t3 WHERE FALSE HAVING c < 0));

the stranded_clean_list chains the units as: Unit1 -> Unit2 -> Unit3.
Because cleanup_stranded_units() was called first, Unit1->cleanup()
would recursively trigger Unit2->cleanup(), which in turn would
trigger Unit3->cleanup(). Unit3's cleanup frees its heap-allocated
join structures. But since Unit3 was merged into Unit2, Unit2 still
holds references to Unit3's structures (e.g., st_join_table). When
control returns to Unit2 for its own local cleanup, it accesses
already-freed memory.

Fix: move cleanup_stranded_units() to the end of cleanup(). This way,
each unit completes its own local cleanup first—clearing its
references to any child structures—before triggering cleanup of its
stranded (child) units. This enforces a parent-first cleanup order.
2026-03-09 11:37:04 -04:00
Marko Mäkelä
f55deca2b2 Merge 10.11 into 11.4 2026-02-19 11:19:00 +02:00
Aleksey Midenkov
9aa8cf3420 MDEV-38799 Some views are broken in Oracle mode after upgrade to Q1 2026
wrap_select_chain_into_derived() inserts wildcard asterisk over
wrapped SELECT. setup_wild() expands the item wildcard but it does not
update field_translation name which still contains the asterisk. Field
translation was implemented for BUG#5147 to keep view column names
intact, find_field_in_view() uses these field translation names.

Now, the fix uses full field list instead of the wildcard in
wrap_select_chain_into_derived() whenever it is possible.
2026-02-16 17:03:06 +03:00
Alexey Botchkov
bd74c8cf7c MDEV-37261 Basic XML data type.
XMLTYPE column added.
Type_handler::get_column_attributes() added so parser can check
if unexpected attributes were specified for the UDT column.
2026-02-09 20:55:41 +01: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
be67aff19b Don't implicitly search in CURRENT_SCHEMA
the intention was not to, but some code paths weren't fixed yet
2026-02-06 17:46:52 +01:00
Sergei Golubchik
5b0818ee63 cleanup
* rename to follow the standard vprintf name convention
* remove `(LEX_CSTRING*) &lex_string` casts
* remove some redundant casts too
* LEX_CSTRING -> Lex_ident_db in path
* Hash_set<Sroutine_hash_entry>
* move assert out of the loop
* some comments and whitespace changes
2026-02-06 17:46:51 +01:00
Sergei Golubchik
7772bf07d8 remove LEX::make_sp_name_sql_path()
it confusingly didn't have anything to do with sql path,
so merged into LEX::make_sp_name()
2026-02-06 17:46:51 +01:00
Sergei Golubchik
823e625233 disallow SET PATH in sf or trg while parsing
but also when executing, of course
2026-02-06 17:46:51 +01:00
Sergei Golubchik
11210a2c05 PATH is not a chistic, it's like sql_mode, remembered implicitly per routine 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