1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-09 11:41:36 +03:00
Commit Graph

2851 Commits

Author SHA1 Message Date
Marko Mäkelä
ad13fb36bf Merge 10.6 into 10.11 2024-01-17 17:37:15 +02:00
Yuchen Pei
d06b6de305 Merge branch '10.5' into 10.6 2024-01-11 12:59:22 +11:00
Yuchen Pei
c9902a20b3 Merge branch '10.4' into 10.5 2024-01-10 18:01:46 +11:00
Igor Babaev
54ed3939f7 MDEV-31657 Crash on query using CTE with the same name as a base table
If a query contained a CTE whose name coincided with the name of one of
the base tables used in the specification of the CTE and the query had at
least two references to this CTE in the specifications of other CTEs then
processing of the query led to unlimited recursion that ultimately caused
a crash of the server.

Any secondary non-recursive reference to a CTE requires creation of a copy
of the CTE specification. All the references to CTEs in this copy must be
resolved. If the specification contains a reference to a base table whose
name coincides with the name of then CTE then it should be ensured that
this reference in no way can be resolved against the name of the CTE.
2024-01-03 09:57:39 -08:00
Sergei Golubchik
c154aafe1a Merge remote-tracking branch '11.3' into 11.4 2023-12-21 15:40:55 +01:00
Sergei Golubchik
7f0094aac8 Merge branch '11.2' into 11.3 2023-12-21 02:14:59 +01:00
Sergei Golubchik
fef31a26f3 Merge branch '11.1' into 11.2 2023-12-20 23:43:05 +01:00
Sergei Golubchik
7a5448f8da Merge branch '11.0' into 11.1 2023-12-19 20:11:54 +01:00
Sergei Golubchik
fd0b47f9d6 Merge branch '10.6' into 10.11 2023-12-18 11:19:04 +01:00
Alexander Barkov
aed9c656a9 MDEV-32101 CREATE PACKAGE [BODY] for sql_mode=DEFAULT
This patch adds PACKAGE support with SQL/PSM dialect for sql_mode=DEFAULT:

- CREATE PACKAGE
- DROP PACKAGE
- CREATE PACKAGE BODY
- DROP PACKAGE BODY
- Package function and procedure invocation from outside of the package:
    -- using two step identifiers
    SELECT pkg.f1();
    CALL pkg.p1()

    -- using three step identifiers
    SELECT db.pkg.f1();
    CALL db.pkg.p1();

This is a non-standard MariaDB extension.

However, later this code can be used to implement
the SQL Standard and DB2 dialects of CREATE MODULE.
2023-12-18 13:34:55 +04:00
Sergei Golubchik
e95bba9c58 Merge branch '10.5' into 10.6 2023-12-17 11:20:43 +01:00
Aleksey Midenkov
5462b61b0c MDEV-22164 without validation for exchange partition/convert in
1. WITHOUT/WITH VALIDATION may be added to EXCHANGE PARTITION or CONVERT TABLE:

  alter table tp exchange partition p1 with table t with validation;
  alter table tp exchange partition p1 with table t; -- same as with validation
  alter table tp exchange partition p1 with table t without validation;

2. Optional THAN keyword for RANGE partitioning. Normally you type:

  create table tp (a int primary key) partition by range (a) (
    partition p0 values less than (100),
    partition p1 values less than maxvalue);

  Now you may type (PARTITION keyword is also optional):

  create table tp (a int primary key) partition by range (a) (
    p0 values less (100),
    p1 values less maxvalue);
2023-12-07 17:37:01 +03:00
Sergei Golubchik
98a39b0c91 Merge branch '10.4' into 10.5 2023-12-02 01:02:50 +01:00
Marko Mäkelä
02701a8430 Merge 11.2 into 11.3 2023-11-28 11:19:50 +02:00
Marko Mäkelä
0d29f3759c Merge 11.1 into 11.2 2023-11-28 11:19:06 +02:00
Marko Mäkelä
edc478847b Merge 11.0 into 11.1 2023-11-24 15:58:35 +02:00
Vladislav Vaintroub
bb8e1bf7a2 Merge 11.3 into 11.4 2023-11-21 15:43:20 +01:00
Marko Mäkelä
90d968dab9 Merge 10.6 into 10.11 2023-11-20 10:08:19 +02:00
Rex
2c1345ab27 MDEV-31995 Fix2 allocate memory in mem_root properly.
Lex_ident_sys had no new operator and was used incorrectly in
save_item_list_names(), so leaked memory.
2023-11-18 10:05:54 +11:00
Marko Mäkelä
44b9e41694 Merge 10.5 into 10.6 2023-11-17 13:07:35 +02:00
Rex
8b509a5d64 Merge 10.4 into 10.5 2023-11-16 06:43:24 +12:00
Oleksandr Byelkin
34272bd6a5 Merge branch '11.2' into 11.3 2023-11-14 18:33:03 +01:00
Oleksandr Byelkin
0427c4739e Merge tag '11.1' into 11.2
MariaDB 11.1.3 release
2023-11-14 18:28:37 +01:00
Alexander Barkov
b0379ea4b3 Cleanup: Adding "const" to the member Spvar_definition::m_column_type_ref
and to related methods and their parameters:
- The return value of Spvar_definition::m_column_type_ref()
- The parameter of Spvar_definition::set_column_type_ref()
- The method Qualified_column_ident::resolve_type_ref()
- The parameter of LEX::sp_variable_declarations_column_type_finalize()
2023-11-10 12:45:55 +04:00
Oleksandr Byelkin
0f5613a25f Merge branch '11.0' into 11.1 2023-11-08 18:03:08 +01:00
Oleksandr Byelkin
04d9a46c41 Merge branch '10.6' into 10.10 2023-11-08 16:23:30 +01:00
Oleksandr Byelkin
b83c379420 Merge branch '10.5' into 10.6 2023-11-08 15:57:05 +01:00
Oleksandr Byelkin
6cfd2ba397 Merge branch '10.4' into 10.5 2023-11-08 12:59:00 +01:00
Alexander Barkov
2b6d241ee4 MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE
The crash happened with an indexed virtual column whose
value is evaluated using a function that has a different meaning
in sql_mode='' vs sql_mode=ORACLE:

- DECODE()
- LTRIM()
- RTRIM()
- LPAD()
- RPAD()
- REPLACE()
- SUBSTR()

For example:

CREATE TABLE t1 (
  b VARCHAR(1),
  g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,
  KEY g(g)
);

So far we had replacement XXX_ORACLE() functions for all mentioned function,
e.g. SUBSTR_ORACLE() for SUBSTR(). So it was possible to correctly re-parse
SUBSTR_ORACLE() even in sql_mode=''.

But it was not possible to re-parse the MariaDB version of SUBSTR()
after switching to sql_mode=ORACLE. It was erroneously mis-interpreted
as SUBSTR_ORACLE().

As a result, this combination worked fine:

SET sql_mode=ORACLE;
CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...;
INSERT ...
FLUSH TABLES;
SET sql_mode='';
INSERT ...

But the other way around it crashed:

SET sql_mode='';
CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...;
INSERT ...
FLUSH TABLES;
SET sql_mode=ORACLE;
INSERT ...

At CREATE time, SUBSTR was instantiated as Item_func_substr and printed
in the FRM file as substr(). At re-open time with sql_mode=ORACLE, "substr()"
was erroneously instantiated as Item_func_substr_oracle.

Fix:

The fix proposes a symmetric solution. It provides a way to re-parse reliably
all sql_mode dependent functions to their original CREATE TABLE time meaning,
no matter what the open-time sql_mode is.

We take advantage of the same idea we previously used to resolve sql_mode
dependent data types.

Now all sql_mode dependent functions are printed by SHOW using a schema
qualifier when the current sql_mode differs from the function sql_mode:

SET sql_mode='';
CREATE TABLE t1 ... SUBSTR(a,b,c) ..;
SET sql_mode=ORACLE;
SHOW CREATE TABLE t1;   ->   mariadb_schema.substr(a,b,c)

SET sql_mode=ORACLE;
CREATE TABLE t2 ... SUBSTR(a,b,c) ..;
SET sql_mode='';
SHOW CREATE TABLE t1;   ->   oracle_schema.substr(a,b,c)

Old replacement names like substr_oracle() are still understood for
backward compatibility and used in FRM files (for downgrade compatibility),
but they are not printed by SHOW any more.
2023-11-08 15:01:20 +04:00
Rex
eb8053b377 MDEV-31995 Bogus error executing PS for query using CTE with renaming of columns
This commit addresses column naming issues with CTEs in the use of prepared
statements and stored procedures. Usage of either prepared statements or
procedures with Common Table Expressions and column renaming may be affected.

There are three related but different issues addressed here.

1) First execution issue. Consider the following

prepare s from "with cte (col1, col2) as (select a as c1, b as c2 from t
order by c1) select col1, col2 from cte";
execute s;

After parsing, items in the select are named (c1,c2), order by (and group by)
resolution is performed, then item names are set to (col1, col2).
When the statement is executed, context analysis is again performed, but
resolution of elements in the order by statement will not be able to find c1,
because it was renamed to col1 and remains this way.

The solution is to save the names of these items during context resolution
before they have been renamed. We can then reset item names back to those after
parsing so first execution can resolve items referred to in order and group by
clauses.

2) Second Execution Issue

When the derived table contains more than one select 'unioned' together we could
reasonably think that dealing with only items in the first select (which
determines names in the resultant table) would be sufficient.  This can lead to
a different problem.  Consider

prepare st from "with cte (c1,c2) as
  (select a as col1, sum(b) as col2 from t1 where a > 0 group by col1
    union select a as col3, sum(b) as col4 from t2 where b > 2 group by col3)
  select * from cte where c1=1";

When the optimizer (only run during the first execution) pushes the outside
condition "c1=1" into every select in the derived table union, it renames the
items to make the condition valid.  In this example, this leaves the first item
in the second select named 'c1'.  The second execution will now fail 'group by'
resolution.

Again, the solution is to save the names during context analysis, resetting
before subsequent resolution, but making sure that we save/reset the item
names in all the selects in this union.

3) Memory Leak

During parsing Item::set_name() is used to allocate memory in the statement
arena.  We cannot use this call during statement execution as this represents
a memory leak.  We directly set the item list names to those in the column list
of this CTE (also allocated during parsing).

Approved by Igor Babaev <igor@mariadb.com>
2023-10-30 16:47:18 +12:00
Brandon Nesterenko
0c1bf5e247 MDEV-27247: Add keywords "SQL_BEFORE_GTIDS" and "SQL_AFTER_GTIDS" for START SLAVE UNTIL
New Feature:
============
This patch extends the START SLAVE UNTIL command with options
SQL_BEFORE_GTIDS and SQL_AFTER_GTIDS to allow user control of
whether the replica stops before or after a provided GTID state. Its
syntax is:

START SLAVE UNTIL (SQL_BEFORE_GTIDS|SQL_AFTER_GTIDS)=”<gtid_list>”

When providing SQL_BEFORE_GTIDS=”<gtid_list>”, for each domain
specified in the gtid_list, the replica will execute transactions up
to the GTID found, and immediately stop processing events in that
domain (without executing the transaction of the specified GTID).
Once all domains have stopped, the replica will stop. Events
originating from domains that are not specified in the list are not
replicated.

START SLAVE UNTIL SQL_AFTER_GTIDS=”<gtid_list>” is an alias to the
default behavior of START SLAVE UNTIL master_gtid_pos=”<gtid_list>”.
That is, the replica will only execute transactions originating from
domain ids provided in the list, and will stop once all transactions
provided in the UNTIL list have all been executed.

Example:
=========
If a primary server has a binary log consisting of the following GTIDs:

0-1-1
1-1-1
0-1-2
1-1-2
0-1-3
1-1-3

If a fresh replica (i.e. one with an empty GTID position,
@@gtid_slave_pos='') is started with SQL_BEFORE_GTIDS, i.e.

START SLAVE UNTIL SQL_BEFORE_GTIDS=”1-1-2”

The resulting gtid_slave_pos of the replica will be “1-1-1”.
This is because the replica will execute only events from domain 1
until it sees the transaction with sequence number 2, and
immediately stop without executing it.

If the replica is started with SQL_AFTER_GTIDS, i.e.

START SLAVE UNTIL SQL_AFTER_GTIDS=”1-1-2”

then the resulting gtid_slave_pos of the replica will be “1-1-2”.
This is because it will only execute events from domain 1 until it
has executed the provided GTID.

Reviewed By:
============
Kristian Nielson <knielsen@knielsen-hq.org>
2023-10-23 06:40:05 -06:00
Alexander Barkov
534a2bf1c6 MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO
An "ITERATE innerLoop" did not work properly inside
a WHILE loop, which itself is inside an outer FOR loop:

outerLoop:
  FOR
   ...
   innerLoop:
    WHILE
      ...
      ITERATE innerLoop;
      ...
    END WHILE;
    ...
  END FOR;

It erroneously generated an integer increment code for the outer FOR loop.
There were two problems:
1. "ITERATE innerLoop" worked like "ITERATE outerLoop"
2. It was always integer increment, even in case of FOR cursor loops.

Background:
- A FOR loop automatically creates a dedicated sp_pcontext stack entry,
  to put the iteration and bound variables on it.

- Other loop types (LOOP, WHILE, REPEAT), do not generate a dedicated
  slack entry.

  The old code erroneously assumed that sp_pcontext::m_for_loop
  either describes the most inner loop (in case the inner loop is FOR),
  or is empty (in case the inner loop is not FOR).

  But in fact, sp_pcontext::m_for_loop is never empty inside a FOR loop:
  it describes the closest FOR loop, even if this FOR loop has nested
  non-FOR loops inside.

  So when we're near the ITERATE statement in the above script,
  sp_pcontext::m_for_loop is not empty - it stores information about
  the FOR loop labeled as "outrLoop:".

Fix:
- Adding a new member sp_pcontext::Lex_for_loop::m_start_label,
  to remember the explicit or the auto-generated label correspoding
  to the start of the FOR body. It's used during generation
  of "ITERATE loop_label" code to check if "loop_label" belongs
  to the current FOR loop pointed by sp_pcontext::m_for_loop,
  or belongs to a non-FOR nested loop.

- Adding LEX methods sp_for_loop_intrange_iterate() and
  sp_for_loop_cursor_iterate() to reuse the code between
  methods handling:
  * ITERATE
  * END FOR

- Adding a test for Lex_for_loop::is_for_loop_cursor()
  and generate a code either a cursor fetch, or for an integer increment.
  Before this change, it always erroneously generated an integer increment
  version.

- Cleanup: Initialize Lex_for_loop_st::m_cursor_offset inside
  Lex_for_loop_st::init(), to avoid not initialized members.

- Cleanup: Removing a redundant method:
    Lex_for_loop_st::init(const Lex_for_loop_st &other)
  Using Lex_for_loop_st::operator(const Lex_for_loop_st &other) instead.
2023-10-04 16:06:59 +04:00
Igor Babaev
4e2594768d MDEV-32259 Test from win.test fails with statement memory protection
The function setup_windows() called at the prepare phase of processing a
select builds a list of all window specifications used in the select. This list
is built on the statement memory and it must be done only once.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-09-27 07:48:01 -07:00
Igor Babaev
47f0135d7a MDEV-32245 Test from subselect.test fails with statement memory protection
With this patch st_select_lex::ref_pointer_array is never re-allocated.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-09-26 08:55:34 -07:00
Nikita Malyavin
28b4037242 Merge branch '11.2' into 11.3 2023-09-21 14:15:04 +04:00
Alexander Barkov
d75ef02ac2 MDEV-32220 sql_yacc.yy: unify the drop_routine rule
- Removing two copies of the drop_routine.
  Adding a shared and much simplified version.

- Removing LEX metods:
      bool stmt_drop_function(const DDL_options_st &options,
                              const Lex_ident_sys_st &db,
                              const Lex_ident_sys_st &name);

      bool stmt_drop_function(const DDL_options_st &options,
                              const Lex_ident_sys_st &name);

      bool stmt_drop_procedure(const DDL_options_st &options,
                               sp_name *name);

  The code inside the methods was very similar.
  Adding one method instead:

      bool stmt_drop_routine(const Sp_handler *sph,
                          const DDL_options_st &options,
                          const Lex_ident_sys_st &db,
                          const Lex_ident_sys_st &name);

- Adding a new virtual method Sp_handler:sqlcom_drop().
  It helped to unify the code inside the new stmt_drop_routine().
2023-09-21 08:58:21 +04:00
Alexander Barkov
f5aae71661 MDEV-31606 Refactor check_db_name() to get a const argument
Problem:
Under terms of MDEV-27490, we'll update Unicode version used
to compare identifiers to 14.0.0. Unlike in the old Unicode version,
in the new version a string can grow during lower-case. We cannot
perform check_db_name() inplace any more.

Change summary:

- Allocate memory to store lower-cased identifiers in memory root

- Removing check_db_name() performing both in-place lower-casing and validation
  at the same time. Splitting it into two separate stages:
  * creating a memory-root lower-cased copy of an identifier
    (using new MEM_ROOT functions and Query_arena wrapper methods)
  * performing validation on a constant string
    (using Lex_ident_fs methods)

Implementation details:

- Adding a mysys helper function to allocate lower-cased strings on MEM_ROOT:

    lex_string_casedn_root()

  and a Query_arena wrappers for it:

    make_ident_casedn()
    make_ident_opt_casedn()

- Adding a Query_arena method to perform both MEM_ROOT lower-casing and
  database name validation at the same time:

    to_ident_db_internal_with_error()

  This method is very close to the old (pre-11.3) check_db_name(),
  but performs lower-casing to a newly allocated MEM_ROOT
  memory (instead of performing lower-casing the original string in-place).

- Adding a Table_ident method which additionally handles derived table names:

    to_ident_db_internal_with_error()

- Removing the old check_db_name()
2023-09-13 11:04:27 +04:00
Alexander Barkov
495c32d9ad MDEV-31972 Change parameter of make_sp_name*() from LEX_CSTRING to Lex_ident_sys_st
Changing LEX_CSTRING* parameters of LEX::make_sp_name() to Lex_ident_sys_st.

This makes the code clear because a value of Lex_ident_sys_st has
some guaranteed additional constraints over a base LEX_CSTRING:

- Its LEX_CSTRING::str is not NULL (sql_yacc.yy would abort otherwise)
- Its LEX_CSTRING::str is 0-terminated
- Its a valid utf8 string
- The string pointed by LEX_CSTRING::str was created on THD::mem_root

Also changing "pass by pointer" to "pass by reference",
as these parameters can never be NULL - they are Bison stack variables.
2023-08-21 10:09:45 +04:00
Sergei Golubchik
18ddde4826 Merge branch '11.1' into 11.2 2023-08-18 00:59:16 +02:00
Nikita Malyavin
500787c72a Add const to alloc-related thd methods
Also update abi declarations. The abi itself is unchanged, since const
doesn't affect C-style exported name.
2023-08-15 10:16:13 +02:00
Oleksandr Byelkin
f5fae75652 Merge branch '11.0' into 11.1 2023-08-09 08:25:14 +02:00
Oleksandr Byelkin
ced243a099 Merge branch '10.9' into 10.10 2023-08-05 20:34:09 +02:00
Oleksandr Byelkin
34a8e78581 Merge branch '10.6' into 10.9 2023-08-04 08:01:06 +02:00
Sergei Golubchik
98de11723c cleanup: extern -> static
in particular, this fixes a compiler warning:
sql/sql_lex.h:406:19: warning: ‘sp_data_access_name’ defined but not used [-Wunused-variable]
2023-08-02 13:29:48 +02:00
Oleksandr Byelkin
6bf8483cac Merge branch '10.5' into 10.6 2023-08-01 15:08:52 +02:00
Marko Mäkelä
e81fa34502 Merge 11.1 into 11.2 2023-07-26 15:49:24 +03:00
Marko Mäkelä
c6ac1e39b6 Merge 11.0 into 11.1 2023-07-26 15:13:43 +03:00
Marko Mäkelä
b1b47264d2 Merge 10.9 into 10.10 2023-07-26 14:17:36 +03:00
Dmitry Shulga
1ee1979ed6 MDEV-5816: Stored programs: validation of stored program statements
This patch is the second part of implementation for cursor's statement
re-parsing. The patch does the following changes:
  - on re-parsing a failed SP instruction that does need to get access
    to LEX a new lex is instantiated for every SP instruction except
    cursor relating SP instructions.
  - items created on re-parsing a cursor relating statement are moved
    to the free_list of sp_lex_cursor.
2023-07-20 17:46:45 +07:00
Dmitry Shulga
465c81b323 MDEV-5816: Stored programs: validation of stored program statements
Added re-parsing of failed statements inside a stored routine.

General idea of the patch is to install an instance of the class
Reprepare_observer before executing a next SP instruction and
re-parse a statement of this SP instruction in case of
its execution failure.

To implement the described approach the class sp_lex_keeper
has been extended with the method validate_lex_and_exec_core()
that is just a wrapper around the method reset_lex_and_exec_core()
with additional setting/resetting an instance of the class
Reprepare_observer on each iteration of SP instruction
execution.

If reset_lex_and_exec_core() returns error and an instance
of the class Reprepare_observer is installed before running
a SP instruction then a number of attempts to re-run the SP
instruction is checked against a max. limit and in case it doesn't
reach the limit a statement for the failed SP instruction is re-parsed.

Re-parsing of a statement for the failed SP instruction is implemented
by the new method sp_le_inst::parse_expr() that prepends
a SP instruction's statement with the clause 'SELECT' and parse it.
Own SP instruction MEM_ROOT and a separate free_list is used for
parsing of a SP statement. On successful re-parsing of SP instruction's
statement the virtual methods adjust_sql_command() and
on_after_expr_parsing() of the class sp_lex_instr is called
to update the SP instruction state with a new data created
on parsing the statement.

Few words about reason for prepending a SP instruction's statement
with the clause 'SELECT' - this is required step to produce a valid
SQL statement, since for some SP instructions the instructions statement
is not a valid SQL statement. Wrapping such text into 'SELECT ( )'
produces a correct operator from SQL syntax point of view.
2023-07-20 17:46:45 +07:00