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

2146 Commits

Author SHA1 Message Date
Alexander Barkov
bfabe0e530 MDEV-39518 Allow prepared statements in stored functions in assignment right hand
Allowing prepared statements in stored functions when
a stored function is used in an assignment right hand.

Both DEFAULT clause of a variable initialization and
the right side of the SET statement are supported:

  CREATE PROCEDURE p1()
  BEGIN
    -- case 1: DEFAULT clause
    DECLARE spvar1 INT DEFAULT f1_with_ps(); -- OK

    -- case 2: SP variable assignment statement
    DECLARE spvar2 INT;
    SET spvar2= f1_with_ps(); -- OK
  END;

- Only assignments to SP variables works for now:
  * SET spvar= func_with_ps(); -- OK
  * SET @uvar= func_with_ps(); -- Error

- Only bare function calls are supported for now. Using a function in
  an expression does not make it PS-safe yet:
    SET v= f1()+0;

- The parser now does not reject PS statements in stored functions.
  PS applicability in stored functions is now detected at run time.
  Note, PS statements in triggers are still prohibited by the parser.

- Functions with PS do not acquire MDL locks on tables, and no MDL is
  taken on the routines themselves either. They work like procedures in
  terms of table opening and routine locking: a concurrent DROP FUNCTION
  can complete while such a function is executing.

- Functions with PS are not replicated as a single `SELECT f1()` call.
  They are replicated per-statement, like procedures.

Helper changes:
- Changing the return result for LEX::sp_variable_declarations_init()
  from void to bool to catch errors in the caller properly.

Misc:
- This patch incorporates fixes for the following bugs found during debugging:
  MDEV-40224,MDEV-40225,MDEV-40226,MDEV-40227,MDEV-40240,
  MDEV-40285,MDEV-40288,MDEV-40315,MDEV-40318,MDEV-40890,MDEV-40900,
  MDEV-40901,MDEV-40913,MDEV-40914,MDEV-41013,MDEV-41015,MDEV-41019

Assisted-by: Claude - reviews and minor clean-ups
2026-09-08 08:12:46 +04:00
forkfun
b8dbc264f0 Merge branch '13.0' into 'main' 2026-08-03 13:42:39 +02:00
forkfun
1a4bb1bbfd Merge branch '12.3' into '13.0' 2026-07-30 16:15:40 +02: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
ad7f29afb3 Merge branch 10.6 into 10.11 2026-07-23 11:12:27 +02:00
Sergei Golubchik
40c5d53793 MDEV-30942 MSAN_OPTIONS=poison_in_dtor=1 causes failures in free_root()
Materialized_cursor included MEM_ROOT where it itself (Materialized_cursor)
was allocated. Materialized_cursor inherits from Server_side_cursor,
and Server_side_cursor::operator delete frees this mem_root.

This offends MSAN with poison_in_dtor, because when Materialized_cursor
is destroyed, MEM_ROOT is poisoned and Server_side_cursor::operator delete
accesses memory it really shouldn't.

Fix:
* MEM_ROOT is moved into Server_side_cursor. Materialized_cursor is
  the only class inheriting from it, so nobody is affected.
* operator delete is replaced with a function cdestroy() which
  saves the MEM_ROOT, deletes the object, then frees the root.
* cannot close() from ~Materialized_cursor anymore, main_mem_root
  should be copied before the destruction
2026-07-22 13:22:04 +02:00
Alexander Barkov
9b075b2cb5 MDEV-40396 open SYS_REFCURSOR crash, if too many cursors
When THD::m_statement_cursor was resized by a call of alloc_dynamic,
the memory location of all sp_cursor::result changed.
Therefore all members "select_result *Server_side_cursor::select"
previously initialized in the constructor to addresses of
sp_cursor::result became invalid.

Fix:
- Removing the member "select_result *result;" from Server_side_cursor.
- Passing instead a new "select_result *" parameter to
  methods open() and fetch() of Server_side_cursor and its descendant
  Materialized cursor.

So now, for example, when sp_cursor::fetch() is called, it executes:

    server_side_cursor->fetch(&result/*new parameter*/, 1);

The address value `&result` is now always correct.
2026-07-21 08:42:20 +04:00
Vladislav Vaintroub
934108aab5 MDEV-14443 DENY statement
Implements DENY/REVOKE DENY and associated tasks.
2026-07-20 13:23:00 +03:00
Alexander Barkov
980c911c5b MDEV-39022 Add LOCAL spvar syntax for prepared statements and SYS_REFCURSORs
This patch adds the following syntax:

OPEN c0 FOR LOCAL spvar_with_ps_name;
PREPARE LOCAL spvar_with_ps_name FROM 'dynamic sql';
EXECUTE LOCAL spvar_with_ps_name;
DEALLOCATE PREPARE LOCAL spvar_with_ps_name;

OPEN c0 FOR PREPARE stmt;
2026-07-14 14:22:31 +04:00
Oleksandr Byelkin
9f98f82b14 Merge branch '11.8' into 12.3 2026-05-26 21:15:58 +02:00
Oleksandr Byelkin
f572addcc1 Merge branch '12.3' into 13.0 2026-05-22 09:52:05 +02:00
Oleksandr Byelkin
3f388a1cce Merge branch '11.8' into 12.3 2026-05-22 09:27:18 +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
Oleksandr Byelkin
6828ff7390 Merge branch '10.6' into 10.11 2026-05-08 07:38:22 +02:00
Oleg Smirnov
9b714f5534 MDEV-38045: Implement implicit query block names for optimizer hints
This patch implements support for implicit query block (QB) names in
optimizer hints, allowing hints to reference query blocks and tables
within derived tables, views and CTEs without requiring explicit
QB_NAME hints.

Examples.
-- Addressing a table inside a derived table using implicit QB name
select /*+ no_index(t1@dt) */ *
  from (select * from t1 where a > 10) as DT;
-- this is an equivalent to:
select /*+ no_index(t1@dt) */ * from
  (select /*+ qb_name(dt)*/ * from t1 where a > 10) as DT;
-- Addressing a query block corresponding to the derived table
select /*+ no_bnl(@dt) */ *
  from (select * from t1, t2 where t.1.a > t2.a) as DT;

-- View
create view v1 as select * from t1 where a > 10 and b > 100;
-- referencing a table inside a view by implicit QB name:
select /*+ index_merge(t1@v1 idx_a, idx_b) */ *
  from v1, t2 where v1.a = t2.a;
-- equivalent to:
create view v1 as select /*+ qb_name(qb_v1) */ *
  from t1 where a > 10 and b > 100;
select /*+ index_merge(t1@qb_v1 idx_a, idx_b) */ *
  from v1, t2 where v1.a = t2.a;

-- CTE
with aless100 as (select a from t1 where b <100)
  select /*+ index(t1@aless100) */ * from aless100;
-- equivalent to:
with aless100 as (select /*+ qb_name(aless100) */ a from t1 where b <100)
  select /*+ index(t1@aless100) */ * from aless100;

Limitations:
  - Only SELECT statements support implicit QB names. DML operations
    (UPDATE, DELETE, INSERT) only support explicit QB names
2026-04-30 16:58:47 +07:00
Sergei Golubchik
c0fb844833 MDEV-39493 FILE privilege isn't checked for derived
check global privileges separately,
before checking for per-table SELECT_ACL
2026-04-29 15:38:03 +02:00
Sergei Golubchik
92641e4aa8 MDEV-39478 COM_STMT_EXECUTE incorrectly checks for parameter value length
* remove redundant checks for `len` in `get_param_length()`
* validate return value `length` in `get_param_length()`
* fix all `Item_param::set_param_XXX()` methods to never read past `len`

note that all `Item_param::set_param_XXX()` methods correctly handle
zero-length values.
2026-04-29 15:38:03 +02:00
Mikhail Pochatkin
cbcff6324a MDEV-39173 Replace sprintf with snprintf, remove deprecated pragma
Remove the unscoped #pragma GCC diagnostic ignored
"-Wdeprecated-declarations" from include/violite.h and replace all
sprintf/vsprintf calls with snprintf/vsnprintf across the codebase.

Where possible, pass actual buffer sizes as function parameters
instead of using hardcoded constants or recomputing strlen().
Notable API changes:
- get_date(): added to_len parameter for buffer size
- nice_time(), end_timer() in client/mysql.cc: added buff_size
- generate_new_name(): added name_size parameter
- calc_md5(): added buffer_size parameter (fixes off-by-one)
- MD5_HASH_TO_STRING macro: added _size parameter
- Added MYSQL_UDF_MAX_RESULT_LENGTH constant in mysql_com.h

Also fixed a pre-existing bug in sql/rpl_mi.cc where the ellipsis
"..." was written to the wrong buffer (dbuff instead of buff).

Vendored code is excluded: extra/readline, extra/wolfssl,
wsrep-lib, libmariadb, storage/mroonga/vendor, zlib.
2026-04-16 19:00:12 +10:00
Alexander Barkov
90f8178f33 MDEV-10152 Add support for TYPE .. IS REF CURSOR
Adding support for the strict cursor data types:

Example 1a:
  TYPE rec0_t IS RECORD (a INT, VARCHAR(10));
  TYPE cur0_t IS REF CURSOR RETURN rec0_t;

Example 1b:
  TYPE rec0_t IS RECORD (a t1.a%TYPE, b t1.b%TYPE);
  TYPE cur0_t IS REF CURSOR RETURN rec0_t;

Example 1c:
  TYPE rec0_t IS RECORD (a INT, VARCHAR(10));
  r0 rec0_t;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example 1d:
  TYPE rec0_t IS RECORD (a t1.a%TYPE, b t1.b%TYPE);
  r0 rec0_t;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example2a:
  TYPE cur0_t IS REF CURSOR RETURN t1%ROWTYPE; -- t1 is a table

Example 2b:
  r0 t1%ROWTYPE;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example3a:
  CURSOR cursor_sample IS SELECT a,b FROM t1;
  TYPE cur0_t IS REF CURSOR RETURN cursor_sample%ROWTYPE;

Example3b:
  CURSOR cursor_sample IS SELECT a,b FROM t1;
  r0 cursor_sample%ROWTYPE;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

If a cursor variable is declared with a RETURN clause then:
1. At OPEN type the data type of the SELECT list row is compared
  for compatibility with the cursor RETURN data type.
  The SELECT list row must be assignable to the RETURN type row.
  If case if assignability is not meet, an error is raised
  Assignability means:
  - The arity of the SELECT list must be equal to the arity
    of the RETURN clause
  - Every n-th field of the SELECT list must be assignable to the
    n-th field of the RETURN Clause

2. At FETCH time, the data is fetched in two steps:
  a. On the first step the data is fetched into a virtual table
     with the row type described in the RETURN clause
  b. On the second step the data is copied from the virtual table
     to the target fetch list. Data type conversion can happen
     on this step.

Change details:

Adding new methods:
- sp_cursor::check_assignability_to
- Virtual_tmp_table::check_assignability_from
- Virtual_tmp_table::sp_set_from_select_list
- Virtual_tmp_table::sp_save_in_vtable
- Virtual_tmp_table::sp_save_in_target_list
- LEX::check_ref_cursor_components
- LEX::make_sp_instr_copy_struct_for_last_context_variables
- LEX::declare_type_ref_cursor
- sp_cursor::Select_fetch_into_spvars::send_data_with_return_type

Adding new members:
- sp_instr_copen_by_ref::m_cursor_name
- Select_fetch_into_spvars::m_return_type
- Select_materialize::m_cursor_name
- Select_materialize::m_return_type

Adding new virtual methods:
- Item::resolve_spvar_cursor_rowtype
- Type_handler::Spvar_definition_resolve_type_refs
- Server_side_cursor::check_assignability_to
- Overriding Select_materialize::prepare to raise an error when the cursor
  returned data type is not compatible with the RETURN clause

Making these methods virtual:
- Field::check_assignability_from

Adding new classes:
- sp_type_def_ref
- RowTypeBuffer

Adding new constructors to:
- Spvar_definition

Adding new helper methods (e.g. to reuse the code)
- Field::store_field_maybe_null
- ChanBuffer::append_ulonglong
- sp_pcontext::set_type_for_last_context_variables

Minor changes:
- Making TABLE::export_structure const
- Overriding Item_splocal::type_extra_attributes. It was forgotten in earlier changes.

Adding new error messages
- ER_CANNOT_CAST_ON_IDENT1_ASSIGNMENT_FOR_OPERATION
- ER_CANNOT_CAST_ON_IDENT2_ASSIGNMENT_FOR_OPERATION
2026-04-06 15:16:38 +04: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
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
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
d1fd168d9c remove unused arguments 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
Sergei Golubchik
b29d3779e4 Merge branch '10.6' into 10.11 2026-01-28 14:22:20 +01:00
Sergei Golubchik
71d4cae866 MDEV-37503 UBSAN: downcast Item_func_plus to Item_field invalid in sql_prepare.cc:1516
use reinterpret_cast to silence UBSAN.
add a debug check to make sure the wrong value is never used.
2026-01-26 10:01:31 +01:00
Sergei Golubchik
cb31d7536b MDEV-38604 Assertion `thd->utime_after_query >= thd->utime_after_lock' failed in query_response_time_audit_notify on 2nd execution of SP with query cache
even when PS is served from a query cache, thd->utime_after_query
must be updated.

also, backport the assert from 11.8
2026-01-23 12:15:34 +01: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
Marko Mäkelä
8fab129382 Merge 10.6 into 10.11 2026-01-02 11:06:05 +02:00
Sergei Golubchik
317fb10915 MDEV-38375 do MYSQL_AUDIT_GENERAL_STATUS on ps execute too
just like slow logging, MYSQL_AUDIT_GENERAL_STATUS
should be done inside Prepared_statement::execute()
2025-12-27 14:39:37 +01:00
Aleksey Midenkov
9f70e0a76c MDEV-32299 Segfault when preparing unreferenced select in recursive CTE
With_element::prepare_unreferenced() contains query from recursive CTE
which is upper owner of unreferenced CTE itself. Such recursive
derived table is resolved into its expression and it tries to resolve
fields or any other data from subqueries which are not yet
prepared. These subqueries are preparing in upper frames of the same
stack after prepare_unreferenced() finishes.

That does not happen when recursion happens in referenced CTE because
in that case there are links between the derived tables defined by the
parser and descending into such recursion descends further into all
the dependency queries. No such link exists in unreferenced query
therefore it misses its upper dependencies.

The fix moves prepare_unreferenced() later after JOIN::prepare() so it
has the chance to access all the prepared data.

There may be another fix of failing unreferenced queries with error as
such kind of queries seem to be not usable.
2025-12-23 13:42:45 +03:00
Dave Gosselin
049ee29e7e MDEV-37260 Implicitly named query blocks, CREATE VIEW AS supports hints
Query blocks have implicit names, such as `select#1`, formulated
by appending their select number to the string `select#`.  This patch
allows hints to scope their applicability by implicit query block
name.  For example,
  SELECT /*+ JOIN_ORDER(@`select#2` t1, t2) */ ...
@`select#2` is an implicit query block name.  Users can control hint
applicability per query block without first naming the blocks with
QB_NAME().

Hints may now be specified within VIEWs during their creation and
they are applied locally within that VIEW's scope.  For example,
  CREATE VIEW v1 AS
    SELECT /*+ IGNORE_INDEX(t1 idx1) */ FROM t1 ... GROUP BY ... HAVING ...
In many cases and for some parts of the VIEW, the query plan
doesn't really depend on how the VIEW is used, so it makes sense
to control a part of the query plan from the VIEW definition.

Implicit names are not yet supported in VIEWs.  Attempting to create
a VIEW with an implicit name reference will cause the server to create
the VIEW, but it will emit a warning and exclude that hint from the query.
2025-10-27 10:29:22 -04:00
Oleksandr Byelkin
c976b527db Merge branch '11.8' into bb-12.1-release 2025-10-08 09:05:38 +02:00
Marko Mäkelä
e8ef8c0055 Merge 10.11 into 11.4 2025-09-24 13:40:09 +03:00
Aleksey Midenkov
32e9871917 MDEV-37404 Cleanups
Deadcode leftovers.
2025-09-19 12:31:14 +03:00
Aleksey Midenkov
2667b544ed MDEV-37404 Cleanups
Deadcode leftovers.
2025-09-18 15:59:52 +03:00
Sergei Golubchik
aab83aecdc Merge branch '11.8' into 12.0
main/statistics_json.result is updated for f8ba5ced55 (MDEV-36099)

The test uses 'delete from t1' in many places and then populates
the table again. The natural order of rows in a MyISAM table is well
defined and the test was implicitly relying on that.

before f8ba5ced55 delete was deleting rows one by one, using
ha_myisam::delete_row() because the connection was stuck in rbr mode.
This caused rows to be shown in the reverse insertion order (because of
the delete link list).

MDEV-36099 fixes this bug and the server now correctly uses
ha_myisam::delete_all_rows(). This makes rows to be shown in the
insertion order as expected.
2025-07-31 20:55:47 +02:00
Sergei Golubchik
b565b3e7e0 Merge branch '11.4' into 11.8 2025-07-28 21:29:29 +02:00
Sergei Golubchik
c4ed889b74 Merge branch '10.11' into 11.4 2025-07-28 19:40:10 +02:00
Sergei Golubchik
053f9bcb5b Merge branch '10.6' into 10.11 2025-07-28 18:06:31 +02:00
Sergei Golubchik
c27d78beb5 MDEV-36870 Spurious unrelated permission error when selecting from table with default that uses nextval(sequence)
Lots of different cases, SELECT, SELECT DEFAULT(),
UPDATE t SET x=DEFAULT, prepares statements,
opening of a table for the I_S, prelocking (so TL_WRITE),
insert with subquery (so SQLCOM_SELECT), etc.

Don't check NEXTVAL privileges in fix_fields() anymore, it cannot
possibly handle all the cases correctly. Make a special method
Item_func_nextval::check_access() for that and invoke it from

* fix_fields on explicit SELECT NEXTVAL()
  (but not if NEXTVAL() is used in a DEFAULT clause)
* when DEFAULT bareword in used in, say, UPDATE t SET x=DEFAULT
  (but not if DEFAULT() itself is used in a DEFAULT clause)
* in CREATE TABLE
* in ALTER TABLE ALGORITHM=INPLACE (that doesn't go CREATE TABLE path)
* on INSERT

helpers
* Virtual_column_info::check_access() to walk the item tree and invoke
  Item::check_access()
* TABLE::check_sequence_privileges() to iterate default expressions
  and invoke Virtual_column_info::check_access()

also, single-table UPDATE in prepared statements now associates
value items with fields just as multi-update already did, fixes the
case of PREPARE s "UPDATE t SET x=?"; EXECUTE s USING DEFAULT.
2025-07-09 18:04:46 +02:00