1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-13 13:47:59 +03:00
Commit Graph

79 Commits

Author SHA1 Message Date
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
633417308f MDEV-37312 ASAN errors or assertion failure upon attempt to UPDATE FOR PORTION violating long unique under READ COMMITTED
in case of a long unique conflict ha_write_row() used delete_row()
to remove the newly inserted row, and it used rnd_pos() to position
the cursor before deletion. This rnd_pos() was freeing and reallocating
blobs in record[0]. So when the code for FOR PORTION OF did
  store_record(record[2]);
  ha_write_row()
  restore_record(record[2]);
it ended up with blob pointers to a freed memory.

Let's use lookup_handler for deletion.
2025-07-26 10:54:28 +02:00
Sergei Golubchik
fb2f324f85 MDEV-37310 Non-debug failing assertion node->pcur->rel_pos == BTR_PCUR_ON upon violating long unique under READ-COMMITTED
let's disallow UPDATE IGNORE in READ COMMITTED with the table
has UNIQUE constraint that is USING HASH or is WITHOUT OVERLAPS

This rarely-used combination should not block a release, with be
fixed in MDEV-37233
2025-07-25 12:28:30 +02:00
Sergei Golubchik
cb7978a12d MDEV-36720 Possible memory leak on updating table with index without overlaps
when closing a lookup_handler, don't forget to close it in PSI too
2025-07-17 09:18:17 +02:00
Sergei Golubchik
9703c90712 MDEV-37199 UNIQUE KEY USING HASH accepting duplicate records
Server-level UNIQUE constraints (namely, WITHOUT OVERLAPS and USING HASH)
only worked with InnoDB in REPEATABLE READ isolation mode, when the
constraint was checked first and then the row was inserted or updated.
Gap locks prevented race conditions when a concurrent connection
could've also checked the constraint and inserted/updated a row
at the same time.

In READ COMMITTED there are no gap locks. To avoid race conditions,
we now check the constraint *after* the row operation. This is
enabled by the HA_CHECK_UNIQUE_AFTER_WRITE table flag that InnoDB
sets in the READ COMMITTED transactions.

Checking the constraint after the row operation is more complex.
First, the constraint will see the current (inserted/updated) row,
and needs to skip it. Second, IGNORE operations become tricky,
as we need to revert the insert/update and continue statement execution.

write_row() (INSERT IGNORE) is reverted with delete_row(). Conveniently
it deletes the current row, that is, the last inserted row.

update_row(a,b) (UPDATE IGNORE) is reverted with a reversed update,
update_row(b,a). Conveniently, it updates the current row too.

Except in InnoDB when the PK is updated - in this case InnoDB internally
performs delete+insert, but does not move the cursor, so the "current"
row is the deleted one and the reverse update doesn't work.
This combination now throws an "unsupported" error and will
be fixed in MDEV-37233
2025-07-16 13:02:44 +02:00
Sergei Golubchik
f1a7693bc0 Merge branch '10.11' into 11.4 2025-01-14 23:45:41 +01:00
Marko Mäkelä
420d9eb27f Merge 10.6 into 10.11 2025-01-08 12:51:26 +02:00
Monty
88d9348dfc Remove dates from all rdiff files 2025-01-05 16:40:11 +02:00
Oleksandr Byelkin
99b370e023 Merge branch '11.2' into 11.4 2024-05-21 19:38:51 +02:00
Marko Mäkelä
683fbced6b Merge 11.0 into 11.1 2024-03-28 12:15:36 +02:00
Marko Mäkelä
d73baa402a Merge 10.11 into 11.0 2024-02-20 12:02:01 +02:00
Nikita Malyavin
22e41dae88 MDEV-32501 KEY_PERIOD_USAGE reveals information to unprivileged user
Restrict access to KEY_PERIOD_USAGE: show the constraint record iff any
non-select privilege on any table column is granted.

Also drop the unprivileged user in the end of test and add merge anchor.
2024-02-12 22:26:06 +01:00
Nikita Malyavin
5c2f8c017c MDEV-32503 Queries from I_S.KEY_PERIOD_USAGE do not obey case-sensitivity
Set the correct values for idx_field1, idx_field2 (i.e. db and table name
fields) of ST_SCHEMA_TABLE instance.
2024-02-12 22:26:06 +01:00
Nikita Malyavin
d4b5f7a503 MDEV-32205 crash in get_schema_key_period_usage_record without InnoDB
Move table open result processing to the caller

* st_schema_table::process_table doesn't have to check whether the table
was opened successfully
* It also doesn't have to check for a thd error and convert it to a warning
* This simplifies adding new tables into information_schema
* A callback still can output some info to a user in case of error. In
order to do this, I_S_EXTENDED_ERROR_HANDLING should be specified in
i_s_requested_object.
2024-02-12 22:26:06 +01:00
Nikita Malyavin
4246c0fa01 MDEV-22597 Add views for periods in information_schema
Two new information_schema views are added:
* PERIOD table -- columns TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
  PERIOD_NAME, START_COLUMN_NAME, END_COLUMN_NAME.
* KEY_PERIOD_USAGE -- works similar to KEY_COLUMN_USAGE, but for periods.
  Columns CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME,
  TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, PERIOD_NAME

Two new columns are added to the COLUMNS view:
 IS_SYSTEM_TIME_PERIOD_START, IS_SYSTEM_TIME_PERIOD_END - contain YES/NO.
2024-02-12 22:26:06 +01:00
Marko Mäkelä
86c2c89743 Merge 10.6 into 10.11 2024-02-08 15:04:46 +02:00
Marko Mäkelä
91a2192bf2 Merge 10.5 into 10.6 2024-02-07 13:51:03 +02:00
Nikita Malyavin
68c1fbfc17 MDEV-25370 Update for portion changes autoincrement key in bi-temp table
According to the standard, the autoincrement column (i.e. *identity
column*) should be advanced each insert implicitly made by
UPDATE/DELETE ... FOR PORTION.

This is very unconvenient use in several notable cases. Concider a
WITHOUT OVERLAPS key with an autoinc column:
id int auto_increment, unique(id, p without overlaps)

An update or delete with FOR PORTION creates a sense that id will remain
unchanged in such case.

The standard's IDENTITY reminds MariaDB's AUTO_INCREMENT, however
the generation rules differ in many ways. For example, there's also a
notion autoincrement index, which is bound to the autoincrement field.

We will define our own generation rule for the PORTION OF operations
involving AUTO_INCREMENT:
* If an autoincrement index contains WITHOUT OVERLAPS specification, then
a new value should not be generated, otherwise it should.

Apart from WITHOUT OVERLAPS there is also another notable case, referred
by the reporter - a unique key that has an autoincrement column and a field
from the period specification:
  id int auto_increment, unique(id, s), period for p(s, e)

for this case, no exception is made, and the autoincrementing rules will be
proceeded accordung to the standard (i.e. the value will be advanced on
implicit inserts).
2024-01-31 16:03:38 +01:00
Sergei Golubchik
cbabb95915 Merge branch '11.0' into 11.1 2023-06-05 20:15:15 +02:00
Sergei Petrunia
c7fe8e51de Merge 10.11 into 11.0 2023-04-17 16:50:01 +03:00
Marko Mäkelä
a009280e60 Merge 10.9 into 10.10 2023-04-14 12:24:14 +03:00
Marko Mäkelä
5bada1246d Merge 10.5 into 10.6 2023-04-11 16:15:19 +03:00
Alexander Barkov
fb72dfbf7f MDEV-30415 MDEV-30415 PERIOD false positive overlap wtih utf8mb4_unicode_nopad_ci
The problem was earlier fixed by the patch for MDEV-30034.
Adding MTR tests only.
2023-04-06 09:45:05 +04:00
Igor Babaev
3a9358a410 MDEV-28883 Re-design the upper level of handling UPDATE and DELETE statements
This patch introduces a new way of handling UPDATE and DELETE commands at
the top level after the parsing phase. This new way of processing update
and delete statements can be seen in the implementation of the  prepare()
and execute() methods from the new Sql_cmd_dml class. This class derived
from the Sql_cmd class can be considered as an interface class for processing
such commands as SELECT, INSERT, UPDATE, DELETE and other comands
manipulating data in tables.
With this patch processing of update and delete statements after parsing
proceeds by the following schema:
  - precheck of the access rights is performed for the used tables
  - the used tables are opened
  - context analysis phase is performed for the statement
  - the used tables are locked
  - the statement is optimized and executed
  - clean-up is performed for the statement
The implementation of the method Sql_cmd_dml::execute() adheres this schema.
The virtual functions of the class Sql_cmd_dml used for precheck of the
access rights, context analysis, optimization and execution allow to adjust
this schema for processing data manipulation statements of any types.

This schema of processing data manipulation statements is taken from the
current MySQL code. Moreover the definition the class Sql_cmd_dml introduced
in this patch is almost a full replica of such class in the existing MySQL.
However the implementation of the derived classes for update and delete
statements is quite different. This implementation employs the JOIN class
for all kinds of update and delete statements. It allows to perform main
bulk of context analysis actions by the function JOIN::prepare(). This
guarantees that characteristics and properties of the statement tree
discovered for optimization phase when doing context analysis are the same
for single-table and multi-table updates and deletes.

With this patch the following functions are gone:
  mysql_prepare_update(), mysql_multi_update_prepare(),
  mysql_update(), mysql_multi_update(),
  mysql_prepare_delete(), mysql_multi_delete_prepare(), mysql_delete().
The code within these functions have been used as much as possible though.
The functions mysql_test_update() and mysql_test_delete() are also not
needed anymore. The method Sql_cmd_dml::prepare() serves processing
  - update/delete statement
  - PREPARE stmt FROM "<update/delete statement>"
  - EXECUTE stmt when stmt is prepared from update/delete statement.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-03-15 17:35:22 -07:00
Monty
b74d2623eb Removed diff dates from rdiff files 2023-02-03 11:57:45 +03:00
Marko Mäkelä
3ff4eb07ed Merge 10.9 into 10.10 2022-12-07 09:49:38 +02:00
Marko Mäkelä
e55397a46d Merge 10.5 into 10.6 2022-12-05 18:04:23 +02:00
Jan Lindström
4eb8e51c26 Merge 10.4 into 10.5 2022-11-30 13:10:52 +02:00
Marko Mäkelä
5e996fbad9 Merge 10.9 into 10.10 2022-09-21 10:59:56 +03:00
Marko Mäkelä
44fd2c4b24 Merge 10.5 into 10.6 2022-09-20 16:53:20 +03:00
Alexander Barkov
fe844c16b6 Merge remote-tracking branch 'origin/10.4' into 10.5 2022-09-14 16:24:51 +04:00
Marko Mäkelä
18795f5512 Merge 10.3 into 10.4 2022-09-13 16:36:38 +03:00
Marko Mäkelä
e71aca8200 Merge 10.9 into 10.10 2022-08-30 13:33:02 +03:00
Marko Mäkelä
f410974f0f Merge 10.5 into 10.6 2022-08-30 13:01:16 +03:00
Marko Mäkelä
29fa9bcee0 Merge 10.4 into 10.5 2022-08-30 12:29:04 +03:00
tmokmss
827b049e1e MDEV-18873 Server crashes in Compare_identifiers::operator or in my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
empty identifier specified as `` ends up with a NULL LEX_CSTRING::str in lexer.
This is not considered correct in upper layers, for example in Compare_identifiers::operator().
Empty column name is usually avoided by a check_column_name() call while parsing,
and period name matches the column name completely.
Hence, this fix uses the mentioned call for verification, too.
2022-08-26 12:40:58 +03:00
Sergei Golubchik
45e0373a78 MDEV-28632 Change default of explicit_defaults_for_timestamp to ON 2022-08-10 15:03:22 +02:00
Oleksandr Byelkin
10aa576483 Merge branch '10.5' into 10.6 2020-11-14 20:05:35 +01:00
Marko Mäkelä
d7a5824899 Merge 10.4 into 10.5 2020-11-13 21:54:21 +02:00
Nayuta Yanagisawa
b13fe8e51b MDEV-18842: Unfortunate error message when the same column is used for application period start and end
An application-time period must be composed of two different columns.
We added a check that ensures that the above condition is met.
2020-11-04 12:33:13 +03:00
Marko Mäkelä
09a1f0075a Merge 10.5 into 10.6 2020-11-02 12:49:19 +02:00
Nikita Malyavin
e618f7e9f6 MDEV-22506 Malformed error message for ER_KEY_CONTAINS_PERIOD_FIELDS
Though this is an error message task, the problem was deep in the
`mysql_prepare_create_table` implementation. The problem is described as
follows:

1. `append_system_key_parts` was called before
`mysql_prepare_create_table`, though key name generation was done close to
the latest stage of the latter.
2. We can't move `append_system_key_parts` in the end, because system keys
should be appended before some checks done.
3. If the checks from `append_system_key_parts` are moved to the end of
`mysql_prepare_create_table`, then some other inappropriate errors are
issued. like `ER_DUP_FIELDNAME`.

To have key name specified in error message, name generation should be done
before the checks, which consequenced in more changes.

The final design for key initialization in `mysql_prepare_create_table`
follows. The initialization is done in three phases:
1. Calculate a total number of keys created with respect to keys ignored.
 Allocate KEY* buffer.
2. Generate unique names; calculate a total number of key parts.
 Make early checks. Allocate KEY_PART_INFO* buffer.
3. Initialize key parts, make the rest of the checks.
2020-11-02 14:21:05 +10:00
Nikita Malyavin
a79c6e369e MDEV-22677 UPDATE crashes on partitioned HEAP table WITHOUT OVERLAPS
`ha_heap::clone` was creating a handler by share's handlerton, which is
partition handlerton.

handler's handlerton should be used instead.

Here in particular, HEAP handlerton will be used and it will create ha_heap
handler.
2020-11-02 14:11:43 +10:00
Nikita Malyavin
d9e00770a3 MDEV-22608 ASAN use-after-poison in TABLE::check_period_overlaps
The bug was fixed by MDEV-22599 bugfix, which changed `Field::cmp` call
to `Field::cmp_prefix` in `TABLE::check_period_overlaps`.

The trick is that `Field_bit::cmp` apparently calls `Field_bit::cmp_key`,
which condiders an argument an actual pointer to data, which isn't correct
for `Field_bit`, since it stores data by `bit_ptr`. which is in the
beginning of the record, and using `ptr` is incorrect (we use it through
`ptr_in_record` call)
2020-11-02 14:11:43 +10:00
Nikita Malyavin
afca976885 MDEV-22639 Assertion failed in ha_check_overlaps upon multi-table update
After Sergei's cleanup this assertion is not actual anymore -- we can't
predict if the handler was used for lookup, especially in multi-update
scenario.

`position(old_data)` is made earlier in `ha_check_overlaps`, therefore it
is guaranteed that we compare right refs.
2020-11-02 14:11:43 +10:00
Nikita Malyavin
d543363f25 MDEV-22714 Assertion failed upon multi-update on table WITHOUT OVERLAPS
The problem here was that ha_check_overlaps internally uses ha_index_read,
which in case of fail overwrites table->status. Even though the handlers
are different, they share a common table, so the value is anyway spoiled.
This is bad, and table->status is badly designed and overweighted by
functionality, but nothing can be done with it, since the code related to
this logic is ancient and it's impossible to extract it with normal effort.

So let's just save and restore the value in ha_update_row before and after
the checks.

Other operations like INSERT and simple UPDATE are not in risk, since they
don't use this table->status approach.
DELETE does not do any unique checks, so it's also safe.
2020-11-02 14:11:42 +10:00
Marko Mäkelä
898521e2dd Merge 10.4 into 10.5 2020-10-30 11:15:30 +02:00
Aleksey Midenkov
27b762e23d MDEV-22805 SIGSEGV in check_fields on UPDATE
Additional case for PS protocol: UPDATE is converted to multi-update
in mysql_multi_update_prepare().
2020-10-29 13:47:50 +03:00
Dmitry Shulga
97b10b7fdc MDEV-22805: SIGSEGV in check_fields on UPDATE
For debug build of MariaDB server running of the following test case
will hit the assert `thd->lex->sql_command == SQLCOM_UPDATE' in the function
check_fields() on attempt to execute the UPDATE statement.

  CREATE TABLE t1 (a INT);
  UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT 1 FROM t1) TO 2 SET a = 1;

Stack trace to the fired assert statement
  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_UPDATE)
listed below:
  mysql_execute_command() ->
    mysql_multi_update_prepare() -->
      Multiupdate_prelocking_strategy::handle_end() -->
        check_fiels()

It's worth to note that this stack trace looks like a multi update
statement is being executed. The fired assert is checked inside the
function check_fields() in case table->has_period() returns the value
true that in turns happens when temporal period specified in the UPDATE
statement. Condition specified in the DEBUG_ASSERT statement returns
the false value since the data member thd->lex->sql_command have the
value SQLCOM_UPDATE_MULTI. So, the main question is why a program control
flow go to the path prescribed for handling MULTI update statement
despite of the fact that the ordinary UPDATE statement being executed.

The answer is a way that SQL grammar rules written.

When the statement
  UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT 1 FROM t1) TO 2 SET a = 1;
being parsed an action for the rule 'table_primary_ident' (part of this action
is listed below to simplify description) is  invoked to handle the table
name 't1' specified in the clause 'SELECT 1 FROM t1'.

table_primary_ident:
  table_ident opt_use_partition opt_for_system_time_clause
  opt_table_alias_clause opt_key_definition
  {
    SELECT_LEX *sel= Select;
    sel->table_join_options= 0;
    if (!($$= Select->add_table_to_list(thd, $1, $4,

This action calls the method st_select_lex::add_table_to_list()
to add the table name 't1' to the list of tables being used by the statement.

Later, an action for the following grammar rule
update_table_list:
  table_ident opt_use_partition for_portion_of_time_clause
  opt_table_alias_clause opt_key_definition
  {
    SELECT_LEX *sel= Select;
    sel->table_join_options= 0;
    if (!($$= Select->add_table_to_list(thd, $1, $4,

is invoked to handle the clause 't1 FOR PORTION OF APPTIME FROM ... TO 2'.
This action also calls the method st_select_lex::add_table_to_list()
to add the table name 't1' to the list of tables being used by the statement.

In result the table name 't1' contained twice in this list.

Presence of duplicate names for the table 't1' in a list of table used by
a statement leads to the fact that the function unique_table() called
from the function mysql_update() returns the value true that forces
implementation of the function mysql_update() to return the value 2 as
a signal to fall through the case boundary of the switch statement placed
in the function mysql_execute_statement() and start handling of the case
for sql_command SQLCOM_UPDATE_MULTI. The compound statement block for the
case SQLCOM_UPDATE_MULTI invokes the function mysql_multi_update_prepare()
that executes the statement
  set thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
and after that calls the method
  Multiupdate_prelocking_strategy::handle_end(). Finally, this method
invokes the check_field() function and assert is fired.

The above analysis shows that update for a table that simultaneously specified
both as a destination table of UPDATE statement and as a table taking part in
subquery is actually treated by MariaDB server as multi-update statement.
Taking into account that multi-update statement for temporal period
table is not supported yet by MariaDB, correct way to fix the bug is to return
the error ER_NOT_SUPPORTED_YET for this case.
2020-10-27 18:55:22 +07:00