From 586f1973ae8e32b0533228ba01a96fe51e2066c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Fri, 12 Dec 2025 08:53:33 +0000 Subject: [PATCH 001/152] MDEV-37098 Fix Spider test failures in network-less environments When running tests in environments without a network interface (e.g. Podman container launched with `--network=none`), Spider was not able to retrieve a hardware address to generate a node ID. This triggered a warning in the server log, causing MTR to fail multiple Spider tests due to unexpected warnings and output result mismatches with: [Warning] mariadbd: Can't get hardware address with error 2 Fix this by logging Spider hardware address errors to server log only by setting it as a NOTE. This does not pollute the client output. When`my_gethwaddr` fails, the code zeroes out the address buffer, resulting in a `spider_unique_id` formatted like `-000000000000-PID-`, which is fully valid and emitting warnings was a bit overkill to begin with. --- storage/spider/spd_table.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index b8857900927..72a6b2ac3b8 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6288,8 +6288,12 @@ int spider_db_init( if (my_gethwaddr((uchar *) addr)) { - my_printf_error(ER_SPIDER_CANT_NUM, ER_SPIDER_CANT_STR1, MYF(ME_WARNING), + my_printf_error(ER_SPIDER_CANT_NUM, ER_SPIDER_CANT_STR1, MYF(ME_NOTE), "get hardware address with error ", errno); + /* + If we can't get the hardware address, we zero it out. + The spider_unique_id will then look like: -000000000000-PID- + */ bzero(addr,6); } spider_unique_id.str = spider_unique_id_buf; From 4dbbd316045397ce2c43106580673454775393d8 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 5 Jan 2026 15:55:51 +0200 Subject: [PATCH 002/152] MDEV-23298 Assertion `table_list->prelocking_placeholder == TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on CREATE OR REPLACE TABLE Fixed by removing wrong assert Review: Sanja Byelkin --- mysql-test/main/create_or_replace.result | 29 ++++++++++++++++++++++++ mysql-test/main/create_or_replace.test | 26 +++++++++++++++++++++ sql/sql_base.cc | 6 ----- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 692c9d3e322..42eae555ab4 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -582,3 +582,32 @@ DROP TABLE IF EXISTS tm, t; # # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_persistent; +# +# MDEV-23298 Assertion `table_list->prelocking_placeholder == +# TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +# CREATE OR REPLACE TABLE +# +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1,t2; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 5758620de71..30c709f53f2 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -532,3 +532,29 @@ DROP TABLE IF EXISTS tm, t; --echo # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_persistent; + +--echo # +--echo # MDEV-23298 Assertion `table_list->prelocking_placeholder == +--echo # TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +--echo # CREATE OR REPLACE TABLE +--echo # + +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +drop table t1,t2; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 00a2fb90c58..79d7d7d3232 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5157,12 +5157,6 @@ static bool check_lock_and_start_stmt(THD *thd, thr_lock_type lock_type; DBUG_ENTER("check_lock_and_start_stmt"); - /* - Prelocking placeholder is not set for TABLE_LIST that - are directly used by TOP level statement. - */ - DBUG_ASSERT(table_list->prelocking_placeholder == TABLE_LIST::PRELOCK_NONE); - /* TL_WRITE_DEFAULT and TL_READ_DEFAULT are supposed to be parser only types of locks so they should be converted to appropriate other types From e309477815ee240c2c7fef559d16d869a5709cfd Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Tue, 7 Jan 2025 16:14:33 -0500 Subject: [PATCH 003/152] MDEV-35765 ST_OVERLAPS wrong result when dim(geom1) <> dim(geom2) Validates that the two geometries passed to ST_OVERLAPS have the same number of dimensions. --- mysql-test/main/mdev-35765.result | 20 +++++++++ mysql-test/main/mdev-35765.test | 14 +++++++ sql/item_geofunc.cc | 68 +++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 mysql-test/main/mdev-35765.result create mode 100644 mysql-test/main/mdev-35765.test diff --git a/mysql-test/main/mdev-35765.result b/mysql-test/main/mdev-35765.result new file mode 100644 index 00000000000..9a3de115b83 --- /dev/null +++ b/mysql-test/main/mdev-35765.result @@ -0,0 +1,20 @@ +# +# MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +# +DROP table if EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' +DROP table if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +ST_OVERLAPS(t1.geom, t2.geom) +0 +DROP TABLE t1, t2; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/mdev-35765.test b/mysql-test/main/mdev-35765.test new file mode 100644 index 00000000000..f9d04cff1f4 --- /dev/null +++ b/mysql-test/main/mdev-35765.test @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +--echo # +DROP table if EXISTS t1; +DROP table if EXISTS t2; +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +DROP TABLE t1, t2; +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index af2b8dfd261..20f13d51000 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1408,6 +1408,38 @@ exit: } +static void handle_sp_crosses_func_case(Gcalc_function &func, + Gcalc_operation_transporter &trn, + Geometry_ptr_with_buffer_and_mbr &g1, + Geometry_ptr_with_buffer_and_mbr &g2, + uint &shape_a, uint &shape_b, + bool &null_value) +{ + func.add_operation(Gcalc_function::op_intersection, 2); + if (func.reserve_op_buffer(3)) + return; + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_intersection, 2); + shape_a= func.get_next_expression_pos(); + if ((null_value= g1.store_shapes(&trn))) + return; + shape_b= func.get_next_expression_pos(); + if ((null_value= g2.store_shapes(&trn))) + return; + if (func.reserve_op_buffer(7)) + return; + func.add_operation(Gcalc_function::op_intersection, 2); + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_difference, 2); + func.repeat_expression(shape_a); + func.repeat_expression(shape_b); + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_difference, 2); + func.repeat_expression(shape_b); + func.repeat_expression(shape_a); +} + + bool Item_func_spatial_precise_rel::val_bool() { DBUG_ENTER("Item_func_spatial_precise_rel::val_int"); @@ -1469,29 +1501,21 @@ bool Item_func_spatial_precise_rel::val_bool() null_value= g1.store_shapes(&trn) || g2.store_shapes(&trn); break; case SP_OVERLAPS_FUNC: + { + // Both geometries must have the same number of dimensions. + uint32 g1_dim, g2_dim; + const char *dummy; + g1.geom->dimension(&g1_dim, &dummy); + g2.geom->dimension(&g2_dim, &dummy); + if (g1_dim != g2_dim) + DBUG_RETURN(0); + handle_sp_crosses_func_case(func, trn, g1, g2, + shape_a, shape_b, null_value); + break; + } case SP_CROSSES_FUNC: - func.add_operation(Gcalc_function::op_intersection, 2); - if (func.reserve_op_buffer(3)) - break; - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_intersection, 2); - shape_a= func.get_next_expression_pos(); - if ((null_value= g1.store_shapes(&trn))) - break; - shape_b= func.get_next_expression_pos(); - if ((null_value= g2.store_shapes(&trn))) - break; - if (func.reserve_op_buffer(7)) - break; - func.add_operation(Gcalc_function::op_intersection, 2); - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_difference, 2); - func.repeat_expression(shape_a); - func.repeat_expression(shape_b); - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_difference, 2); - func.repeat_expression(shape_b); - func.repeat_expression(shape_a); + handle_sp_crosses_func_case(func, trn, g1, g2, + shape_a, shape_b, null_value); break; case SP_TOUCHES_FUNC: if (func.reserve_op_buffer(5)) From 7edf2dc9ddbc4a638915334509a032690941272d Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 6 Jan 2026 20:07:38 +0200 Subject: [PATCH 004/152] Added --with-asan to compile-pentium64-asan-max This was needed to get rid of compilation problems with -Wframe-larger-than=16384 --- BUILD/compile-pentium64-asan-max | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD/compile-pentium64-asan-max b/BUILD/compile-pentium64-asan-max index cedf5254e59..f2ebc146b27 100755 --- a/BUILD/compile-pentium64-asan-max +++ b/BUILD/compile-pentium64-asan-max @@ -23,7 +23,7 @@ path=`dirname $0` # extra_flags="$pentium64_cflags $debug_cflags -lasan -O -g -fsanitize=address -USAFEMALLOC -UFORCE_INIT_OF_VARS -Wno-uninitialized -Wno-maybe-uninitialized -DMYSQL_SERVER_SUFFIX=-asan-max" -extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs $disable_asan_plugins" +extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs $disable_asan_plugins --with-asan=ON" export LDFLAGS="-ldl" . "$path/FINISH.sh" From 9fa3f51f59f5b7a6d84c68a45e6a6579f55847b3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 11 Dec 2025 14:42:40 +0100 Subject: [PATCH 005/152] MDEV-38313 Add WantedBy=sockets.target to systemd socket definations mariadb.socket and others need a Install section to include the WantedBy=sockets.target. This is consistent with other socket definations of systemd. Thanks Mark Bolhuis for the bug report. --- support-files/mariadb-extra.socket.in | 4 +++- support-files/mariadb-extra@.socket.in | 4 +++- support-files/mariadb.socket.in | 3 +++ support-files/mariadb@.socket.in | 3 +++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/support-files/mariadb-extra.socket.in b/support-files/mariadb-extra.socket.in index f268a0ad2a8..a98148dab2f 100644 --- a/support-files/mariadb-extra.socket.in +++ b/support-files/mariadb-extra.socket.in @@ -5,6 +5,9 @@ Description=MariaDB @VERSION@ database server (socket activation extra port) Documentation=man:mariadbd(8) Documentation=https://mariadb.com/kb/en/library/systemd/ +[Install] +WantedBy=sockets.target + [Socket] Service=mariadb.service @@ -17,4 +20,3 @@ FileDescriptorName=extra ListenStream=@mariadb-extra ListenStream=@MYSQL_UNIX_ADDR@-extra - diff --git a/support-files/mariadb-extra@.socket.in b/support-files/mariadb-extra@.socket.in index f33344f2abd..906b2ca57c3 100644 --- a/support-files/mariadb-extra@.socket.in +++ b/support-files/mariadb-extra@.socket.in @@ -5,6 +5,9 @@ Description=MariaDB @VERSION@ database server (socket activation extra port mult Documentation=man:mariadbd(8) Documentation=https://mariadb.com/kb/en/library/systemd/ +[Install] +WantedBy=sockets.target + [Socket] Service=mariadb@%i.service @@ -17,4 +20,3 @@ FileDescriptorName=extra ListenStream=@mariadb-extra-%I ListenStream=@MYSQL_UNIX_ADDR@-extra-%I - diff --git a/support-files/mariadb.socket.in b/support-files/mariadb.socket.in index d99fdee0334..52dfb6b0655 100644 --- a/support-files/mariadb.socket.in +++ b/support-files/mariadb.socket.in @@ -4,6 +4,9 @@ Description=MariaDB @VERSION@ database server (socket activation) Documentation=man:mariadbd(8) Documentation=https://mariadb.com/kb/en/library/systemd/ +[Install] +WantedBy=sockets.target + [Socket] ############################################################################## diff --git a/support-files/mariadb@.socket.in b/support-files/mariadb@.socket.in index 561a44443c9..e3e9a9e5a4a 100644 --- a/support-files/mariadb@.socket.in +++ b/support-files/mariadb@.socket.in @@ -4,6 +4,9 @@ Description=MariaDB @VERSION@ database server (socket activation multi-instance Documentation=man:mariadbd(8) Documentation=https://mariadb.com/kb/en/library/systemd/ +[Install] +WantedBy=sockets.target + [Socket] ############################################################################## From 635a8500ed8d62763ac57c26b2de821f255c84b0 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 5 Jan 2026 14:58:32 +0100 Subject: [PATCH 006/152] MDEV-36888 Assertion `typeid(*copy) == typeid(*this)' in Item_func_or_sum::do_build_clone Problems was in forgotten Item type in two places: clone and finding origin field. The handling added. --- mysql-test/main/view.result | 12 +++++++++++- mysql-test/main/view.test | 11 ++++++++++- sql/item.cc | 1 + sql/item.h | 2 ++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 234b21cc072..0bb6abb2fdf 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -7076,5 +7076,15 @@ ERROR 22007: Truncated incorrect DECIMAL value: '' DROP VIEW v1; DROP TABLE t1, t2; # -# End of 10.6 tests +# MDEV-36888: Assertion `typeid(*copy) == typeid(*this)' in +# Item_func_or_sum::do_build_clone # +CREATE TABLE t (a INT default 1); +INSERT INTO t VALUES (0),(2); +CREATE ALGORITHM=TEMPTABLE VIEW v AS SELECT * FROM t; +EXECUTE IMMEDIATE "SELECT * FROM v WHERE COERCIBILITY(VALUE(a)) > a"; +a +0 +drop view v; +drop table t; +# End of 10.6 tests diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 9a10a80f922..f15f21f34a9 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -6839,5 +6839,14 @@ DROP VIEW v1; DROP TABLE t1, t2; --echo # ---echo # End of 10.6 tests +--echo # MDEV-36888: Assertion `typeid(*copy) == typeid(*this)' in +--echo # Item_func_or_sum::do_build_clone --echo # +CREATE TABLE t (a INT default 1); +INSERT INTO t VALUES (0),(2); +CREATE ALGORITHM=TEMPTABLE VIEW v AS SELECT * FROM t; +EXECUTE IMMEDIATE "SELECT * FROM v WHERE COERCIBILITY(VALUE(a)) > a"; +drop view v; +drop table t; + +--echo # End of 10.6 tests diff --git a/sql/item.cc b/sql/item.cc index 051c13adc3b..eb432a643c9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8026,6 +8026,7 @@ Item *find_producing_item(Item *item, st_select_lex *sel) { DBUG_ASSERT(item->type() == Item::FIELD_ITEM || item->type() == Item::TRIGGER_FIELD_ITEM || + item->type() == Item::INSERT_VALUE_ITEM || (item->type() == Item::REF_ITEM && ((Item_ref *) item)->ref_type() == Item_ref::VIEW_REF)); Item_field *field_item= NULL; diff --git a/sql/item.h b/sql/item.h index b6d48244fcb..cbfaa2dd1c4 100644 --- a/sql/item.h +++ b/sql/item.h @@ -7201,6 +7201,8 @@ public: { return mark_unsupported_function("value()", arg, VCOL_IMPOSSIBLE); } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; From 15e4ae4a91a6bda41a6bb036cb105ba104c731e9 Mon Sep 17 00:00:00 2001 From: nada Date: Wed, 7 Jan 2026 17:13:22 +0100 Subject: [PATCH 007/152] MDEV-37908: Replace KB links with MariaDB Documentation links --- CONTRIBUTING.md | 14 +++++++------- CREDITS | 2 +- Docs/mysql.info | 11 ----------- man/aria_chk.1 | 2 +- man/aria_dump_log.1 | 2 +- man/aria_ftdump.1 | 2 +- man/aria_pack.1 | 2 +- man/aria_read_log.1 | 2 +- man/aria_s3_copy.1 | 2 +- man/comp_err.1 | 2 +- man/galera_recovery.1 | 2 +- man/innochecksum.1 | 2 +- man/mariabackup.1 | 2 +- man/mariadb-conv.1 | 2 +- man/mariadb-service-convert.1 | 2 +- man/mbstream.1 | 2 +- man/msql2mysql.1 | 2 +- man/my_print_defaults.1 | 2 +- man/my_safe_process.1 | 2 +- man/myisam_ftdump.1 | 2 +- man/myisamchk.1 | 2 +- man/myisamlog.1 | 2 +- man/myisampack.1 | 2 +- man/mysql-stress-test.pl.1 | 2 +- man/mysql-test-run.pl.1 | 2 +- man/mysql.1 | 2 +- man/mysql.server.1 | 2 +- man/mysql_client_test.1 | 2 +- man/mysql_config.1 | 2 +- man/mysql_convert_table_format.1 | 2 +- man/mysql_find_rows.1 | 2 +- man/mysql_fix_extensions.1 | 2 +- man/mysql_install_db.1 | 2 +- man/mysql_plugin.1 | 2 +- man/mysql_secure_installation.1 | 2 +- man/mysql_setpermission.1 | 2 +- man/mysql_tzinfo_to_sql.1 | 2 +- man/mysql_upgrade.1 | 2 +- man/mysql_waitpid.1 | 2 +- man/mysqlaccess.1 | 2 +- man/mysqladmin.1 | 2 +- man/mysqlbinlog.1 | 2 +- man/mysqlcheck.1 | 7 ++++++- man/mysqld.8 | 4 ++-- man/mysqld_multi.1 | 2 +- man/mysqld_safe.1 | 2 +- man/mysqld_safe_helper.1 | 2 +- man/mysqldump.1 | 2 +- man/mysqldumpslow.1 | 2 +- man/mysqlhotcopy.1 | 2 +- man/mysqlimport.1 | 2 +- man/mysqlshow.1 | 2 +- man/mysqlslap.1 | 2 +- man/mysqltest.1 | 2 +- man/mytop.1 | 2 +- man/perror.1 | 2 +- man/replace.1 | 2 +- man/resolve_stack_dump.1 | 2 +- man/resolveip.1 | 2 +- man/wsrep_sst_backup.1 | 2 +- man/wsrep_sst_common.1 | 2 +- man/wsrep_sst_mariabackup.1 | 2 +- man/wsrep_sst_mysqldump.1 | 2 +- man/wsrep_sst_rsync.1 | 2 +- man/wsrep_sst_rsync_wan.1 | 2 +- 65 files changed, 76 insertions(+), 82 deletions(-) delete mode 100644 Docs/mysql.info diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 37899f37958..918670fd147 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,15 +5,15 @@ MariaDB Server has a vibrant community contributing in a wide range of areas. Th ### Engage online with other community members --- - [MariaDB on Zulip](https://mariadb.zulipchat.com/) -- [maria-developers mailing list](http://launchpad.net/~maria-developers) -- [maria-discuss mailing list](http://launchpad.net/~maria-discuss) -- [maria-docs mailing list](http://launchpad.net/~maria-docs) -- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter and Facebook. See the [social media page](https://mariadb.com/kb/en/mariadb/social-media/). +- [maria-developers mailing list](https://lists.mariadb.org/postorius/lists/developers.lists.mariadb.org/) +- [maria-discuss mailing list](https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/) +- [maria-docs mailing list](https://lists.mariadb.org/postorius/lists/docs.lists.mariadb.org/) +- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter and Facebook. See the [social media page](https://mariadb.com/docs/general-resources/community/joining-the-community). ### Help document MariaDB ---- -- Contribute towards [documenting MariaDB Server](https://mariadb.com/kb/en/meta/writing-editing-library-articles/) and its ecosystem by adding new content or improving existing content. -- [Translate](https://mariadb.com/kb/en/meta/translating-library-articles/) existing documentation. +- Contribute towards [documenting MariaDB Server](https://mariadb.com/docs/general-resources/about/readme/contributing-documentation) and its ecosystem by adding new content or improving existing content. +- [Translate](https://mariadb.com/docs/general-resources/about/readme/contributing-documentation) existing documentation. ### Help debug and develop MariaDB ----- @@ -43,4 +43,4 @@ New contributors can ask questions any time, but we will provide immediate feedb ### Additional resources ---- - [MariaDB Foundation ](https://mariadb.org/) - - [Knowledge Base](https://mariadb.com/kb/en/) + - [MariaDB Documentation](https://mariadb.com/docs/) diff --git a/CREDITS b/CREDITS index 42f1697f992..9363b3d6858 100644 --- a/CREDITS +++ b/CREDITS @@ -66,7 +66,7 @@ following services to the MariaDB community: - Bug fixing in MariaDB (for bugs that affects a large part of the community) - Building the official MariaDB binaries - Maintaining https://mariadb.org -- Documenting MariaDB in the MariaDB Knowledge Base https://mariadb.com/kb +- Documenting MariaDB in the MariaDB Documentation https://mariadb.com/kb To be able to do the above we need help from corporations and individuals! diff --git a/Docs/mysql.info b/Docs/mysql.info deleted file mode 100644 index 02692f341d3..00000000000 --- a/Docs/mysql.info +++ /dev/null @@ -1,11 +0,0 @@ -MariaDB is in most aspects identical to MySQL. - -Differences between MySQL and MariaDB can be found at: -https://mariadb.com/kb/en/mariadb-vs-mysql-features/ -https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/ - -The MariaDB manual can be found at: -https://mariadb.com/kb/ - -The MySQL Reference Manual is available in various formats on -http://dev.mysql.com/doc. diff --git a/man/aria_chk.1 b/man/aria_chk.1 index 435dac75d70..e9e09fd15b3 100644 --- a/man/aria_chk.1 +++ b/man/aria_chk.1 @@ -241,4 +241,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisamchk(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_dump_log.1 b/man/aria_dump_log.1 index 16463fc222d..86cec5a33b9 100644 --- a/man/aria_dump_log.1 +++ b/man/aria_dump_log.1 @@ -50,6 +50,6 @@ Only read default options from the given file #. Read this file after the global files are read. .PP .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/aria_ftdump.1 b/man/aria_ftdump.1 index 7b5ba5f5211..ddbc572167f 100644 --- a/man/aria_ftdump.1 +++ b/man/aria_ftdump.1 @@ -25,4 +25,4 @@ Be verbose. .SH "SEE ALSO" \fBmyisam_ftdump(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_pack.1 b/man/aria_pack.1 index 2557507b999..0cd34e6756f 100644 --- a/man/aria_pack.1 +++ b/man/aria_pack.1 @@ -72,4 +72,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisampack(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_read_log.1 b/man/aria_read_log.1 index db42162c48f..355573927a8 100644 --- a/man/aria_read_log.1 +++ b/man/aria_read_log.1 @@ -104,4 +104,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisamlog(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_s3_copy.1 b/man/aria_s3_copy.1 index 5844d5a76f0..dd664f44280 100644 --- a/man/aria_s3_copy.1 +++ b/man/aria_s3_copy.1 @@ -49,4 +49,4 @@ Output debug log from marias3 to stdout \fB\-v\fR, \fB\-\-verbose\fR Be verbose. .PP -For more information, please refer to the MariaDB Knowledge Base page https://mariadb.com/kb/en/aria_s3_copy/ +For more information, please refer to the MariaDB Documentation page https://mariadb.com/docs/server/server-usage/storage-engines/s3-storage-engine/aria_s3_copy diff --git a/man/comp_err.1 b/man/comp_err.1 index 6f000869797..c17d2f72fd7 100644 --- a/man/comp_err.1 +++ b/man/comp_err.1 @@ -256,6 +256,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/galera_recovery.1 b/man/galera_recovery.1 index 18da2fa5fd0..da4864d2731 100644 --- a/man/galera_recovery.1 +++ b/man/galera_recovery.1 @@ -13,4 +13,4 @@ galera_recovery \- recover from non\-graceful shutdown .SH DESCRIPTION Use: Recover from non\-graceful shutdown\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/innochecksum.1 b/man/innochecksum.1 index ae7a5b03523..dfe89b4eb8c 100644 --- a/man/innochecksum.1 +++ b/man/innochecksum.1 @@ -312,6 +312,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariabackup.1 b/man/mariabackup.1 index 705234fe67b..3285c405108 100644 --- a/man/mariabackup.1 +++ b/man/mariabackup.1 @@ -13,4 +13,4 @@ mariabackup \- Backup tool .SH DESCRIPTION Use \fBmariabackup \-\-help\fR for details on usage\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mariadb-conv.1 b/man/mariadb-conv.1 index 487ad003aec..b28c946bfe9 100644 --- a/man/mariadb-conv.1 +++ b/man/mariadb-conv.1 @@ -99,6 +99,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/en/mariadb-conv/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/server/clients-and-utilities/administrative-tools/mariadb-conv .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-service-convert.1 b/man/mariadb-service-convert.1 index 258c1793b41..bc87409b65c 100644 --- a/man/mariadb-service-convert.1 +++ b/man/mariadb-service-convert.1 @@ -17,4 +17,4 @@ a user mysqld_safe settings in the my.cnf files\. .PP Redirect output to user directory like /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mbstream.1 b/man/mbstream.1 index 9409d8660e5..6f4af76d1a7 100644 --- a/man/mbstream.1 +++ b/man/mbstream.1 @@ -13,4 +13,4 @@ mbstream \- Serialize/deserialize files in the XBSTREAM format .SH DESCRIPTION Use \fBmbstream \-\-help\fR for details on usage\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/msql2mysql.1 b/man/msql2mysql.1 index ed6c136f395..6903334b6e5 100644 --- a/man/msql2mysql.1 +++ b/man/msql2mysql.1 @@ -62,6 +62,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/my_print_defaults.1 b/man/my_print_defaults.1 index 38f2c0a8fe1..3a9e9122d4c 100644 --- a/man/my_print_defaults.1 +++ b/man/my_print_defaults.1 @@ -228,6 +228,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/my_safe_process.1 b/man/my_safe_process.1 index 455e1b8860f..d0c50ced83e 100644 --- a/man/my_safe_process.1 +++ b/man/my_safe_process.1 @@ -13,4 +13,4 @@ my_safe_process \- Utility program that encapsulates process creation, monitorin .SH DESCRIPTION Use: safe_process [options to safe_process] -- progname arg1 \.\.\. argn\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/myisam_ftdump.1 b/man/myisam_ftdump.1 index 449ff55d37a..dcec85a0c25 100644 --- a/man/myisam_ftdump.1 +++ b/man/myisam_ftdump.1 @@ -244,6 +244,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisamchk.1 b/man/myisamchk.1 index 1dc053337ec..0c709094522 100644 --- a/man/myisamchk.1 +++ b/man/myisamchk.1 @@ -2514,6 +2514,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisamlog.1 b/man/myisamlog.1 index dbf50cf7800..25142f8ea57 100644 --- a/man/myisamlog.1 +++ b/man/myisamlog.1 @@ -227,6 +227,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisampack.1 b/man/myisampack.1 index 89dab7d8cf5..fce2218a1bd 100644 --- a/man/myisampack.1 +++ b/man/myisampack.1 @@ -832,6 +832,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql-stress-test.pl.1 b/man/mysql-stress-test.pl.1 index 6024a2ece08..c623454c0d3 100644 --- a/man/mysql-stress-test.pl.1 +++ b/man/mysql-stress-test.pl.1 @@ -491,6 +491,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1 index 1677c070f3b..7ffdc3bbbe2 100644 --- a/man/mysql-test-run.pl.1 +++ b/man/mysql-test-run.pl.1 @@ -2313,6 +2313,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql.1 b/man/mysql.1 index 2e499a62614..127c896b040 100644 --- a/man/mysql.1 +++ b/man/mysql.1 @@ -3129,6 +3129,6 @@ Bug#25946 \%http://bugs.mysql.com/bug.php?id=25946 .RE .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql.server.1 b/man/mysql.server.1 index b3eff1dd984..b20ea75b3d3 100644 --- a/man/mysql.server.1 +++ b/man/mysql.server.1 @@ -175,6 +175,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_client_test.1 b/man/mysql_client_test.1 index 2866dfa5029..bd6d1f3b68c 100644 --- a/man/mysql_client_test.1 +++ b/man/mysql_client_test.1 @@ -327,6 +327,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_config.1 b/man/mysql_config.1 index 941e372864b..a304a8fad59 100644 --- a/man/mysql_config.1 +++ b/man/mysql_config.1 @@ -242,6 +242,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_convert_table_format.1 b/man/mysql_convert_table_format.1 index 89f6f37bcf9..874110d86f4 100644 --- a/man/mysql_convert_table_format.1 +++ b/man/mysql_convert_table_format.1 @@ -217,6 +217,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_find_rows.1 b/man/mysql_find_rows.1 index c80490c23f0..650b08e75e2 100644 --- a/man/mysql_find_rows.1 +++ b/man/mysql_find_rows.1 @@ -153,6 +153,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_fix_extensions.1 b/man/mysql_fix_extensions.1 index 270290040bd..7f4727b1a68 100644 --- a/man/mysql_fix_extensions.1 +++ b/man/mysql_fix_extensions.1 @@ -63,6 +63,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_install_db.1 b/man/mysql_install_db.1 index f945c259748..0cba4a8d7ce 100644 --- a/man/mysql_install_db.1 +++ b/man/mysql_install_db.1 @@ -393,6 +393,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_plugin.1 b/man/mysql_plugin.1 index 0512bb50ed2..110026996f4 100644 --- a/man/mysql_plugin.1 +++ b/man/mysql_plugin.1 @@ -370,6 +370,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_secure_installation.1 b/man/mysql_secure_installation.1 index 0d30ee24087..4cf6b3faaa1 100644 --- a/man/mysql_secure_installation.1 +++ b/man/mysql_secure_installation.1 @@ -162,6 +162,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_setpermission.1 b/man/mysql_setpermission.1 index 7725ad69828..3d1827e7ec1 100644 --- a/man/mysql_setpermission.1 +++ b/man/mysql_setpermission.1 @@ -163,6 +163,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_tzinfo_to_sql.1 b/man/mysql_tzinfo_to_sql.1 index e287db0c9ce..5f73333b346 100644 --- a/man/mysql_tzinfo_to_sql.1 +++ b/man/mysql_tzinfo_to_sql.1 @@ -118,6 +118,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1 index fb4988cd040..c035ef832d3 100644 --- a/man/mysql_upgrade.1 +++ b/man/mysql_upgrade.1 @@ -723,6 +723,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql_waitpid.1 b/man/mysql_waitpid.1 index 268518d5b98..6d18d5e0def 100644 --- a/man/mysql_waitpid.1 +++ b/man/mysql_waitpid.1 @@ -122,6 +122,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlaccess.1 b/man/mysqlaccess.1 index 762c1959584..973aedc0add 100644 --- a/man/mysqlaccess.1 +++ b/man/mysqlaccess.1 @@ -424,6 +424,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqladmin.1 b/man/mysqladmin.1 index 85dab8d2682..d46657bd037 100644 --- a/man/mysqladmin.1 +++ b/man/mysqladmin.1 @@ -1531,6 +1531,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlbinlog.1 b/man/mysqlbinlog.1 index 7103fa22f2b..e613d1e99cf 100644 --- a/man/mysqlbinlog.1 +++ b/man/mysqlbinlog.1 @@ -2143,6 +2143,6 @@ Bug#42941 \%http://bugs.mysql.com/bug.php?id=42941 .RE .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlcheck.1 b/man/mysqlcheck.1 index 0b101ccb7d1..eb4a18a3e53 100644 --- a/man/mysqlcheck.1 +++ b/man/mysqlcheck.1 @@ -86,8 +86,13 @@ note : The storage engine for the table doesn't support check .\} .PP If +<<<<<<< HEAD:man/mysqlcheck.1 \fBmysqlcheck\fR is unable to repair a table, see the MariaDB Knowledge Base +======= +\fBmariadb-check\fR +is unable to repair a table, see the MariaDB Documentation +>>>>>>> 894af99358b (edit KB to documentation):man/mariadb-check.1 for manual table repair strategies\&. This will be the case, for example, for InnoDB tables, which can be checked with @@ -1152,6 +1157,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqld.8 b/man/mysqld.8 index 16280234034..164b8f3c6b5 100644 --- a/man/mysqld.8 +++ b/man/mysqld.8 @@ -41,7 +41,7 @@ shell> \fBmysqld \-\-verbose \-\-help\fR MariaDB Server also has a set of system variables that affect its operation as it runs\&. System variables can be set at server startup, and many of them can be changed at runtime to effect dynamic server reconfiguration\&. MariaDB Server also has a set of status variables that provide information about its operation\&. You can monitor these status variables to access runtime performance characteristics\&. .PP For a full description of MariaDB Server command options, system variables, and status variables, see -the MariaDB Knowledge Base\&. +the MariaDB Documentation\&. .SH "COPYRIGHT" .br .PP @@ -54,6 +54,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1 index aebae5dd417..74e799092ea 100644 --- a/man/mysqld_multi.1 +++ b/man/mysqld_multi.1 @@ -677,6 +677,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1 index a96e1487980..5810f4c3821 100644 --- a/man/mysqld_safe.1 +++ b/man/mysqld_safe.1 @@ -866,6 +866,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqld_safe_helper.1 b/man/mysqld_safe_helper.1 index 24bb980c37d..be8950fbece 100644 --- a/man/mysqld_safe_helper.1 +++ b/man/mysqld_safe_helper.1 @@ -13,4 +13,4 @@ mariadbd-safe-helper \- helper script (mysqld_safe_helper is now a symlink to ma .SH DESCRIPTION Use: Helper script\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mysqldump.1 b/man/mysqldump.1 index 112b50fe9bc..46929a2d20b 100644 --- a/man/mysqldump.1 +++ b/man/mysqldump.1 @@ -2826,6 +2826,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqldumpslow.1 b/man/mysqldumpslow.1 index 960c634dded..5d52ee6ecbe 100644 --- a/man/mysqldumpslow.1 +++ b/man/mysqldumpslow.1 @@ -327,6 +327,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlhotcopy.1 b/man/mysqlhotcopy.1 index 01f26c15ab5..0dc4187d4b1 100644 --- a/man/mysqlhotcopy.1 +++ b/man/mysqlhotcopy.1 @@ -529,6 +529,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlimport.1 b/man/mysqlimport.1 index 99578950ad3..6e4a2fb48e7 100644 --- a/man/mysqlimport.1 +++ b/man/mysqlimport.1 @@ -872,6 +872,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlshow.1 b/man/mysqlshow.1 index 85b20a971fb..56c1629a93c 100644 --- a/man/mysqlshow.1 +++ b/man/mysqlshow.1 @@ -714,6 +714,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlslap.1 b/man/mysqlslap.1 index dbb458cea36..c097250dce4 100644 --- a/man/mysqlslap.1 +++ b/man/mysqlslap.1 @@ -1160,6 +1160,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqltest.1 b/man/mysqltest.1 index b1326ba8dbe..e9bd7deead9 100644 --- a/man/mysqltest.1 +++ b/man/mysqltest.1 @@ -1078,6 +1078,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mytop.1 b/man/mytop.1 index 6585439fce9..3ccd3651e87 100644 --- a/man/mytop.1 +++ b/man/mytop.1 @@ -2,6 +2,6 @@ .SH NAME mytop \- display MariaDB server performance info like 'top' .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/perror.1 b/man/perror.1 index 94a4bdb3be5..50880796aca 100644 --- a/man/perror.1 +++ b/man/perror.1 @@ -152,6 +152,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/replace.1 b/man/replace.1 index f5327815bb1..728912c2b81 100644 --- a/man/replace.1 +++ b/man/replace.1 @@ -162,6 +162,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/resolve_stack_dump.1 b/man/resolve_stack_dump.1 index df97e405b86..645a5f0c522 100644 --- a/man/resolve_stack_dump.1 +++ b/man/resolve_stack_dump.1 @@ -119,6 +119,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/resolveip.1 b/man/resolveip.1 index 8abc823b24b..7df9b9d0e45 100644 --- a/man/resolveip.1 +++ b/man/resolveip.1 @@ -101,6 +101,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/wsrep_sst_backup.1 b/man/wsrep_sst_backup.1 index d7b145575cc..fa4c4d17a37 100644 --- a/man/wsrep_sst_backup.1 +++ b/man/wsrep_sst_backup.1 @@ -13,4 +13,4 @@ wsrep_sst_backup \- backup helper script for the MariaDB Galera Cluster .SH DESCRIPTION Use: See source code of script\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_common.1 b/man/wsrep_sst_common.1 index 9fd5122c4b4..6410d5b48cb 100644 --- a/man/wsrep_sst_common.1 +++ b/man/wsrep_sst_common.1 @@ -13,4 +13,4 @@ wsrep_sst_common \- common command line parser to be sourced by other SST script .SH DESCRIPTION Use: Common command line parser to be sourced by other SST scripts\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_mariabackup.1 b/man/wsrep_sst_mariabackup.1 index 7259b028bbc..0fe6486410a 100644 --- a/man/wsrep_sst_mariabackup.1 +++ b/man/wsrep_sst_mariabackup.1 @@ -13,4 +13,4 @@ wsrep_sst_mariabackup \- mariabackup\-based state snapshot transfer .SH DESCRIPTION Use: mariabackup-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_mysqldump.1 b/man/wsrep_sst_mysqldump.1 index 56581ae889e..1dea2559a63 100644 --- a/man/wsrep_sst_mysqldump.1 +++ b/man/wsrep_sst_mysqldump.1 @@ -13,4 +13,4 @@ wsrep_sst_mysqldump \- mysqldump\-based state snapshot transfer .SH DESCRIPTION Use: mysqldump-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_rsync.1 b/man/wsrep_sst_rsync.1 index 155cb8ce637..e26faae915b 100644 --- a/man/wsrep_sst_rsync.1 +++ b/man/wsrep_sst_rsync.1 @@ -13,4 +13,4 @@ wsrep_sst_rsync \- rsync-based state snapshot transfer .SH DESCRIPTION Use: rsync-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_rsync_wan.1 b/man/wsrep_sst_rsync_wan.1 index 3eb67b3d718..f7242b4bbe2 100644 --- a/man/wsrep_sst_rsync_wan.1 +++ b/man/wsrep_sst_rsync_wan.1 @@ -13,4 +13,4 @@ wsrep_sst_rsync_wan \- rsync_wan (rsync with delta transfers)\-based state snaps .SH DESCRIPTION Use: rsync_wan\-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ From 41b14ef8231a7f932e67a78d6d678b11cd9a266b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 8 Jan 2026 12:51:44 +0530 Subject: [PATCH 008/152] MDEV-38391 Memory leak in innodb.import_hidden_fts_debug update_vcol_pos(): Move DBUG_EXECUTE_IF before pars_info_create() to prevent memory leak and fix test to properly save/restore debug_dbug variable. --- mysql-test/suite/innodb/r/import_hidden_fts_debug.result | 9 ++++++--- mysql-test/suite/innodb/t/import_hidden_fts_debug.test | 9 ++++++--- storage/innobase/row/row0import.cc | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/r/import_hidden_fts_debug.result b/mysql-test/suite/innodb/r/import_hidden_fts_debug.result index 2cf1746ee25..1d8b5114554 100644 --- a/mysql-test/suite/innodb/r/import_hidden_fts_debug.result +++ b/mysql-test/suite/innodb/r/import_hidden_fts_debug.result @@ -26,19 +26,22 @@ f2 CHAR(2) NOT NULL, f3 INT as (f1) VIRTUAL, INDEX(f3))ENGINE=InnoDB; ALTER TABLE t1 DISCARD TABLESPACE; restore: t1 .ibd and .cfg files +SET @save_debug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_set_index_root_failure"; ALTER TABLE t1 IMPORT TABLESPACE; ERROR HY000: Too many active concurrent transactions -SET DEBUG_DBUG="-d,ib_import_set_index_root_failure"; +set DEBUG_DBUG=@save_dbug; +SET @save_debug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_vcol_update_fail"; ALTER TABLE t1 IMPORT TABLESPACE; ERROR 23000: Can't write; duplicate key in table 't1' -SET DEBUG_DBUG="-d,ib_import_vcol_update_fail"; +set DEBUG_DBUG=@save_dbug; restore: t1 .ibd and .cfg files +SET @save_dbug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_fts_error"; ALTER TABLE t1 IMPORT TABLESPACE; ERROR 23000: Can't write; duplicate key in table 't1' -SET DEBUG_DBUG="-d,ib_import_fts_error"; +SET DEBUG_DBUG=@save_dbug; unlink: t1.ibd unlink: t1.cfg SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS diff --git a/mysql-test/suite/innodb/t/import_hidden_fts_debug.test b/mysql-test/suite/innodb/t/import_hidden_fts_debug.test index e3d8680d4b7..1cc626b3695 100644 --- a/mysql-test/suite/innodb/t/import_hidden_fts_debug.test +++ b/mysql-test/suite/innodb/t/import_hidden_fts_debug.test @@ -39,15 +39,17 @@ ib_restore_tablespaces("test", "t1"); EOF --disable_warnings +SET @save_debug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_set_index_root_failure"; --error ER_TOO_MANY_CONCURRENT_TRXS ALTER TABLE t1 IMPORT TABLESPACE; -SET DEBUG_DBUG="-d,ib_import_set_index_root_failure"; +set DEBUG_DBUG=@save_dbug; +SET @save_debug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_vcol_update_fail"; --error ER_DUP_KEY ALTER TABLE t1 IMPORT TABLESPACE; -SET DEBUG_DBUG="-d,ib_import_vcol_update_fail"; +set DEBUG_DBUG=@save_dbug; perl; do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; @@ -55,10 +57,11 @@ ib_discard_tablespaces("test", "t1"); ib_restore_tablespaces("test", "t1"); EOF +SET @save_dbug=@@debug_dbug; SET DEBUG_DBUG="+d,ib_import_fts_error"; --error ER_DUP_KEY ALTER TABLE t1 IMPORT TABLESPACE; -SET DEBUG_DBUG="-d,ib_import_fts_error"; +SET DEBUG_DBUG=@save_dbug; --enable_warnings perl; diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index a7557044056..872263436b4 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -4558,11 +4558,11 @@ static void row_import_autoinc(dict_table_t *table, row_prebuilt_t *prebuilt, @return DB_SUCCESS or error code */ dberr_t update_vcol_pos(table_id_t table_id, ulint new_pos, trx_t *trx) { + DBUG_EXECUTE_IF("ib_import_vcol_update_fail", + return DB_DUPLICATE_KEY;); pars_info_t *info= pars_info_create(); pars_info_add_ull_literal(info, "id", table_id); pars_info_add_int4_literal(info, "old_pos", new_pos - 1); - DBUG_EXECUTE_IF("ib_import_vcol_update_fail", - return DB_DUPLICATE_KEY;); return que_eval_sql(info, "PROCEDURE UPDATE_VCOL () IS\n" "BEGIN\n" From 3e442165844400206a7a85d542799dc40f02a62d Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Thu, 8 Jan 2026 11:26:45 +0530 Subject: [PATCH 009/152] MDEV-37266: Assertion with derived table and zero-length column One can define a derived table with a zero-length field, for example: (SELECT * FROM (SELECT '' FROM t) as x) Then, the optimizer may create a zero-length index on it (this is not allowed for regular tables). Attempt to use this index will fail an assert in create_ref_for_key(). Fix this by marking zero-length index as an Ignored Index, so the optimizer doesn't try to use it. --- mysql-test/main/derived_view.result | 14 ++++++++++++++ mysql-test/main/derived_view.test | 16 ++++++++++++++++ sql/sql_select.cc | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 1c2c1d34523..77cc6cc01ec 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -4493,3 +4493,17 @@ deallocate prepare stmt; drop view v1,v2; drop table t1,t2; # End of 10.6 tests +# +# MDEV-37266: Assertion in create_ref_for_key() with +# derived_merge OFF +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_with_keys=on'; +CREATE TABLE t1 AS SELECT 1 AS a FROM seq_1_to_2; +SELECT md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) FROM t1; +md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) +0 +0 +DROP table t1; +SET optimizer_switch=@save_optimizer_switch; +# End of 11.4 tests diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index 4483820672e..0b7885cccf3 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2948,3 +2948,19 @@ drop view v1,v2; drop table t1,t2; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-37266: Assertion in create_ref_for_key() with +--echo # derived_merge OFF +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_with_keys=on'; + +CREATE TABLE t1 AS SELECT 1 AS a FROM seq_1_to_2; +SELECT md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) FROM t1; + +DROP table t1; +SET optimizer_switch=@save_optimizer_switch; + +--echo # End of 11.4 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1c1e47142ab..b986e59656e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -22703,8 +22703,24 @@ bool Create_tmp_table::finalize(THD *thd, } } if (share->keys) + { keyinfo->index_flags= table->file->index_flags(0, 0, 1); + /* + We can end up with a zero-length index for + "SELECT * FROM (SELECT '' as col FROM t1) as DT". + Such indexes are not allowed for regular tables. + Query optimizer has at least one assertion that will fail for it. + Make sure the optimizer doesn't use zero-length index + by marking it as ignored. + */ + if (!keyinfo->key_length) + { + table->keys_in_use_for_query.clear_bit(0); + share->ignored_indexes.set_bit(0); + } + } + if (unlikely(thd->is_fatal_error)) // If end of memory goto err; /* purecov: inspected */ share->db_record_offset= 1; From 80e7ce85a799aa43f324b0bc6e2c069fdfe7de42 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 8 Jan 2026 15:09:37 +1100 Subject: [PATCH 010/152] MDEV-37908: Replace perror link with err.mariadb.com link Inspired by 22c69e0853dcd1447b881bd4448600cf286d31eb now that there's a short url. --- extra/perror.c | 8 ++------ mysql-test/main/perror-win.result | 2 +- mysql-test/main/perror.result | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/extra/perror.c b/extra/perror.c index 0cfb5b84dd0..a0f1e2a5e1e 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -360,13 +360,9 @@ int main(int argc,char *argv[]) { found= 1; if (verbose) - { - int hundred= code / 100; printf("MariaDB error code %3d (%s): %s\n" - "Learn more: https://mariadb.com/docs/server/reference/" - "error-codes/mariadb-error-codes-%d00-to-%d99/e%3d\n", - code, name, msg, hundred, hundred, code); - } + "Learn more: https://err.mariadb.com/%3d\n", + code, name, msg, code); else puts(msg); } diff --git a/mysql-test/main/perror-win.result b/mysql-test/main/perror-win.result index d8e1352f4f6..08239584dbf 100644 --- a/mysql-test/main/perror-win.result +++ b/mysql-test/main/perror-win.result @@ -3,6 +3,6 @@ Win32 error code 150: System trace information was not specified in your CONFIG. OS error code 23: Too many open files in system Win32 error code 23: Data error (cyclic redundancy check). MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192T' for key %d -Learn more: https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1000-to-1099/e1062 +Learn more: https://err.mariadb.com/1062 Win32 error code 1062: The service has not been started. Illegal error code: 30000 diff --git a/mysql-test/main/perror.result b/mysql-test/main/perror.result index 0cfcc16ff78..513af215d9e 100644 --- a/mysql-test/main/perror.result +++ b/mysql-test/main/perror.result @@ -1,10 +1,10 @@ Illegal error code: 10000 MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192T' for key %d -Learn more: https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1000-to-1099/e1062 +Learn more: https://err.mariadb.com/1062 MariaDB error code 1408 (ER_STARTUP): %s: ready for connections. Version: '%s' socket: '%s' port: %d %s -Learn more: https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1408 +Learn more: https://err.mariadb.com/1408 MariaDB error code 1459 (ER_TABLE_NEEDS_UPGRADE): Upgrade required. Please do "REPAIR %s %`s" or dump/reload to fix it! -Learn more: https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1459 +Learn more: https://err.mariadb.com/1459 MariaDB error code 1461 (ER_MAX_PREPARED_STMT_COUNT_REACHED): Can't create more than max_prepared_stmt_count statements (current value: %u) -Learn more: https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1461 +Learn more: https://err.mariadb.com/1461 From 44c670de23f5c88fab951667367b5b47b7a46885 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 9 Jan 2026 13:58:27 +0100 Subject: [PATCH 011/152] fix spider/bugfix.mdev_37972 to work for mariadb-test/ that is, when the test dir is renamed --- storage/spider/mysql-test/spider/bugfix/t/mdev_37972.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_37972.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_37972.cnf index 5339ea4cc89..e2bff509fc4 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_37972.cnf +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_37972.cnf @@ -1 +1 @@ -!include ../../../../../../mysql-test/suite/rpl/rpl_1slave_base.cnf +!include suite/rpl/rpl_1slave_base.cnf From 266919299aad9fecf3e21ad4cc2753c354773346 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Dec 2025 15:57:20 +0100 Subject: [PATCH 012/152] cleanup: main.func_json --- mysql-test/main/func_json.result | 9 +--- mysql-test/main/func_json.test | 75 ++++---------------------------- 2 files changed, 9 insertions(+), 75 deletions(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index d0d186538a8..52a62eeeacb 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -1041,9 +1041,6 @@ SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a'); JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a') null # -# Start of 10.4 tests -# -# # MDEV-16351 JSON_OBJECT() treats hybrid functions with boolean arguments as numbers # SELECT @@ -2751,7 +2748,7 @@ SET @JSON=' } ] } - + ' ; # Should return EMPTY result @@ -4953,7 +4950,6 @@ SELECT JSON_SCHEMA_VALID(@a,'{}'); JSON_SCHEMA_VALID(@a,'{}') NULL # End of 11.1 test -# Beginning of 11.2 # # MDEV-30145: JSON_TABLE: allow to retrieve the key when iterating on JSON objects # @@ -5146,8 +5142,6 @@ JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, " k v id # End of 11.2 test # -# Beginning of 11.2 tests -# # MDEV-26182: Implement json_array_intersect() # # JSON_ARRAY_INTERSECT() @@ -5346,7 +5340,6 @@ NULL SET character_set_database=default; SET CHARACTER SET default; # End of 11.2 Test -# Beginning of 11.4 Test # # MDEV-33149: JSON_ARRAY_INTERSECT function crashes the server when # called with empty json arrays, UBSAN runtime error: member access diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 23a418f16de..693b43450f9 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -78,7 +78,7 @@ select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2") select json_contains_path('{ "a": true }', NULL, '$.a' ) as exp; select json_contains_path('{ "a": true }', 'all', NULL ) as exp; select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*') as exp; - + select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1") as exp; select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY") as exp; select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2") as exp; @@ -198,7 +198,6 @@ select json_object('foo', json_unquote(json_object('bar', c)),'qux', c) as fld f --enable_cursor_protocol drop table t1; - select json_object("a", json_object("b", "abcd")); #enable after fix MDEV-31554 --disable_cursor_protocol @@ -313,7 +312,6 @@ set @@global.max_allowed_packet = @save_max_allowed_packet; set @@global.net_buffer_length = @save_net_buffer_length; --disconnect newconn - # # MDEV-12262 Assertion `!null_value' failed in virtual bool Item::send on JSON_REMOVE. # @@ -587,7 +585,6 @@ SELECT CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DOUBLE) AS cf, CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd; - --echo # --echo # MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice. --echo # @@ -679,14 +676,9 @@ SELECT JSON_VALUE('{"nulltest": null}', '$.nulltest'); SELECT 1 + NULL; SELECT 1 + JSON_VALUE('{"nulltest": null}', '$.nulltest'); - SELECT NULL; SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a'); ---echo # ---echo # Start of 10.4 tests ---echo # - --echo # --echo # MDEV-16351 JSON_OBJECT() treats hybrid functions with boolean arguments as numbers --echo # @@ -729,7 +721,6 @@ SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=3) FROM t1))='{" SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=2) FROM t1))='{"x": true}' THEN a END; SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=2) FROM t1))='{"x": false}' THEN a END; - DROP TABLE t1; -- echo # @@ -931,7 +922,6 @@ insert into t200 values ] }'); - select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; @@ -947,7 +937,6 @@ SELECT JSON_LENGTH(); --echo # MDEV-23187: Assorted assertion failures in json_find_path with certain collations - SET @old_collation_connection= @@COLLATION_CONNECTION; SET COLLATION_CONNECTION= ucs2_unicode_ci; @@ -1097,10 +1086,10 @@ DROP TABLE t1; CREATE TABLE t1(id int primary key, name varchar(50)); CREATE TABLE t2(id int, owner_id int); - + INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); - + SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials from t1 LEFT JOIN t2 on t1.id = t2.owner_id GROUP BY t1.id ORDER BY id; @@ -1123,7 +1112,7 @@ CREATE TABLE arrNestTest ( id VARCHAR(80) AS (JSON_COMPACT(JSON_EXTRACT(doc, "$._id"))) UNIQUE KEY, doc JSON, CONSTRAINT id_not_null CHECK(id IS NOT NULL)); - + INSERT INTO test.arrNestTest (doc) VALUES ('{ "_id" : { "$oid" : "611c0a463b150154132f6636" }, "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : 1.0 } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }'); SELECT * FROM arrNestTest; DROP TABLE arrNestTest; @@ -1146,14 +1135,12 @@ set names latin1; select json_arrayagg('ä'), json_objectagg(1, 'ä'); --enable_service_connection - --echo # --echo # MDEV-32287: JSON_EXTRACT not returning multiple values for same path --echo # select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); - --echo # --echo # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json --echo # @@ -1170,7 +1157,6 @@ DROP TABLE t; SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast('2019-01-01' as Date) ), '$.date')) as x; - --echo # --echo # MDEV-22141: JSON_REMOVE returns NULL on valid arguments --echo # @@ -1178,7 +1164,6 @@ SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast(' SELECT JSON_REMOVE('{"A": { "B": 1 }}', '$.A.B.C.D'); - --echo # --echo # MDEV-34143: Server crashes when executing JSON_EXTRACT after setting non-default collation_connection --echo # @@ -1192,7 +1177,6 @@ SELECT JSON_EXTRACT('{"a": 1,"b": 2}','$.a'); SET @@collation_connection= @save_collation_connection; - --echo # End of 10.5 tests --echo # @@ -1216,19 +1200,16 @@ SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_I SELECT JSON_INSERT(JSON_OBJECT(l1, l2, l3, l4), '$.k3', 'v3'),JSON_SET(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2'),JSON_REPLACE(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2') from t; DROP TABLE t; - --echo # --echo # MDEV-27412: JSON_TABLE doesn't properly unquote strings --echo # - SET @data = '[{"Data": ""}]'; SELECT data FROM JSON_TABLE (@data, '$[*]' COLUMNS (data text PATH '$.Data')) AS t; - --echo # --echo # MDEV-21530: json_extract STILL crashes in Item_func_json_extract::read_json --echo # @@ -1272,7 +1253,6 @@ DROP TABLE t1; --echo # MDEV-27677: Implement JSON_OVERLAPS() --echo # - --echo # Testing scalar json datatypes --echo # Comparing scalar json datatypes with itself @@ -1293,7 +1273,6 @@ SELECT JSON_OVERLAPS('true','["abc", 1, 2, true, false]'); SELECT JSON_OVERLAPS('true','["abc", 1, 2, [true]]'); SELECT JSON_OVERLAPS('true','{"A":true}'); - --echo # Testing non-scalar json data types --echo # Comparing object with object (non-nested) @@ -1358,7 +1337,6 @@ SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', '{"C":3, "F":{"E":[5, 6, 7], "D":4}}') as exp; - --echo # Comparing array with array (non-nested) SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, 1]') as exp; @@ -1373,7 +1351,6 @@ SELECT JSON_OVERLAPS('[1, 2, [true, false], null]', '[[1], [true, false]]') as exp; SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]') as exp; - --echo # Comparing one non-scalar json datatypes with another non-scalar --echo # json datatype @@ -1665,7 +1642,6 @@ SELECT JSON_VALUE(@json,'$.x[last-0]'); SELECT JSON_VALUE(@json,'$.x[-0]'); SELECT JSON_VALUE(@json,'$.x[0]'); - --echo # --echo # MDEV-27911: Implement range notation for json path --echo # @@ -1837,7 +1813,6 @@ SET @json1= '[ ]'; SELECT JSON_VALUE(@json1, '$[2][1 to 2].key1'); - SET @json= '[ [1.1, {"key1": "value1"}, 3], [false, 5, 6], @@ -1876,7 +1851,6 @@ SELECT JSON_EXISTS(@json, '$[2][2][1 to 2]'); SELECT JSON_EXISTS(@json, '$[2][2][4 to 6]'); SELECT JSON_EXISTS(@json, '$[2][2][1 to 4]'); - --echo # --echo # MDEV-28326: Server crashes in json_path_parts_compare --echo # @@ -1897,7 +1871,7 @@ SELECT JSON_OVERLAPS(@json1, @json2); --echo # CREATE TABLE t1 ( j JSON ); - + INSERT INTO t1 (j) VALUES ('[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}]'); INSERT INTO t1 (j) VALUES ('[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}, {"key5": 2, "key6": 2}]'); INSERT INTO t1 (j) VALUES ('[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}, {"key5": 3}]'); @@ -1918,7 +1892,6 @@ SELECT JSON_EXTRACT('{ "my-key": 1 }', '$.my-key'); --echo # MDEV-23187: Assorted assertion failures in json_find_path with certain collations --echo # - SET @save_collation_connection= @@collation_connection; SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }'; @@ -1932,7 +1905,6 @@ SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }'; SET sql_mode=0,character_set_connection=utf32; SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1'); - SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }'; SET sql_mode=0,character_set_connection=utf32; SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1'); @@ -2015,14 +1987,14 @@ SET @JSON=' } ] } - + ' ; - + --echo # Should return EMPTY result SELECT * FROM json_table(@JSON, '$.SZ[0].OFFERS[1]' COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; - + --echo # Should return S1A1 SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]' COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; @@ -2299,7 +2271,6 @@ SELECT JSON_SCHEMA_VALID(@string_schema, '"abc"'); SET @schema_array= '{"type":"array"}'; SELECT JSON_SCHEMA_VALID(@schema_array, '[1, 2, {"key1":"val1"}]'); - SET @schema_array= '{"type":"array", "maxItems": 4, "minItems": 2}'; @@ -2770,7 +2741,6 @@ INSERT INTO str_table VALUES('"abcdef"'); INSERT INTO str_table VALUES('"fedcba"'); SELECT * FROM str_table; - INSERT INTO num_table values('15'); --error ER_CONSTRAINT_FAILED INSERT INTO num_table values('25'); @@ -2946,7 +2916,6 @@ SET @schema_array= '{ SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", "string2", "string3"]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", 1, 2]'); - SET @schema_array= '{ "type": "array", "prefixItems": [ @@ -2978,10 +2947,8 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", "string2", "string3"]'); - --echo # Removing prefixItems - SET @schema_array= '{ "type": "array", "items": { "type": "number", "maximum": 10, "minimum":3}, @@ -2990,7 +2957,6 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '[5, 6,"2", "string"]'); - SET @schema_array= '{ "type": "array", "items": { "type": "number", "maximum": 10, "minimum":3}, @@ -3066,7 +3032,6 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '["str1", "str2", 1]'); - --echo # checking that unevaluatedItems alone can have effect on schema validation SET @schema_array= '{ @@ -3089,7 +3054,6 @@ SELECT JSON_SCHEMA_VALID(@schema_array, '[1, "str1"]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[1,2,3]'); - --echo # Object validation SET @property_names= '{ @@ -3130,7 +3094,6 @@ SELECT JSON_SCHEMA_VALID(@object_schema, '{"key1":"val1", "key2": 10, "I_int":20 --echo # existence of unevaluatedProperties still does not change anything because of existence of additional --echo # properties - SET @object_schema= '{ "type":"object", "properties": { @@ -3211,7 +3174,6 @@ SET @object_schema= '{ }'; SELECT JSON_SCHEMA_VALID(@object_schema, '{"key1":"val1", "key2": 10, "I_int":20, "S_":"abc", "some_prop1":[1,2,3]}'); - --echo # Checking that in absence of additionalProperties, validation falls back on evaluatedProperties SET @object_schema= '{ @@ -3787,7 +3749,6 @@ SET @schema = '{ --error ER_JSON_INVALID_VALUE_FOR_KEYWORD SELECT JSON_SCHEMA_VALID(@schema, '2'); - --echo # --echo # MDEV-30704: JSON_SCHEMA_VALID: multipleOf must be greater than zero --echo # @@ -3826,7 +3787,6 @@ SET @schema= '{ "items" : ["str1"]}'; --error ER_JSON_INVALID_VALUE_FOR_KEYWORD SELECT JSON_SCHEMA_VALID(@schema, '[]'); - --echo # --echo # MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value always return 1 --echo # @@ -3872,7 +3832,6 @@ SELECT JSON_SCHEMA_VALID(@schema, '-#'); --echo # MDEV-30689: JSON_SCHEMA_VALID for type=array return 1 for any string that starts with '[' --echo # - SET @schema_array= '{"type":"array"}'; SELECT JSON_SCHEMA_VALID(@schema_array, '['); @@ -3905,11 +3864,8 @@ PREPARE s FROM 'SELECT JSON_SCHEMA_VALID (?,''{}'') FROM DUAL'; SET @a= NULL; SELECT JSON_SCHEMA_VALID(@a,'{}'); - --echo # End of 11.1 test ---echo # Beginning of 11.2 - --echo # --echo # MDEV-30145: JSON_TABLE: allow to retrieve the key when iterating on JSON objects --echo # @@ -3966,7 +3922,6 @@ FROM JSON_TABLE( SELECT JSON_KEY_VALUE('[]', '[0]'); - SELECT JSON_KEY_VALUE('[1, 2, 3]', '$[0]'); SELECT jt.* FROM JSON_TABLE( @@ -4061,14 +4016,10 @@ FROM JSON_TABLE( --echo # End of 11.2 test ---echo # ---echo # Beginning of 11.2 tests --echo # --echo # MDEV-26182: Implement json_array_intersect() --echo # - - --echo # JSON_ARRAY_INTERSECT() --echo # Scalar as elements @@ -4097,7 +4048,6 @@ SET @obj1= '[null, true]'; SET @obj2= '[false, null]'; select json_array_intersect(@obj1, @obj2); - --echo # array as elements SET @json1= '[6,6,6]'; @@ -4138,7 +4088,6 @@ SET @obj1= '[1, 2, 3, 3, 3.0, "abc", true, true, {"key1":"val1"}]'; SET @obj2= '[3.0, 3, 5, "abc", "abc", true, {"key2":"val2"}, {"key1":"val1"}, {"key1":"val2"}]'; select json_array_intersect(@obj1, @obj2); - --echo # Checking Syntax error for JSON_ARRAY_INTERSECT() SET @obj1= '[1, 2, 3, 3, 3.0, "abc", true, true, {"key1":"val1" ]'; SET @obj2= '[3.0, 3, 5, "abc", "abc", true, {"key2":"val2"}, {"key1":"val1"}, {"key1":"val2"}]'; @@ -4156,7 +4105,6 @@ select json_array_intersect(@arr1, @num1); select json_array_intersect(@num1, @bool1); - --echo # JSON_OBJECT_FILTER_KEYS() SET @obj1= '{ "a": 1, "b": 2, "c": 3}'; @@ -4167,12 +4115,10 @@ SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @obj2= '{"b" : 10, "c": 20, "d": 30}'; SELECT JSON_OBJECT_FILTER_KEYS (@obj1, json_array_intersect(json_keys(@obj1), json_keys(@obj2))); - SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @arr2='["x", "y", "z"]'; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr2); - SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @arr2='["key2", "key1", "b"]'; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr1); @@ -4197,7 +4143,6 @@ SET @arr2= '[ "key2", "key1", "b" '; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr1); - --echo # JSON_OBJECT_TO_ARRAY() SET @obj1= '{ "a": [1, 2, 3], "b": { "key1":"val1", "key2": {"key3":"val3"} }, "c": 3, "d" : 1, "e": "xyz", "f": true, "g" : null}'; @@ -4216,7 +4161,6 @@ SELECT JSON_OBJECT_TO_ARRAY(@obj1); SET @arr1= '[1, 2, 3]'; SELECT JSON_OBJECT_TO_ARRAY(@arr1); - --echo # --echo # MDEV-31411: JSON_ARRAY_INTERSECT/JSON_OBJECT_FILTER_KEYS should fetch --echo # data from a table similar to other JSON functions @@ -4236,7 +4180,6 @@ SELECT JSON_ARRAY_INTERSECT(c1, c2) FROM t1; DROP TABLE t1; - --echo # --echo # MDEV-31543: ASAN heap-buffer-overflow in strncpy when fetching keys using JSON_OBJECT_FILTER_KEYS function --echo # @@ -4252,8 +4195,6 @@ SET CHARACTER SET default; --echo # End of 11.2 Test ---echo # Beginning of 11.4 Test - --echo # --echo # MDEV-33149: JSON_ARRAY_INTERSECT function crashes the server when --echo # called with empty json arrays, UBSAN runtime error: member access From 93ef1236002fb42725770f076e7be712c87ea403 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Dec 2025 16:07:34 +0100 Subject: [PATCH 013/152] MDEV-38356 JSON_SCHEMA_VALID() crashes with a long enum --- mysql-test/main/func_json.result | 6 ++++++ mysql-test/main/func_json.test | 8 +++++--- sql/json_schema_helper.cc | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 52a62eeeacb..1df57b28475 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -5377,4 +5377,10 @@ result # SELECT JSON_SCHEMA_VALID('{"properties": "a_string": {"pattern": "^[5-9]$"}}}', '{"a_string": "8"}'); ERROR HY000: Invalid value for keyword properties +# +# MDEV-38356 JSON_SCHEMA_VALID() crashes with a long enum +# +select json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')); +json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')) +0 # End of 11.4 Test diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 693b43450f9..81e36559b12 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -3612,8 +3612,6 @@ SET @schema_reference= '{"$defs": "http://example.com/custom-email-validator.jso --error ER_JSON_SCHEMA_KEYWORD_UNSUPPORTED SELECT JSON_SCHEMA_VALID(@schema_reference, '{}'); - - --echo # --echo # MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment --echo # @@ -4216,7 +4214,6 @@ SELECT ( WITH x AS ( WITH x ( x ) AS ( SELECT ( 1.000000 ) ) SELECT x FROM x ) S select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', '[["2","6"],["3","8"],["4","5"],["1","7"]]') as result from (values (1),(2),(3),(4),(5)) x; - --echo # --echo # MDEV-33640: Server crashes at my_hash_free --echo # @@ -4224,4 +4221,9 @@ select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', --error ER_JSON_INVALID_VALUE_FOR_KEYWORD SELECT JSON_SCHEMA_VALID('{"properties": "a_string": {"pattern": "^[5-9]$"}}}', '{"a_string": "8"}'); +--echo # +--echo # MDEV-38356 JSON_SCHEMA_VALID() crashes with a long enum +--echo # +select json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')); + --echo # End of 11.4 Test diff --git a/sql/json_schema_helper.cc b/sql/json_schema_helper.cc index 5d4d04ae6c1..c453acfd642 100644 --- a/sql/json_schema_helper.cc +++ b/sql/json_schema_helper.cc @@ -88,7 +88,7 @@ void json_get_normalized_string(json_engine_t *je, String *res, } else if(je->value_type == JSON_VALUE_STRING) { - strncpy((char*)a_res.str, val.ptr(), je->value_len); + dynstr_set(&a_res, val.c_ptr()); a_res.length= je->value_len; } From 0397e4e4dc4b5f538bdc71a9bc6cd6aa35f824a7 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Thu, 25 Dec 2025 23:49:52 +0700 Subject: [PATCH 014/152] 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. --- mysql-test/main/rename.result | 40 ++++++++++++++++++++ mysql-test/main/rename.test | 41 ++++++++++++++++++++ sql/sql_class.h | 70 +++++++++++++++++++++++++++++++++++ sql/sql_rename.cc | 15 ++++++++ 4 files changed, 166 insertions(+) diff --git a/mysql-test/main/rename.result b/mysql-test/main/rename.result index 64ccf385958..6da5e059061 100644 --- a/mysql-test/main/rename.result +++ b/mysql-test/main/rename.result @@ -173,3 +173,43 @@ drop table t2; rename table if exists t1 to t2; alter table if exists t2 rename to t1; drop table t1; +# +# MDEV-27027 Atomic DDL: Assertion `!param->got_error' failed upon +# unsuccessful multi-RENAME TABLE +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW +INSERT INTO db.t SELECT SLEEP(0.05); +# Missing table in RENAME TABLE (should error) +RENAME TABLE t1 TO t2, +missing1 TO m1; +ERROR 42S02: Table 'test.missing1' doesn't exist +SHOW CREATE TRIGGER tr1; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON `t1` FOR EACH ROW +INSERT INTO db.t SELECT SLEEP(0.05) latin1 latin1_swedish_ci latin1_swedish_ci # +CREATE TABLE t2 (a INT); +# Attempt to rename to existing table (should error) +RENAME TABLE t2 TO t3, +t1 TO t3; +ERROR 42S01: Table 't3' already exists +SHOW CREATE TRIGGER tr1; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON `t1` FOR EACH ROW +INSERT INTO db.t SELECT SLEEP(0.05) latin1 latin1_swedish_ci latin1_swedish_ci # +# Test multiple warnings captured during renaming +RENAME TABLE IF EXISTS +missing1 TO m1, +missing2 TO m2, +t2 TO t3, # this rename succeeds +missing3 TO m3; +Warnings: +Note 1146 Table 'test.missing1' doesn't exist +Note 1146 Table 'test.missing2' doesn't exist +Note 1146 Table 'test.missing3' doesn't exist +RENAME TABLE IF EXISTS +missing1 TO m1, +t1 TO t3, # this will error: table exists +missing2 TO m2; +ERROR 42S01: Table 't3' already exists +DROP TABLE t1, t3; diff --git a/mysql-test/main/rename.test b/mysql-test/main/rename.test index a0b9f38ae2e..969c0417b4f 100644 --- a/mysql-test/main/rename.test +++ b/mysql-test/main/rename.test @@ -166,3 +166,44 @@ drop table t2; rename table if exists t1 to t2; alter table if exists t2 rename to t1; drop table t1; + +--echo # +--echo # MDEV-27027 Atomic DDL: Assertion `!param->got_error' failed upon +--echo # unsuccessful multi-RENAME TABLE +--echo # +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW + INSERT INTO db.t SELECT SLEEP(0.05); + +--echo # Missing table in RENAME TABLE (should error) +--error ER_NO_SUCH_TABLE +RENAME TABLE t1 TO t2, + missing1 TO m1; # this will error: missing table + +--replace_column 7 # +SHOW CREATE TRIGGER tr1; + +CREATE TABLE t2 (a INT); + +--echo # Attempt to rename to existing table (should error) +--error ER_TABLE_EXISTS_ERROR +RENAME TABLE t2 TO t3, + t1 TO t3; # this will error: table exists + +--replace_column 7 # +SHOW CREATE TRIGGER tr1; + +--echo # Test multiple warnings captured during renaming +RENAME TABLE IF EXISTS + missing1 TO m1, + missing2 TO m2, + t2 TO t3, # this rename succeeds + missing3 TO m3; + +--error ER_TABLE_EXISTS_ERROR +RENAME TABLE IF EXISTS + missing1 TO m1, + t1 TO t3, # this will error: table exists + missing2 TO m2; + +DROP TABLE t1, t3; \ No newline at end of file diff --git a/sql/sql_class.h b/sql/sql_class.h index 42a8567ea5a..d3c50df01f0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2047,6 +2047,76 @@ public: }; +extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); + +/** + Error handler that captures and postpones errors. + Warnings and notes are passed through to the next handler. + Stored errors can be re-emitted later via emit_errors(). +*/ + +class Postponed_error_handler : public Internal_error_handler +{ + struct Error_entry + { + uint sql_errno; + char message[MYSQL_ERRMSG_SIZE]; + Error_entry *next; + }; + + Error_entry *m_first; + Error_entry *m_last; + MEM_ROOT *m_mem_root; + +public: + Postponed_error_handler(MEM_ROOT *mem_root) + : m_first(nullptr), m_last(nullptr), m_mem_root(mem_root) + {} + + bool handle_condition(THD *thd, + uint sql_errno, + const char *sqlstate, + Sql_condition::enum_warning_level *level, + const char *msg, + Sql_condition **cond_hdl) override + { + /* Only capture errors, let warnings and notes pass through */ + if (*level != Sql_condition::WARN_LEVEL_ERROR) + return false; + + Error_entry *entry= (Error_entry*) alloc_root(m_mem_root, + sizeof(Error_entry)); + if (!entry) + return false; // Can't store, let error propagate + + entry->sql_errno= sql_errno; + strmake(entry->message, msg, sizeof(entry->message) - 1); + entry->next= nullptr; + + if (m_last) + m_last->next= entry; + else + m_first= entry; + m_last= entry; + + return true; + } + + bool has_errors() const { return m_first != nullptr; } + + void emit_errors() + { + for (Error_entry *e= m_first; e; e= e->next) + my_message_sql(e->sql_errno, e->message, MYF(0)); + } + + void clear() + { + m_first= m_last= nullptr; + } +}; + + /** This class is an internal error handler implementation for DROP TABLE statements. The thing is that there may be warnings during diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 421c7198c10..5b909200cae 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -20,6 +20,7 @@ */ #include "mariadb.h" +#include "sql_class.h" #include "sql_priv.h" #include "unireg.h" #include "sql_rename.h" @@ -51,6 +52,7 @@ static bool rename_tables(THD *thd, TABLE_LIST *table_list, the new name. */ + bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, bool if_exists) { @@ -60,6 +62,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, int to_table; const char *rename_log_table[2]= {NULL, NULL}; DDL_LOG_STATE ddl_log_state; + Postponed_error_handler postponed_handler(thd->mem_root); DBUG_ENTER("mysql_rename_tables"); /* @@ -162,6 +165,15 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, An exclusive lock on table names is satisfactory to ensure no other thread accesses this table. */ + + /* + Do not emit errors which may occur during the sequence of renamings, + because they will raise the 'thd->is_error()' flag, and `ddl_log_revert()` + may fail due to this. Instead, capture and collect errors and warnings + and emit them only after the renaming and possible reversion are complete. + */ + thd->push_internal_handler(&postponed_handler); + error= rename_tables(thd, table_list, &ddl_log_state, 0, if_exists, &force_if_exists); @@ -192,15 +204,18 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, my_ok(thd); } + thd->pop_internal_handler(); if (likely(!error)) { query_cache_invalidate3(thd, table_list, 0); ddl_log_complete(&ddl_log_state); + DBUG_ASSERT(!postponed_handler.has_errors()); } else { /* Revert the renames of normal tables with the help of the ddl log */ ddl_log_revert(thd, &ddl_log_state); + postponed_handler.emit_errors(); } err: From 08ba31ff902c4d678f2818064bc1e28536c9c02d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 9 Jan 2026 16:38:04 +0200 Subject: [PATCH 015/152] Remove redundant mtr.add_suppression() --- mysql-test/suite/innodb/r/restart.result | 7 ------- mysql-test/suite/innodb/t/restart.test | 8 -------- 2 files changed, 15 deletions(-) diff --git a/mysql-test/suite/innodb/r/restart.result b/mysql-test/suite/innodb/r/restart.result index 95d79a0ab14..3e5e5f2952b 100644 --- a/mysql-test/suite/innodb/r/restart.result +++ b/mysql-test/suite/innodb/r/restart.result @@ -1,15 +1,8 @@ # # MDEV-15333 MariaDB (still) slow start # -# FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files -# of tables with .isl file or DATA DIRECTORY attribute. call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); -# FIXME: This is much more noisy than MariaDB 10.1! -call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd"); -call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); -call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); -call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for test/td because it could not be opened\\."); CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; diff --git a/mysql-test/suite/innodb/t/restart.test b/mysql-test/suite/innodb/t/restart.test index db201f958ef..d9a97f05eb3 100644 --- a/mysql-test/suite/innodb/t/restart.test +++ b/mysql-test/suite/innodb/t/restart.test @@ -14,17 +14,9 @@ let tmp_in_vardir=$MYSQLTEST_VARDIR/tmp; # Note: just like in MySQL, all .ibd files will still be # opened at least once. ---echo # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files ---echo # of tables with .isl file or DATA DIRECTORY attribute. call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); ---echo # FIXME: This is much more noisy than MariaDB 10.1! -call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd"); -call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); -call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); -call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for test/td because it could not be opened\\."); - CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; From accb4af95bdf6c314773456250864cc0d3f591f0 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 9 Jan 2026 20:06:52 +0530 Subject: [PATCH 016/152] MDEV-31892 Server crash upon moving InnoDB table with fulltext index between databases Problem: ======== - When renaming/moving an InnoDB table with fulltext indexes between databases, the server would crash because InnoDB attempted to open auxiliary tables using the old database name instead of the new one. When creating auxiliary index, InnoDB does create temporary sort fulltext index using old table reference which creates the auxiliary table name with the prefix of old database name. FTS Document ID size optimization in row_merge_create_fts_sort_index() using dict_table_get_n_rows() to decide between 4-byte and 8-byte Doc IDs for memory optimization. But dict_table_get_n_rows() returns estimated statistics that may be stale or inaccurate, potentially leading to wrong size decisions and data corruption if 4-byte Doc IDs are chosen when 8-byte are actually needed. Solution: ========= fts_rename_aux_tables(): Iterate through all table indexes and ensure all fulltext indexes are properly renamed row_merge_create_fts_sort_index() : Use new_table instead of old_table when creating temporary FTS sort indexes. row_merge_build_indexes(): Refactored the logic to do memory optimization to determine the doc id size for temporary fts sort index. - When adding FTS index for the first time (DICT_TF2_FTS_ADD_DOC_ID), always use 8-byte Doc IDs - For existing FTS tables or user-supplied Doc ID columns, use fts_get_max_doc_id() approach to check actual maximum Doc ID --- .../suite/innodb_fts/r/innodb-fts-ddl.result | 10 +++++++ .../suite/innodb_fts/t/innodb-fts-ddl.test | 12 +++++++++ storage/innobase/fts/fts0fts.cc | 16 +++++------ storage/innobase/include/row0ftsort.h | 4 +-- storage/innobase/row/row0ftsort.cc | 27 +++---------------- storage/innobase/row/row0merge.cc | 22 +++++++++++++-- 6 files changed, 54 insertions(+), 37 deletions(-) diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result index e890ff6f119..fe7781a72f5 100644 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result @@ -332,3 +332,13 @@ ALTER TABLE t ADD FULLTEXT INDEX ft1(f1); ALTER TABLE t ADD FULLTEXT INDEX ft2(f2); INSERT INTO t (f1,f2,f3) VALUES ('bar','baz','qux'); DROP TABLE t; +# +# MDEV-31892 Server crash upon moving InnoDB table +# with fulltext index between databases +# +CREATE DATABASE db; +CREATE TABLE db.t (pk INT PRIMARY KEY, c CHAR(120), FULLTEXT KEY(c)) ENGINE=InnoDB; +INSERT INTO db.t VALUES (1,'foo'),(2,'bar'); +ALTER TABLE db.t FORCE, RENAME to test.t; +DROP DATABASE db; +DROP TABLE IF EXISTS test.t; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test index b46e8156a91..8d4cbe7b86c 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test @@ -441,3 +441,15 @@ ALTER TABLE t ADD FULLTEXT INDEX ft1(f1); ALTER TABLE t ADD FULLTEXT INDEX ft2(f2); INSERT INTO t (f1,f2,f3) VALUES ('bar','baz','qux'); DROP TABLE t; + +--echo # +--echo # MDEV-31892 Server crash upon moving InnoDB table +--echo # with fulltext index between databases +--echo # +CREATE DATABASE db; +CREATE TABLE db.t (pk INT PRIMARY KEY, c CHAR(120), FULLTEXT KEY(c)) ENGINE=InnoDB; +INSERT INTO db.t VALUES (1,'foo'),(2,'bar'); +ALTER TABLE db.t FORCE, RENAME to test.t; +# Cleanup +DROP DATABASE db; +DROP TABLE IF EXISTS test.t; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index a878905ace4..c4ab1a3a1bd 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1485,17 +1485,15 @@ fts_rename_aux_tables( } } - fts_t* fts = table->fts; + for (dict_index_t *index = dict_table_get_first_index(table); + index; index = dict_table_get_next_index(index)) { + if (!(index->type & DICT_FTS)) { + continue; + } - /* Rename index specific auxiliary tables */ - for (i = 0; fts->indexes != 0 && i < ib_vector_size(fts->indexes); - ++i) { - dict_index_t* index; + FTS_INIT_INDEX_TABLE(&fts_table, nullptr, + FTS_INDEX_TABLE, index); - index = static_cast( - ib_vector_getp(fts->indexes, i)); - - FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index); for (ulint j = 0; j < FTS_NUM_AUX_INDEX; ++j) { fts_table.suffix = fts_get_suffix(j); diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h index 3ffa8243306..e0e721a639e 100644 --- a/storage/innobase/include/row0ftsort.h +++ b/storage/innobase/include/row0ftsort.h @@ -187,8 +187,8 @@ row_merge_create_fts_sort_index( is created */ dict_table_t* table, /*!< in,out: table that FTS index is being created on */ - ibool* opt_doc_id_size); - /*!< out: whether to use 4 bytes + bool opt_doc_id_size); + /*!< in: whether to use 4 bytes instead of 8 bytes integer to store Doc ID during sort */ diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index c94ceb728fb..284c80a6b20 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -70,8 +70,8 @@ row_merge_create_fts_sort_index( is created */ dict_table_t* table, /*!< in,out: table that FTS index is being created on */ - ibool* opt_doc_id_size) - /*!< out: whether to use 4 bytes + bool opt_doc_id_size) + /*!< in: whether to use 4 bytes instead of 8 bytes integer to store Doc ID during sort */ { @@ -115,29 +115,8 @@ row_merge_create_fts_sort_index( field->col = static_cast( mem_heap_zalloc(new_index->heap, sizeof(dict_col_t))); field->col->mtype = DATA_INT; - *opt_doc_id_size = FALSE; - /* Check whether we can use 4 bytes instead of 8 bytes integer - field to hold the Doc ID, thus reduce the overall sort size */ - if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_ADD_DOC_ID)) { - /* If Doc ID column is being added by this create - index, then just check the number of rows in the table */ - if (dict_table_get_n_rows(table) < MAX_DOC_ID_OPT_VAL) { - *opt_doc_id_size = TRUE; - } - } else { - doc_id_t max_doc_id; - - /* If the Doc ID column is supplied by user, then - check the maximum Doc ID in the table */ - max_doc_id = fts_get_max_doc_id((dict_table_t*) table); - - if (max_doc_id && max_doc_id < MAX_DOC_ID_OPT_VAL) { - *opt_doc_id_size = TRUE; - } - } - - if (*opt_doc_id_size) { + if (opt_doc_id_size) { field->col->len = sizeof(ib_uint32_t); field->fixed_len = sizeof(ib_uint32_t); } else { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 2345b853b54..049d0e8ad5f 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4476,14 +4476,32 @@ row_merge_build_indexes( * static_cast(n_indexes); for (i = 0; i < n_indexes; i++) { if (indexes[i]->type & DICT_FTS) { - ibool opt_doc_id_size = FALSE; + bool opt_doc_id_size = false; /* To build FTS index, we would need to extract doc's word, Doc ID, and word's position, so we need to build a "fts sort index" indexing on above three 'fields' */ + + /* Check whether we can use 4 bytes instead of 8 bytes + integer field to hold the Doc ID, thus reduce + the overall sort size. If the fulltext index is being + added for the first time then we should use 8 bytes Doc ID + size because table->stat_n_rows is an estimation and + not reliable to determine the Doc ID size. */ + if (old_table->fts || !DICT_TF2_FLAG_IS_SET( + new_table, DICT_TF2_FTS_ADD_DOC_ID)) { + /* If the Doc ID column is supplied by user + or rebuilding the existing FTS table, then + check the maximum Doc ID in the old table */ + doc_id_t max_doc_id = + fts_get_max_doc_id((dict_table_t*) old_table); + opt_doc_id_size = + (max_doc_id < MAX_DOC_ID_OPT_VAL); + } + fts_sort_idx = row_merge_create_fts_sort_index( - indexes[i], old_table, &opt_doc_id_size); + indexes[i], new_table, opt_doc_id_size); row_merge_dup_t* dup = static_cast( From 3009210e63a8168afb0d946397133eb4bc16a5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Smutn=C3=BD?= Date: Thu, 18 Dec 2025 16:13:17 +0100 Subject: [PATCH 017/152] fsp0fsp.cc: log unexpected table in sys tablespace Fix log message about unexpected table in system tablespace as the current message can be missleading due to still existing (but already deprecated) system tables SYS_DATAFILES and SYS_TABLESPACES, reported in - MDEV-38412 Also adding the informative message with table name of the unexpected table in system table space. --- mysql-test/suite/innodb/r/sys_defragment_fail.result | 3 ++- mysql-test/suite/innodb/t/sys_defragment_fail.test | 4 +++- storage/innobase/fsp/fsp0fsp.cc | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/sys_defragment_fail.result b/mysql-test/suite/innodb/r/sys_defragment_fail.result index 90735538fa3..bf418396ee0 100644 --- a/mysql-test/suite/innodb/r/sys_defragment_fail.result +++ b/mysql-test/suite/innodb/r/sys_defragment_fail.result @@ -17,7 +17,8 @@ INSERT INTO t1 SELECT seq, seq FROM seq_1_to_4096; DROP TABLE t2; InnoDB 0 transactions not purged # restart -FOUND 1 /InnoDB: User table exists in the system tablespace/ in mysqld.1.err +FOUND 1 /InnoDB: Found unexpected table in system tablespace: test\/t1/ in mysqld.1.err +FOUND 1 /InnoDB: Unexpected table exists in the system tablespace/ in mysqld.1.err DROP TABLE t1; InnoDB 0 transactions not purged # restart: --debug_dbug=+d,fail_after_level_defragment diff --git a/mysql-test/suite/innodb/t/sys_defragment_fail.test b/mysql-test/suite/innodb/t/sys_defragment_fail.test index 4800e2619cb..aca741b9021 100644 --- a/mysql-test/suite/innodb/t/sys_defragment_fail.test +++ b/mysql-test/suite/innodb/t/sys_defragment_fail.test @@ -29,7 +29,9 @@ let $restart_parameters=; --source include/restart_mysqld.inc let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; -let SEARCH_PATTERN=InnoDB: User table exists in the system tablespace; +let SEARCH_PATTERN=InnoDB: Found unexpected table in system tablespace: test\/t1; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN=InnoDB: Unexpected table exists in the system tablespace; --source include/search_pattern_in_file.inc DROP TABLE t1; diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index d537b4478e7..1fa03e20998 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -5723,6 +5723,14 @@ corrupt: goto corrupt; if (!dict_sys.is_sys_table(mach_read_from_8(field))) { + const byte *name_field = rec_get_nth_field_old( + rec, DICT_FLD__SYS_TABLES__NAME, &len); + if (len != UNIV_SQL_NULL && len > 0) + { + sql_print_information( + "InnoDB: Found unexpected table in system tablespace: %.*s", + (int)len, (const char *)name_field); + } err= DB_SUCCESS_LOCKED_REC; btr_pcur_close(&pcur); goto func_exit; @@ -5740,7 +5748,7 @@ dberr_t fil_space_t::defragment() noexcept if (err == DB_SUCCESS_LOCKED_REC) { sql_print_information( - "InnoDB: User table exists in the system tablespace." + "InnoDB: Unexpected table exists in the system tablespace." "Please try to move the data from system tablespace " "to separate tablespace before defragment the " "system tablespace."); From 7f8f90654dd4c3d84556d7dd7ff30c137c6e3836 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 11 Jan 2026 17:34:20 +0700 Subject: [PATCH 018/152] MDEV-36686: Fix crash with DEFAULT() in WHERE clause with nested views Item_default_value::do_build_clone() was performing a shallow copy, causing the cloned item to share its 'arg' pointer with the original. During condition pushdown for derived tables: 1. build_pushable_cond() cloned the WHERE clause condition 2. grouping_field_transformer_for_where transformed the cloned DEFAULT(a) to reference the inner select's grouping field, modifying the shared 'arg' via change_item_tree() 3. cleanup_excluding_const_fields_processor cleaned up the transformed items, setting Item_field::field = 0 4. The original WHERE clause still referenced the cleaned-up item 5. Crash in Item_field::used_tables() accessing field->table Fix: Make do_build_clone() create a deep clone of 'arg' member, ensuring the cloned Item_default_value has independent state. --- mysql-test/main/derived_cond_pushdown.result | 11 +++++++++++ mysql-test/main/derived_cond_pushdown.test | 15 +++++++++++++++ sql/item.h | 8 +++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 45660c76d21..9048911c431 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -21679,3 +21679,14 @@ a b drop view v1,v2; drop table t1,t2; # End of 10.7 tests +# +# MDEV-36686: Crash with DEFAULT() in WHERE clause with nested views +# +create table t1 (a varchar(128)); +create view v1 as select a, count(*) from t1 group by a; +create view v2 as select * from v1; +select * from v2 where greatest(a, default(a)); +a count(*) +drop view v2, v1; +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 0350ce91c92..653774c5f22 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -4315,3 +4315,18 @@ drop view v1,v2; drop table t1,t2; --echo # End of 10.7 tests + +--echo # +--echo # MDEV-36686: Crash with DEFAULT() in WHERE clause with nested views +--echo # + +create table t1 (a varchar(128)); +create view v1 as select a, count(*) from t1 group by a; +create view v2 as select * from v1; + +select * from v2 where greatest(a, default(a)); + +drop view v2, v1; +drop table t1; + +--echo # End of 10.11 tests diff --git a/sql/item.h b/sql/item.h index 0daa169d9c4..76bcf4f073a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -7087,7 +7087,13 @@ public: new_item->m_share_field= 1; return new_item; } - Item* do_build_clone(THD *thd) const override { return get_copy(thd); } + Item* do_build_clone(THD *thd) const override + { + Item_default_value *copy= (Item_default_value *) get_copy(thd); + if (!copy || (arg && !(copy->arg= arg->build_clone(thd)))) + return NULL; + return copy; + } private: bool tie_field(THD *thd); }; From f304628b2c2373ebdf566460e5ade29054980e1a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 11 Jan 2026 19:21:04 +0400 Subject: [PATCH 019/152] MDEV-38540 - spider/bugfix.perfschema fails sporadically Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying performance_schema.status_by_thread only for connections that it uses. --- storage/spider/mysql-test/spider/bugfix/r/perfschema.result | 4 +++- storage/spider/mysql-test/spider/bugfix/t/perfschema.test | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/storage/spider/mysql-test/spider/bugfix/r/perfschema.result b/storage/spider/mysql-test/spider/bugfix/r/perfschema.result index 9ce2e38f40b..cc63c5bea2a 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/perfschema.result +++ b/storage/spider/mysql-test/spider/bugfix/r/perfschema.result @@ -3,7 +3,9 @@ # connect foo,localhost,root; select variable_name, variable_value from performance_schema.status_by_thread -where variable_name like '%spider_direct_aggregate%'; +inner join performance_schema.threads on status_by_thread.thread_id=threads.thread_id +where variable_name like '%spider_direct_aggregate%' +and processlist_id in ($default_id, connection_id()); variable_name variable_value Spider_direct_aggregate 0 Spider_direct_aggregate 0 diff --git a/storage/spider/mysql-test/spider/bugfix/t/perfschema.test b/storage/spider/mysql-test/spider/bugfix/t/perfschema.test index cb9e5f1ad1d..3ca1eff4132 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/perfschema.test +++ b/storage/spider/mysql-test/spider/bugfix/t/perfschema.test @@ -6,10 +6,14 @@ enable_query_log; --echo # --echo # MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled --echo # +let $default_id= `select connection_id()`; connect foo,localhost,root; --disable_view_protocol +evalp select variable_name, variable_value from performance_schema.status_by_thread -where variable_name like '%spider_direct_aggregate%'; +inner join performance_schema.threads on status_by_thread.thread_id=threads.thread_id +where variable_name like '%spider_direct_aggregate%' +and processlist_id in ($default_id, connection_id()); --enable_view_protocol disconnect foo; connection default; From 0eebe3a98f05bd2a386f4334eafd586ce8b64523 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 11 Jan 2026 16:34:18 +0400 Subject: [PATCH 020/152] MDEV-38539 - compat/oracle.sp-package-mdl fails sporadically Test output was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying information_schema.processlist only for connections that it uses. Avoid ID-CONNECTION_ID() expression, it is not deterministic. --- .../compat/oracle/r/sp-package-mdl.result | 18 ++++++++++-------- .../suite/compat/oracle/t/sp-package-mdl.test | 5 ++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/compat/oracle/r/sp-package-mdl.result b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result index bb46341f202..200493c5cb0 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package-mdl.result +++ b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result @@ -25,46 +25,48 @@ connect conn2,localhost,root,,; SET sql_mode=ORACLE; DROP PACKAGE pkg1; connection default; -SELECT ID-CONNECTION_ID() AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) +WHERE ID IN (CONNECTION_ID(), $conn1_id, $conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE; -CONN 0 -INFO SELECT ID-CONNECTION_ID() AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +CONN default_id +INFO SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) +WHERE ID IN (CONNECTION_ID(), conn1_id, conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE STATE Filling schema table LOCK_MODE MDL_SHARED_NO_WRITE LOCK_TYPE User lock TABLE_NAME -CONN 1 +CONN conn1_id INFO DO GET_LOCK('lock',300) STATE User lock LOCK_MODE MDL_SHARED LOCK_TYPE Stored package body metadata lock TABLE_NAME pkg1 -CONN 1 +CONN conn1_id INFO DO GET_LOCK('lock',300) STATE User lock LOCK_MODE MDL_SHARED LOCK_TYPE Stored function metadata lock TABLE_NAME pkg1.f1 -CONN 1 +CONN conn1_id INFO DO GET_LOCK('lock',300) STATE User lock LOCK_MODE MDL_SHARED LOCK_TYPE Stored procedure metadata lock TABLE_NAME pkg1.p1 -CONN 2 +CONN conn2_id INFO DROP PACKAGE pkg1 STATE Waiting for stored package body metadata lock LOCK_MODE MDL_BACKUP_DDL LOCK_TYPE Backup lock TABLE_NAME -CONN 2 +CONN conn2_id INFO DROP PACKAGE pkg1 STATE Waiting for stored package body metadata lock LOCK_MODE MDL_INTENTION_EXCLUSIVE diff --git a/mysql-test/suite/compat/oracle/t/sp-package-mdl.test b/mysql-test/suite/compat/oracle/t/sp-package-mdl.test index de4f7aaabad..4340febd3fa 100644 --- a/mysql-test/suite/compat/oracle/t/sp-package-mdl.test +++ b/mysql-test/suite/compat/oracle/t/sp-package-mdl.test @@ -85,10 +85,13 @@ WHERE ID=$conn2_id # to DROP the package pkg1 # --vertical_results -SELECT ID-CONNECTION_ID() AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +let $default_id= `SELECT CONNECTION_ID()`; +--replace_result $conn1_id conn1_id $conn2_id conn2_id $default_id default_id +evalp SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) + WHERE ID IN (CONNECTION_ID(), $conn1_id, $conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE; --horizontal_results From 16311b0fb202c01e2bd6fe4ac323397c4e7c4cb7 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 11 Jan 2026 15:08:14 +0400 Subject: [PATCH 021/152] MDEV-38537 - sysschema.pr_ps_setup_show_enabled fails sporadically Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying performance_schema.threads only for connections that it uses. --- mysql-test/suite/sysschema/r/pr_ps_setup_show_enabled.result | 3 ++- mysql-test/suite/sysschema/t/pr_ps_setup_show_enabled.test | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/sysschema/r/pr_ps_setup_show_enabled.result b/mysql-test/suite/sysschema/r/pr_ps_setup_show_enabled.result index 261ccb191ed..bcb94f0650c 100644 --- a/mysql-test/suite/sysschema/r/pr_ps_setup_show_enabled.result +++ b/mysql-test/suite/sysschema/r/pr_ps_setup_show_enabled.result @@ -14,7 +14,8 @@ UPDATE performance_schema.threads SET INSTRUMENTED = 'NO' WHERE NAME LIKE 'thread/innodb/srv\_%' OR NAME LIKE '%con\_%' - OR NAME LIKE '%signal_handler%'; + OR NAME LIKE '%signal_handler%' + OR (NAME='thread/sql/one_connection' AND PROCESSLIST_ID!=CONNECTION_ID()); CALL sys.ps_setup_show_enabled(FALSE, FALSE); performance_schema_enabled 1 diff --git a/mysql-test/suite/sysschema/t/pr_ps_setup_show_enabled.test b/mysql-test/suite/sysschema/t/pr_ps_setup_show_enabled.test index b8ef622b2e9..f9993ed943d 100644 --- a/mysql-test/suite/sysschema/t/pr_ps_setup_show_enabled.test +++ b/mysql-test/suite/sysschema/t/pr_ps_setup_show_enabled.test @@ -26,7 +26,8 @@ UPDATE performance_schema.threads SET INSTRUMENTED = 'NO' WHERE NAME LIKE 'thread/innodb/srv\_%' OR NAME LIKE '%con\_%' - OR NAME LIKE '%signal_handler%'; + OR NAME LIKE '%signal_handler%' + OR (NAME='thread/sql/one_connection' AND PROCESSLIST_ID!=CONNECTION_ID()); # Show limited info (no thread or instrument info) CALL sys.ps_setup_show_enabled(FALSE, FALSE); From 6fe391d2aa2a79fdc183166793189e756d4da44b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 13 Jan 2026 00:58:30 +0400 Subject: [PATCH 022/152] Fixed mtr --embedded compat/oracle.sp-package-mdl Embedded mode produces different thread identifiers, which makes replace_result replace unwanted occurences. Use temporary table for filtering out unwanted threads such that replace_result is not needed anymore. This is regression after 0eebe3a98f0. --- .../suite/compat/oracle/r/sp-package-mdl.result | 13 +++++++++---- .../suite/compat/oracle/t/sp-package-mdl.test | 10 ++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/compat/oracle/r/sp-package-mdl.result b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result index 200493c5cb0..7767f401b9a 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package-mdl.result +++ b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result @@ -25,18 +25,22 @@ connect conn2,localhost,root,,; SET sql_mode=ORACLE; DROP PACKAGE pkg1; connection default; -SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +CREATE TEMPORARY TABLE mythreads(t_id INT UNSIGNED NOT NULL, t_name VARCHAR(16)); +INSERT INTO mythreads VALUES(CONNECTION_ID(), 'default_id'),($conn1_id, 'conn1_id'),($conn2_id, 'conn2_id'); +SELECT t_name AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST +INNER JOIN mythreads +ON (ID=t_id) LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) -WHERE ID IN (CONNECTION_ID(), $conn1_id, $conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE; CONN default_id -INFO SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +INFO SELECT t_name AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST +INNER JOIN mythreads +ON (ID=t_id) LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) -WHERE ID IN (CONNECTION_ID(), conn1_id, conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE STATE Filling schema table LOCK_MODE MDL_SHARED_NO_WRITE @@ -72,6 +76,7 @@ STATE Waiting for stored package body metadata lock LOCK_MODE MDL_INTENTION_EXCLUSIVE LOCK_TYPE Schema metadata lock TABLE_NAME +DROP TABLE mythreads; DO RELEASE_LOCK('lock'); connection conn1; pkg1.f1() diff --git a/mysql-test/suite/compat/oracle/t/sp-package-mdl.test b/mysql-test/suite/compat/oracle/t/sp-package-mdl.test index 4340febd3fa..fc66bbe42a9 100644 --- a/mysql-test/suite/compat/oracle/t/sp-package-mdl.test +++ b/mysql-test/suite/compat/oracle/t/sp-package-mdl.test @@ -84,16 +84,18 @@ WHERE ID=$conn2_id # to acquire an exclusive MDL on 'package body pkg1', # to DROP the package pkg1 # +CREATE TEMPORARY TABLE mythreads(t_id INT UNSIGNED NOT NULL, t_name VARCHAR(16)); +evalp INSERT INTO mythreads VALUES(CONNECTION_ID(), 'default_id'),($conn1_id, 'conn1_id'),($conn2_id, 'conn2_id'); --vertical_results -let $default_id= `SELECT CONNECTION_ID()`; ---replace_result $conn1_id conn1_id $conn2_id conn2_id $default_id default_id -evalp SELECT ID AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +SELECT t_name AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME FROM INFORMATION_SCHEMA.PROCESSLIST + INNER JOIN mythreads + ON (ID=t_id) LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO ON (ID=THREAD_ID) - WHERE ID IN (CONNECTION_ID(), $conn1_id, $conn2_id) ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE; --horizontal_results +DROP TABLE mythreads; # # Now let conn1 finish the package routine execution From e04fcec4bce73687730f5cb07f1796f1565831ad Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 11 Jan 2026 00:02:14 +0400 Subject: [PATCH 023/152] MDEV-10677 - perfschema.threads_mysql fails in buildbot (type=BACKGROUND mismatch) Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying performance_schema.threads only for connections that it uses. --- mysql-test/suite/perfschema/r/threads_mysql.result | 3 +++ mysql-test/suite/perfschema/t/threads_mysql.test | 2 ++ 2 files changed, 5 insertions(+) diff --git a/mysql-test/suite/perfschema/r/threads_mysql.result b/mysql-test/suite/perfschema/r/threads_mysql.result index 20c119da31f..ede4ec51d0c 100644 --- a/mysql-test/suite/perfschema/r/threads_mysql.result +++ b/mysql-test/suite/perfschema/r/threads_mysql.result @@ -6,6 +6,7 @@ AS unified_parent_thread_id, `role`, instrumented FROM performance_schema.threads WHERE name LIKE 'thread/sql%' + AND (name != 'thread/sql/one_connection' OR processlist_id=connection_id()) ORDER BY name; name thread/sql/main type BACKGROUND @@ -42,6 +43,7 @@ AS unified_parent_thread_id, `role`, instrumented FROM performance_schema.threads WHERE name LIKE 'thread/sql%' + AND (name != 'thread/sql/one_connection' OR processlist_id=connection_id()) ORDER BY name connection_type Socket unified_parent_thread_id unified parent_thread_id @@ -114,6 +116,7 @@ FROM performance_schema.threads t1 INNER JOIN performance_schema.threads t2 ON t1.parent_thread_id = t2.thread_id WHERE t1.name LIKE 'thread/sql%' AND t1.parent_thread_id IS NOT NULL +AND (t1.name != 'thread/sql/one_connection' OR t1.processlist_id=connection_id()) ORDER BY parent_thread_name, child_thread_name; parent_thread_name child_thread_name thread/sql/event_scheduler thread/sql/event_worker diff --git a/mysql-test/suite/perfschema/t/threads_mysql.test b/mysql-test/suite/perfschema/t/threads_mysql.test index cf0a1386b5f..45afbd33072 100644 --- a/mysql-test/suite/perfschema/t/threads_mysql.test +++ b/mysql-test/suite/perfschema/t/threads_mysql.test @@ -38,6 +38,7 @@ SELECT name, type, processlist_user, processlist_host, processlist_db, `role`, instrumented FROM performance_schema.threads WHERE name LIKE 'thread/sql%' + AND (name != 'thread/sql/one_connection' OR processlist_id=connection_id()) ORDER BY name; --enable_ps_protocol @@ -110,6 +111,7 @@ FROM performance_schema.threads t1 INNER JOIN performance_schema.threads t2 ON t1.parent_thread_id = t2.thread_id WHERE t1.name LIKE 'thread/sql%' AND t1.parent_thread_id IS NOT NULL + AND (t1.name != 'thread/sql/one_connection' OR t1.processlist_id=connection_id()) ORDER BY parent_thread_name, child_thread_name; # Cleanup From 3d3536358d4432c22485407c6d707b29bf59360d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sat, 10 Jan 2026 19:07:12 +0400 Subject: [PATCH 024/152] MDEV-38534 - perfschema.user_var_func fails sporadically Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying performance_schema.user_variables_by_thread only for connections that it uses. --- mysql-test/suite/perfschema/r/user_var_func.result | 6 ++++++ mysql-test/suite/perfschema/t/user_var_func.test | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/perfschema/r/user_var_func.result b/mysql-test/suite/perfschema/r/user_var_func.result index 82a8e7ec096..9fed4660622 100644 --- a/mysql-test/suite/perfschema/r/user_var_func.result +++ b/mysql-test/suite/perfschema/r/user_var_func.result @@ -7,6 +7,9 @@ select @v1a, @v2a, @v3a, @v4a, @v_unknown; Hello World 65 NULL NULL select VARIABLE_NAME, VARIABLE_VALUE from performance_schema.user_variables_by_thread +inner join performance_schema.threads +on user_variables_by_thread.thread_id=threads.thread_id +where threads.processlist_id=connection_id() order by VARIABLE_NAME; VARIABLE_NAME VARIABLE_VALUE v1a Hello @@ -23,6 +26,9 @@ select @v1b, @v2b, @v3b, @v4b, @v_unknown; Salut La compagnie 12 NULL NULL select VARIABLE_NAME, VARIABLE_VALUE from performance_schema.user_variables_by_thread +inner join performance_schema.threads +on user_variables_by_thread.thread_id=threads.thread_id +where threads.processlist_id in ($default_id, connection_id()) order by VARIABLE_NAME; VARIABLE_NAME VARIABLE_VALUE v1a Hello diff --git a/mysql-test/suite/perfschema/t/user_var_func.test b/mysql-test/suite/perfschema/t/user_var_func.test index 3c9ea4f3cf3..1a4deaa9f2a 100644 --- a/mysql-test/suite/perfschema/t/user_var_func.test +++ b/mysql-test/suite/perfschema/t/user_var_func.test @@ -2,6 +2,8 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +let $default_id= `select connection_id()`; + set @v1a="Hello"; set @v2a="World"; set @v3a=65; @@ -11,6 +13,9 @@ select @v1a, @v2a, @v3a, @v4a, @v_unknown; select VARIABLE_NAME, VARIABLE_VALUE from performance_schema.user_variables_by_thread + inner join performance_schema.threads + on user_variables_by_thread.thread_id=threads.thread_id + where threads.processlist_id=connection_id() order by VARIABLE_NAME; connect(con1, localhost, root,,); @@ -22,8 +27,11 @@ set @v4b=NULL; select @v1b, @v2b, @v3b, @v4b, @v_unknown; -select VARIABLE_NAME, VARIABLE_VALUE +evalp select VARIABLE_NAME, VARIABLE_VALUE from performance_schema.user_variables_by_thread + inner join performance_schema.threads + on user_variables_by_thread.thread_id=threads.thread_id + where threads.processlist_id in ($default_id, connection_id()) order by VARIABLE_NAME; --connection default From 29a986a0247904e026584e3f2ae250c81a1486d5 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sat, 10 Jan 2026 15:10:50 +0400 Subject: [PATCH 025/152] MDEV-38531 - perfschema.statement_digest_consumers2 fails sporadically Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying performance_schema.events_statements_current only for connections that it uses. --- .../suite/perfschema/r/statement_digest_consumers2.result | 5 ++++- .../suite/perfschema/t/statement_digest_consumers2.test | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/perfschema/r/statement_digest_consumers2.result b/mysql-test/suite/perfschema/r/statement_digest_consumers2.result index b59c4f06808..2859d7c2463 100644 --- a/mysql-test/suite/perfschema/r/statement_digest_consumers2.result +++ b/mysql-test/suite/perfschema/r/statement_digest_consumers2.result @@ -128,7 +128,10 @@ DROP TRIGGER trg; #################################### SELECT schema_name, digest, digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; schema_name digest digest_text count_star -SELECT digest, digest_text FROM performance_schema.events_statements_current; +SELECT digest, digest_text FROM performance_schema.events_statements_current +INNER JOIN performance_schema.threads +ON events_statements_current.thread_id=threads.thread_id +WHERE threads.processlist_id=connection_id(); digest digest_text NULL NULL #################################### diff --git a/mysql-test/suite/perfschema/t/statement_digest_consumers2.test b/mysql-test/suite/perfschema/t/statement_digest_consumers2.test index 98442349927..ad7838e3cc3 100644 --- a/mysql-test/suite/perfschema/t/statement_digest_consumers2.test +++ b/mysql-test/suite/perfschema/t/statement_digest_consumers2.test @@ -31,7 +31,10 @@ TRUNCATE TABLE performance_schema.events_statements_summary_by_digest; --echo # QUERYING PS STATEMENT DIGEST --echo #################################### SELECT schema_name, digest, digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; -SELECT digest, digest_text FROM performance_schema.events_statements_current; +SELECT digest, digest_text FROM performance_schema.events_statements_current + INNER JOIN performance_schema.threads + ON events_statements_current.thread_id=threads.thread_id + WHERE threads.processlist_id=connection_id(); # Cleanup for Digest --source ../include/digest_cleanup.inc From 9446b9178844e5ef291a181e2778b8f525a043d5 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 11 Jan 2026 00:10:01 +0100 Subject: [PATCH 026/152] MDEV-38498 mariadb-dump -dir doesn't convert database names Similar to MDEV-37483, use file name encoding for dbnames to create directories. Adapt mariadb-import to convert the names back. --- client/mysqldump.cc | 38 +++++++++----- client/mysqlimport.cc | 73 ++++++++++++++++++--------- mysql-test/main/mariadb-import.result | 36 +++++++++++++ mysql-test/main/mariadb-import.test | 40 +++++++++++++++ 4 files changed, 150 insertions(+), 37 deletions(-) diff --git a/client/mysqldump.cc b/client/mysqldump.cc index 26fa2751536..a9c8aa59449 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -1943,21 +1943,35 @@ static char *cover_definer_clause(const char *stmt_str, } +static char *format_fs_safe_filename(const char *from, char *to, size_t to_size) +{ + if (check_if_legal_tablename(from)) + strxnmov(to, to_size - 1, from , "@@@", NULL); + else + { + uint errors, len; + len= my_convert(to, (uint32)(to_size - 1), &my_charset_filename, + from, (uint32) strlen(from), charset_info, &errors); + to[len]= 0; + } + return to; +} + +static void format_fs_safe_output_dir(const char *db, char *out_dir, size_t out_size) +{ + DBUG_ASSERT(opt_dir); + char fs_safe_db[FN_REFLEN]; + format_fs_safe_filename(db, fs_safe_db, sizeof(fs_safe_db)); + my_snprintf(out_dir, out_size, "%s/%s", opt_dir, fs_safe_db); +} + static const char* build_path_for_table(char *to, const char *dir, const char *table, const char *ext) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; convert_dirname(tmp_path, dir, NULL); my_load_path(tmp_path, tmp_path, NULL); - if (check_if_legal_tablename(table)) - strxnmov(filename, sizeof(filename) - 1, table, "@@@", NULL); - else - { - uint errors, len; - len= my_convert(filename, sizeof(filename) - 1, &my_charset_filename, - table, (uint32)strlen(table), charset_info, &errors); - filename[len]= 0; - } + format_fs_safe_filename(table, filename, sizeof(filename)); return fn_format(to, filename, tmp_path, ext, MYF(MY_UNPACK_FILENAME)); } @@ -1984,7 +1998,7 @@ static FILE* open_sql_file_for_table(const char *db, const char* table, int flag if (opt_dir) { out_dir= out_dir_buf; - my_snprintf(out_dir_buf, sizeof(out_dir_buf), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, out_dir_buf, sizeof(out_dir_buf)); } res= my_fopen(build_path_for_table(filename, out_dir, table, ".sql"), @@ -4314,7 +4328,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, char *out_dir= path; if (!out_dir) { - my_snprintf(out_dir_buf, sizeof(out_dir_buf), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, out_dir_buf, sizeof(out_dir_buf)); out_dir= out_dir_buf; } @@ -7390,7 +7404,7 @@ static void ensure_out_dir_exists(const char *db) { DBUG_ASSERT(opt_dir); char outdir[FN_REFLEN]; - my_snprintf(outdir, sizeof(outdir), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, outdir, sizeof(outdir)); struct stat st; if (stat(outdir, &st) == 0) { diff --git a/client/mysqlimport.cc b/client/mysqlimport.cc index 0a50f2dabe2..d19e6696110 100644 --- a/client/mysqlimport.cc +++ b/client/mysqlimport.cc @@ -50,7 +50,7 @@ static std::vector all_tp_connections; std::atomic aborting{false}; static void kill_tp_connections(MYSQL *mysql); -static void db_error_with_table(MYSQL *mysql, char *table); +static void db_error_with_table(MYSQL *mysql, const char *table); static void db_error(MYSQL *mysql); static char *field_escape(char *to,const char *from,uint length); static char *add_load_option(char *ptr,const char *object, @@ -82,12 +82,36 @@ static char **argv_to_free; static void safe_exit(int error, MYSQL *mysql); static void set_exitcode(int code); +/* + Try to convert from filesystem-safe name escaping to string + in default character set. + + @param name Name to unescape + @param buf Buffer to store result + @param sz Size of buffer + @return length of result string, or 0 on error or decodin + not needed +*/ +static uint decode_fs_safe_name(const char *name, char *buf, size_t sz) +{ + if (!strchr(name, '@')) + return 0; + uint errors, len; + len= my_convert(buf, (uint32)(sz - 1), default_charset_info, name, (uint32) strlen(name), + &my_charset_filename, &errors); + if (errors || !len) + return 0; + buf[len]= 0; + return len; +} + struct table_load_params { std::string data_file; /* name of the file to load with LOAD DATA INFILE */ std::string sql_file; /* name of the file that contains CREATE TABLE or CREATE VIEW */ std::string dbname; /* name of the database */ + std::string tablename; /* name of the table */ bool tz_utc= false; /* true if the script sets the timezone to UTC */ bool is_view= false; /* true if the script is for a VIEW */ std::vector triggers; /* CREATE TRIGGER statements */ @@ -98,12 +122,21 @@ struct table_load_params table_load_params(const char* dfile, const char* sqlfile, const char* db, ulonglong data_size) : data_file(dfile), sql_file(sqlfile), - dbname(db), triggers(), + triggers(), size(data_size), sql_text(parse_sql_script(sqlfile, &tz_utc, &triggers)), ddl_info(sql_text) { is_view= ddl_info.table_name.empty(); + /* Convert dbname from FS safe encoding if needed. */ + char decoded_name[FN_REFLEN]; + uint len= decode_fs_safe_name(db, decoded_name, sizeof(decoded_name)); + dbname= len ? std::string(decoded_name, len) : std::string(db); + + char raw_tblname[FN_REFLEN]; + fn_format(raw_tblname, dfile, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + len= decode_fs_safe_name(raw_tblname, decoded_name, sizeof(decoded_name)); + tablename= len ? std::string(decoded_name, len) : std::string(raw_tblname); } int create_table_or_view(MYSQL *); int load_data(MYSQL *); @@ -646,7 +679,7 @@ int table_load_params::create_table_or_view(MYSQL* mysql) int table_load_params::load_data(MYSQL *mysql) { - char tablename[FN_REFLEN], hard_path[FN_REFLEN], + char hard_path[FN_REFLEN], escaped_name[FN_REFLEN * 2 + 1], sql_statement[FN_REFLEN*16+256], *end; DBUG_ENTER("table_load_params::load"); @@ -666,23 +699,10 @@ int table_load_params::load_data(MYSQL *mysql) } const char *filename= data_file.c_str(); - - fn_format(tablename, filename, "", "", MYF(MY_REPLACE_DIR | MY_REPLACE_EXT)); - if (strchr(tablename, '@')) - { - uint errors, len; - CHARSET_INFO *cs= - get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(0)); - len= my_convert(escaped_name, sizeof(escaped_name) - 1, cs, tablename, - (uint32)strlen(tablename), &my_charset_filename, &errors); - if (!errors) - strmake(tablename, escaped_name, len); - } - const char *db= current_db ? current_db : dbname.c_str(); std::string full_tablename= quote_identifier(db); full_tablename+= "."; - full_tablename+= quote_identifier(tablename); + full_tablename+= quote_identifier(tablename.c_str()); if (tz_utc && exec_sql(mysql, "SET TIME_ZONE='+00:00';")) DBUG_RETURN(1); @@ -698,7 +718,7 @@ int table_load_params::load_data(MYSQL *mysql) if (opt_delete) { if (verbose) - fprintf(stdout, "Deleting the old data from table %s\n", tablename); + fprintf(stdout, "Deleting the old data from table %s\n", tablename.c_str()); snprintf(sql_statement, FN_REFLEN * 16 + 256, "DELETE FROM %s", full_tablename.c_str()); if (exec_sql(mysql, sql_statement)) @@ -723,7 +743,7 @@ int table_load_params::load_data(MYSQL *mysql) if (verbose) { fprintf(stdout, "Loading data from %s file: %s into %s\n", - (opt_local_file) ? "LOCAL" : "SERVER", hard_path, tablename); + (opt_local_file) ? "LOCAL" : "SERVER", hard_path, tablename.c_str()); } mysql_real_escape_string(mysql, escaped_name, hard_path, (unsigned long) strlen(hard_path)); @@ -757,14 +777,14 @@ int table_load_params::load_data(MYSQL *mysql) if (mysql_query(mysql, sql_statement)) { - db_error_with_table(mysql, tablename); + db_error_with_table(mysql, tablename.c_str()); DBUG_RETURN(1); } if (!silent) { const char *info= mysql_info(mysql); if (info) /* If NULL-pointer, print nothing */ - fprintf(stdout, "%s.%s: %s\n", db, tablename, info); + fprintf(stdout, "%s.%s: %s\n", db, tablename.c_str(), info); } @@ -879,9 +899,6 @@ static MYSQL *db_connect(char *host, char *database, if (opt_default_auth && *opt_default_auth) mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); - if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME)) - default_charset= (char *)my_default_csname(); - my_set_console_cp(default_charset); mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0); mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, @@ -971,7 +988,7 @@ static void safe_exit(int error, MYSQL *mysql) -static void db_error_with_table(MYSQL *mysql, char *table) +static void db_error_with_table(MYSQL *mysql, const char *table) { if (aborting) return; @@ -1273,6 +1290,12 @@ int main(int argc, char **argv) free_defaults(argv_to_free); return(1); } + + if (!strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME)) + default_charset= (char *) my_default_csname(); + my_set_console_cp(default_charset); + default_charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, 0); + if (opt_use_threads > MAX_THREADS) { fatal_error("Too many connections, max value for --parallel is %d\n", diff --git a/mysql-test/main/mariadb-import.result b/mysql-test/main/mariadb-import.result index 691952b7a7d..283d06953aa 100644 --- a/mysql-test/main/mariadb-import.result +++ b/mysql-test/main/mariadb-import.result @@ -387,3 +387,39 @@ use test; mariadb-import: Path 'MYSQLTEST_VARDIR/tmp/non_existing' specified by option '--dir' does not exist # Test too many threads, builtin limit 256 Too many connections, max value for --parallel is 256 +# MDEV-37483 mariadb-dump --dir doesn't convert db names +create database `con_schöne_grüße`; +create table `con_schöne_grüße`.t(a int) select 1 as a; +create database `com1`; +create table `com1`.t(b int) select 2 as b; +create database `con/bar`; +create table `con/bar`.t select 3 as c; +create database `con@fame`; +create table `con@fame`.t (d int) select 4 as d; +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; +com1@@@ +con@002fbar +con@fame +con_sch@0j@00b6ne_gr@0j@00bc@0j@1re +# +# Check if expected tables were correctly restored +# +select * from `con_schöne_grüße`.t; +a +1 +select * from `com1`.t; +b +2 +select * from `con/bar`.t; +c +3 +select * from `con@fame`.t; +d +4 +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; diff --git a/mysql-test/main/mariadb-import.test b/mysql-test/main/mariadb-import.test index 29d7ed7f2f3..c3d967218b6 100644 --- a/mysql-test/main/mariadb-import.test +++ b/mysql-test/main/mariadb-import.test @@ -235,3 +235,43 @@ use test; --exec $MYSQL_IMPORT --dir $MYSQLTEST_VARDIR/tmp/dump --parallel=300 2>&1 --rmdir $MYSQLTEST_VARDIR/tmp/dump + +--echo # MDEV-37483 mariadb-dump --dir doesn't convert db names + +create database `con_schöne_grüße`; +create table `con_schöne_grüße`.t(a int) select 1 as a; +create database `com1`; +create table `com1`.t(b int) select 2 as b; +create database `con/bar`; +create table `con/bar`.t select 3 as c; +create database `con@fame`; +create table `con@fame`.t (d int) select 4 as d; + +--mkdir $MYSQLTEST_VARDIR/tmp/dump +--exec $MYSQL_DUMP --dir=$MYSQLTEST_VARDIR/tmp/dump --all-databases + +--move_file $MYSQLTEST_VARDIR/tmp/dump/con@0040fame $MYSQLTEST_VARDIR/tmp/dump/con@fame + +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; + +--exec $MYSQL_IMPORT --dir $MYSQLTEST_VARDIR/tmp/dump --silent + +--lowercase_result +--list_files $MYSQLTEST_VARDIR/tmp/dump co* + +--echo # +--echo # Check if expected tables were correctly restored +--echo # + +select * from `con_schöne_grüße`.t; +select * from `com1`.t; +select * from `con/bar`.t; +select * from `con@fame`.t; + +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; From 33413c631898ecfc97abd51e272330feca55bf03 Mon Sep 17 00:00:00 2001 From: gkodinov Date: Tue, 13 Jan 2026 11:09:02 +0200 Subject: [PATCH 027/152] MDEV-38499: cmake and bison warnings on MacOSX when compiling mariadb from a git tree Problems: 1. bison incorrectly issues a warning when it sees "b4_bin" 2. MacOSX linker issues a warning about duplicate mysys/dbug/etc libraries. On 1: worked around by adding a compiler define with a different name aliasing the character set variable used with a name that won't trigger the bison warning On 2: This is due to the fact that there's a circular dependency between mysys and dbug (among others). Turned the warning off by adding a compiler option to be applied to targets lined with mysys to turn the warning off. --- mysys/CMakeLists.txt | 14 ++++++++++++++ sql/sql_parse.h | 14 ++++++++++++++ sql/sql_yacc.yy | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 0253d4471da..bf011844ab1 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -179,6 +179,20 @@ IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=") TARGET_LINK_LIBRARIES(mysys pthread) ENDIF() +# This is a workaround for the warning about duplicate libraries on macOS. +# The issue is as follows: mysys depends on dbug and dbug depends on mysys. +# This causes cmake to append dbug twice when you append mysys as a library. +# And you get a warning from the MacOSX linker. +# TODO: to remove the circular dependency and this workaround. +include(CheckLinkerFlag) +IF(APPLE AND (CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")) + CHECK_LINKER_FLAG(C "LINKER:-no_warn_duplicate_libraries" HAVE_NO_WARN_DUPLICATE_LIBRARIES) + IF(HAVE_NO_WARN_DUPLICATE_LIBRARIES) + TARGET_LINK_OPTIONS(mysys INTERFACE LINKER:-no_warn_duplicate_libraries) + ENDIF() +ENDIF() + + ADD_EXECUTABLE(thr_lock thr_lock.c) TARGET_LINK_LIBRARIES(thr_lock mysys) SET_TARGET_PROPERTIES(thr_lock PROPERTIES COMPILE_FLAGS "-DMAIN") diff --git a/sql/sql_parse.h b/sql/sql_parse.h index ebe3fe97114..0d73f6e2c0b 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -191,4 +191,18 @@ check_table_access(THD *thd, privilege_t requirements,TABLE_LIST *tables, { return false; } #endif /*NO_EMBEDDED_ACCESS_CHECKS*/ +/** + Due to an issue with the bison parser, we need to use a different name. + + This is a workaround! + + If we use the global charset variable name we get a warning in the bison + parser stderr : suspicious sequence in the output: b4_bin [-Wother] + So we work around by having this define that doesn't have 'b4_bin' in it. + + This has been reported, but not fixed yet: + https://lists.gnu.org/archive/html/bug-bison/2021-10/msg00027.html +*/ +#define MY_CHARSET_UTF8MB4_BIN my_charset_utf8mb4_bin + #endif /* SQL_PARSE_INCLUDED */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4ad2d62a415..ae132ce0ead 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6595,7 +6595,7 @@ field_type_lob: { $$.set(&type_handler_medium_blob); } | JSON_SYM opt_compressed { - Lex->charset= &my_charset_utf8mb4_bin; + Lex->charset= &MY_CHARSET_UTF8MB4_BIN; $$.set(&type_handler_long_blob_json); } ; From 4de773e90cc8ff5a38e5585780643bdcb986f515 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 29 Dec 2025 18:03:23 +0400 Subject: [PATCH 028/152] 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. --- .../compat/oracle/r/sp-package-code.result | 30 ++++++++++++ .../compat/oracle/t/sp-package-code.test | 30 ++++++++++++ sql/sql_class.h | 2 + sql/sql_cmd.h | 34 +++++++++++++ sql/sql_lex.cc | 21 ++++++++ sql/sql_lex.h | 1 + sql/sql_parse.cc | 49 ++++++++----------- sql/sql_yacc.yy | 18 ++++--- 8 files changed, 149 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/compat/oracle/r/sp-package-code.result b/mysql-test/suite/compat/oracle/r/sp-package-code.result index 0dea72dba89..2a1c44c27e4 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package-code.result +++ b/mysql-test/suite/compat/oracle/r/sp-package-code.result @@ -243,3 +243,33 @@ Pos Instruction 7 jump 11 DROP PACKAGE pkg1; DROP TABLE t1; +# Start of 10.11 tests +# +# MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution +# +CREATE PACKAGE pkg1 AS +PROCEDURE p1(); +END; +$$ +CREATE PACKAGE BODY pkg1 AS +FUNCTION f1() RETURN INT AS +BEGIN +RETURN 10; +END; +PROCEDURE p1() AS +BEGIN +SHOW FUNCTION CODE f1; +END; +END; +$$ +CALL pkg1.p1; +Pos Instruction +0 freturn int 10 +CALL pkg1.p1; +Pos Instruction +0 freturn int 10 +CALL pkg1.p1; +Pos Instruction +0 freturn int 10 +DROP PACKAGE pkg1; +# End of 10.11 tests diff --git a/mysql-test/suite/compat/oracle/t/sp-package-code.test b/mysql-test/suite/compat/oracle/t/sp-package-code.test index 9cca53964ec..659e3d43367 100644 --- a/mysql-test/suite/compat/oracle/t/sp-package-code.test +++ b/mysql-test/suite/compat/oracle/t/sp-package-code.test @@ -180,3 +180,33 @@ SHOW PROCEDURE CODE pkg1.p1; SHOW PACKAGE BODY CODE pkg1; DROP PACKAGE pkg1; DROP TABLE t1; + +--echo # Start of 10.11 tests + +--echo # +--echo # MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution +--echo # + +DELIMITER $$; +CREATE PACKAGE pkg1 AS + PROCEDURE p1(); +END; +$$ +CREATE PACKAGE BODY pkg1 AS + FUNCTION f1() RETURN INT AS + BEGIN + RETURN 10; + END; + PROCEDURE p1() AS + BEGIN + SHOW FUNCTION CODE f1; + END; +END; +$$ +DELIMITER ;$$ +CALL pkg1.p1; +CALL pkg1.p1; +CALL pkg1.p1; +DROP PACKAGE pkg1; + +--echo # End of 10.11 tests diff --git a/sql/sql_class.h b/sql/sql_class.h index d3c50df01f0..aa78312c3b6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -8120,6 +8120,8 @@ class Database_qualified_name public: LEX_CSTRING m_db; LEX_CSTRING m_name; + Database_qualified_name() + { } Database_qualified_name(const LEX_CSTRING *db, const LEX_CSTRING *name) :m_db(*db), m_name(*name) { } diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index f94ffee2f9f..8bf6b9f99fa 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -180,4 +180,38 @@ public: } }; + +#ifndef DBUG_OFF +/** + Sql_cmd_call represents the SHOW CODE statement: + - SHOW PROCEDURE CODE + - SHOW FUNCTION CODE + - SHOW PACKAGE BODY CODE +*/ +class Sql_cmd_show_routine_code : public Sql_cmd +{ +public: + class sp_name *m_name; + const class Sp_handler *m_handler; + enum_sql_command m_sql_command; + Sql_cmd_show_routine_code(class sp_name *name, + const class Sp_handler *handler, + enum_sql_command sql_command) + :m_name(name), + m_handler(handler), + m_sql_command(sql_command) + {} + + virtual ~Sql_cmd_show_routine_code() = default; + + bool execute(THD *thd) override; + + enum_sql_command sql_command_code() const override + { + return m_sql_command; + } +}; +#endif // DBUG_OFF + + #endif // SQL_CMD_INCLUDED diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 15391c37e6b..d31620324a6 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9390,6 +9390,27 @@ bool LEX::add_create_view(THD *thd, DDL_options_st ddl, } +bool LEX::show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name) +{ +#ifdef DBUG_OFF + my_error(ER_FEATURE_DISABLED, MYF(0), + "SHOW PROCEDURE|FUNCTION CODE", "--with-debug"); + return true; +#else + sql_command= cmd; + Database_qualified_name pkgname; + const Sp_handler *sph= Sp_handler::handler(cmd); + if (sph->sp_resolve_package_routine(thd, thd->lex->sphead, + name, &sph, &pkgname)) + return true; + if (!(m_sql_cmd= new (thd->mem_root) Sql_cmd_show_routine_code(name, sph, + cmd))) + return true; + return false; +#endif +} + + bool LEX::call_statement_start(THD *thd, sp_name *name) { Database_qualified_name pkgname(&null_clex_str, &null_clex_str); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 490ba9df6ce..700cd18ae2b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3971,6 +3971,7 @@ public: const sp_name *name, const sp_name *name2, const char *cpp_body_end); + bool show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name); bool call_statement_start(THD *thd, sp_name *name); bool call_statement_start(THD *thd, const Lex_ident_sys_st *name); bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a87becfc6f5..0523fc492e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3288,6 +3288,24 @@ static bool prepare_db_action(THD *thd, privilege_t want_access, } +#ifndef DBUG_OFF +bool Sql_cmd_show_routine_code::execute(THD *thd) +{ + sp_head *sp; + if (m_handler->sp_cache_routine(thd, m_name, &sp)) + return true; + if (!sp || sp->show_routine_code(thd)) + { + /* We don't distinguish between errors for now */ + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + m_handler->type_str(), m_name->m_name.str); + return true; + } + return false; +} +#endif // DBUG_OFF + + bool Sql_cmd_call::execute(THD *thd) { TABLE_LIST *all_tables= thd->lex->query_tables; @@ -5967,34 +5985,6 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) goto error; break; } - case SQLCOM_SHOW_PROC_CODE: - case SQLCOM_SHOW_FUNC_CODE: - case SQLCOM_SHOW_PACKAGE_BODY_CODE: - { -#ifndef DBUG_OFF - Database_qualified_name pkgname(&null_clex_str, &null_clex_str); - sp_head *sp; - const Sp_handler *sph= Sp_handler::handler(lex->sql_command); - WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); - if (sph->sp_resolve_package_routine(thd, thd->lex->sphead, - lex->spname, &sph, &pkgname)) - return true; - if (sph->sp_cache_routine(thd, lex->spname, &sp)) - goto error; - if (!sp || sp->show_routine_code(thd)) - { - /* We don't distinguish between errors for now */ - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - sph->type_str(), lex->spname->m_name.str); - goto error; - } - break; -#else - my_error(ER_FEATURE_DISABLED, MYF(0), - "SHOW PROCEDURE|FUNCTION CODE", "--with-debug"); - goto error; -#endif // ifndef DBUG_OFF - } case SQLCOM_SHOW_CREATE_TRIGGER: { if (check_ident_length(&lex->spname->m_name)) @@ -6199,6 +6189,9 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) case SQLCOM_SIGNAL: case SQLCOM_RESIGNAL: case SQLCOM_GET_DIAGNOSTICS: + case SQLCOM_SHOW_PROC_CODE: + case SQLCOM_SHOW_FUNC_CODE: + case SQLCOM_SHOW_PACKAGE_BODY_CODE: case SQLCOM_CALL: case SQLCOM_REVOKE: case SQLCOM_GRANT: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 61f22eb7d16..3517fed44d6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14024,23 +14024,25 @@ show_param: } | PROCEDURE_SYM CODE_SYM sp_name { - Lex->sql_command= SQLCOM_SHOW_PROC_CODE; - Lex->spname= $3; + if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PROC_CODE, $3)) + MYSQL_YYABORT; } | FUNCTION_SYM CODE_SYM sp_name { - Lex->sql_command= SQLCOM_SHOW_FUNC_CODE; - Lex->spname= $3; + if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_FUNC_CODE, $3)) + MYSQL_YYABORT; } | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM CODE_SYM sp_name { - Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE; - Lex->spname= $4; + if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE, + $4)) + MYSQL_YYABORT; } | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM CODE_SYM sp_name { - Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE; - Lex->spname= $4; + if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE, + $4)) + MYSQL_YYABORT; } | CREATE EVENT_SYM sp_name { From 01ff5ae6b677bead4c41d91bf5afb25c593a1d02 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 13 Jan 2026 12:11:18 +1100 Subject: [PATCH 029/152] Deb: prep work - duke=Debian 15, resolute=Ubuntu 26.04 --- debian/autobake-deb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 0e11a98f830..81d81dfb5e2 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -109,7 +109,7 @@ in remove_uring fi ;& - "trixie"|"forky"|"sid") + "trixie"|"forky"|"duke"|"sid") # The default packaging should always target Debian Sid, so in this case # there is intentionally no customizations whatsoever. ;; @@ -128,7 +128,7 @@ in replace_uring_with_aio fi ;& - "noble"|"oracular"|"plucky"|"questing") + "noble"|"oracular"|"plucky"|"questing"|"resolute") # mariadb-plugin-rocksdb s390x not supported by us (yet) # ubuntu doesn't support mips64el yet, so keep this just # in case something changes. From fafa57b12bf362d80afe0edbd40070ebbc537c26 Mon Sep 17 00:00:00 2001 From: gkodinov Date: Wed, 14 Jan 2026 10:29:54 +0200 Subject: [PATCH 030/152] Follow up for MDEV-384999: fix cmake warnings: Moved the include inside the check for cmake version so that it doesn't fail on older cmake's. --- mysys/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index bf011844ab1..515414c553a 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -184,8 +184,8 @@ ENDIF() # This causes cmake to append dbug twice when you append mysys as a library. # And you get a warning from the MacOSX linker. # TODO: to remove the circular dependency and this workaround. -include(CheckLinkerFlag) IF(APPLE AND (CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")) + include(CheckLinkerFlag) CHECK_LINKER_FLAG(C "LINKER:-no_warn_duplicate_libraries" HAVE_NO_WARN_DUPLICATE_LIBRARIES) IF(HAVE_NO_WARN_DUPLICATE_LIBRARIES) TARGET_LINK_OPTIONS(mysys INTERFACE LINKER:-no_warn_duplicate_libraries) From 87757223e994869afb8a5f51c7a4ef045f386f6b Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 28 Jan 2019 00:26:23 +0100 Subject: [PATCH 031/152] MDEV-35904/MDEV-19210: use environment file in systemd units for _WSREP_START_POSITION MDEV-35904 - backport MDEV-19210 to 10.11 as referenced by unset environment variables become warnings. We used to run `systemctl set-environment` to pass _WSREP_START_POSITION. This is bad because: * it clutter systemd's environment (yes, pid 1) * it requires root privileges * options (like LimitNOFILE=) are not applied Let's just create an environment file in ExecStartPre=, that is read before ExecStart= kicks in. We have _WSREP_START_POSITION around for the main process without any downsides. --- support-files/CMakeLists.txt | 2 ++ support-files/mariadb.service.in | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index f4cc5f265a5..1ed10fd8037 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -32,6 +32,8 @@ ELSE() SET(MYSQLD_GROUP "mysql") SET(ini_file_extension "cnf") SET(HOSTNAME "uname -n") + get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY) + SET(mysqlunixdir ${MYSQL_UNIX_DIR}) ENDIF() # XXX: shouldn't we just have variables for all this stuff and centralise diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 547fc1732fa..8f21bd32369 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -69,17 +69,23 @@ ProtectHome=true # Execute pre and post scripts as root, otherwise it does it as User= PermissionsStartOnly=true +# Use an environment file to pass variable _WSREP_NEW_CLUSTER +EnvironmentFile=-@mysqlunixdir@/wsrep-new-cluster + +# Use an environment file to pass variable _WSREP_START_POSITION +EnvironmentFile=-@mysqlunixdir@/wsrep-start-position + @SYSTEMD_EXECSTARTPRE@ # Perform automatic wsrep recovery. When server is started without wsrep, # galera_recovery simply returns an empty string. In any case, however, # the script is not expected to return with a non-zero status. -# It is always safe to unset _WSREP_START_POSITION environment variable. +# It is always safe to remove @mysqlunixdir@/wsrep-start-position +# environment file. # Do not panic if galera_recovery script is not available. (MDEV-10538) -ExecStartPre=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION" ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ VAR=`@bindir@/galera_recovery`; [ $? -eq 0 ] \ - && systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1" + && echo _WSREP_START_POSITION=$VAR > @mysqlunixdir@/wsrep-start-position || exit 1" # Needed to create system tables etc. # ExecStartPre=@scriptdir@/mysql_install_db -u mysql @@ -92,7 +98,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ ExecStart=@sbindir@/mariadbd $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION # Unset _WSREP_START_POSITION environment variable. -ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION" +ExecStartPost=/bin/rm -f @mysqlunixdir@/wsrep-start-position @SYSTEMD_EXECSTARTPOST@ From 4b5e6846066a5bd53b72688a7dc881bfa103e2c3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 25 Sep 2025 07:05:01 +1000 Subject: [PATCH 032/152] MDEV-37726 wsrep-new-cluster and wsrep-start-position in wrong directory with wrong selinux permissions After moving the systemd service to using environment files instead of `systemctl set-environment` in 11.6 (MDEV-19210), they (wsrep-new-cluster and wsrep-start-position) are located in /var/lib/mysql along with the socket file in Fedora/RHEL-based distros. This causes them to have incorrect selinux permissions and therefore be not readable by systemd. A solution is to generate these files in the run directory, instead, which already has correct selinux label mysqld_var_run_t mysql-selinux-1.0.12. Dissociating these files and the socket in CMake configs can also prove useful for other things. This also corrects some of the duplicate code in the build scripts and made INSTALL_RUNDATADIR into a proper location and used this for the tmpfiles where the temporary files are created. Debian's location is /run/mysqld/ matching its INSTALL_UNIX_ADDRDIR, which is now a temporary location controlled by tmpfiles. --- cmake/install_layout.cmake | 8 +++++++- scripts/galera_new_cluster.sh | 6 +++--- support-files/CMakeLists.txt | 9 +++++---- support-files/mariadb.service.in | 12 ++++++------ support-files/tmpfiles.conf.in | 16 +++++++++++++++- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 877b147bc6e..9410bc7a48a 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -163,6 +163,7 @@ SET(INSTALL_UNIX_ADDRDIR_RPM "${INSTALL_MYSQLDATADIR_RPM}/mysql.sock" SET(INSTALL_SYSTEMD_UNITDIR_RPM "/usr/lib/systemd/system") SET(INSTALL_SYSTEMD_SYSUSERSDIR_RPM "/usr/lib/sysusers.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d") +SET(INSTALL_RUNDATADIR_RPM "/run/mariadb") SET(INSTALL_PAMDIR_RPM "/${INSTALL_LIBDIR_RPM}/security") SET(INSTALL_PAMDATADIR_RPM "/etc/security") @@ -193,7 +194,8 @@ SET(INSTALL_SUPPORTFILESDIR_DEB "share/mysql") # SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql") -SET(INSTALL_UNIX_ADDRDIR_DEB "/run/mysqld/mysqld.sock") +SET(INSTALL_RUNDATADIR_DEB "/run/mysqld") +SET(INSTALL_UNIX_ADDRDIR_DEB "${INSTALL_RUNDATADIR_DEB}/mysqld.sock") SET(INSTALL_SYSTEMD_UNITDIR_DEB "/lib/systemd/system") SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d") @@ -257,3 +259,7 @@ IF(NOT MYSQL_UNIX_ADDR) SET(MYSQL_UNIX_ADDR ${INSTALL_UNIX_ADDRDIR}) ENDIF() +IF(NOT INSTALL_RUNDATADIR) + get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY) + SET(INSTALL_RUNDATADIR "${MYSQL_UNIX_DIR}" CACHE FILEPATH "Rundata installation directory" ${FORCE}) +ENDIF() diff --git a/scripts/galera_new_cluster.sh b/scripts/galera_new_cluster.sh index ac9dcf42102..b0aef8e05d2 100755 --- a/scripts/galera_new_cluster.sh +++ b/scripts/galera_new_cluster.sh @@ -21,11 +21,11 @@ EOF exit 0 fi -systemctl set-environment _WSREP_NEW_CLUSTER='--wsrep-new-cluster' && \ - systemctl restart ${1:-mariadb} +echo _WSREP_NEW_CLUSTER='--wsrep-new-cluster' > "@INSTALL_RUNDATADIR@/wsrep-new-cluster" && \ + systemctl restart mariadb.service extcode=$? -systemctl set-environment _WSREP_NEW_CLUSTER='' +rm -f "@INSTALL_RUNDATADIR@/wsrep-new-cluster" exit $extcode diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 1ed10fd8037..9d947943bbf 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -32,8 +32,6 @@ ELSE() SET(MYSQLD_GROUP "mysql") SET(ini_file_extension "cnf") SET(HOSTNAME "uname -n") - get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY) - SET(mysqlunixdir ${MYSQL_UNIX_DIR}) ENDIF() # XXX: shouldn't we just have variables for all this stuff and centralise @@ -199,8 +197,11 @@ IF(UNIX AND NOT WITHOUT_SERVER) RENAME mariadb.conf COMPONENT Server) ENDIF() - IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_TMPUSERS) AND INSTALL_SYSTEMD_TMPFILESDIR) - get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY) + IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_TMPUSERS) AND INSTALL_SYSTEMD_TMPFILESDIR + AND INSTALL_RUNDATADIR) + IF(MYSQL_DATADIR STREQUAL INSTALL_RUNDATADIR) + SET(DISABLE_TMP "#") + ENDIF() CONFIGURE_FILE(tmpfiles.conf.in ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 8f21bd32369..2dc90af83c5 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -70,22 +70,22 @@ ProtectHome=true PermissionsStartOnly=true # Use an environment file to pass variable _WSREP_NEW_CLUSTER -EnvironmentFile=-@mysqlunixdir@/wsrep-new-cluster +EnvironmentFile=-@INSTALL_RUNDATADIR@/wsrep-new-cluster # Use an environment file to pass variable _WSREP_START_POSITION -EnvironmentFile=-@mysqlunixdir@/wsrep-start-position +EnvironmentFile=-@INSTALL_RUNDATADIR@/wsrep-start-position @SYSTEMD_EXECSTARTPRE@ # Perform automatic wsrep recovery. When server is started without wsrep, # galera_recovery simply returns an empty string. In any case, however, # the script is not expected to return with a non-zero status. -# It is always safe to remove @mysqlunixdir@/wsrep-start-position +# It is always safe to remove @INSTALL_RUNDATADIR@/wsrep-start-position # environment file. # Do not panic if galera_recovery script is not available. (MDEV-10538) ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ VAR=`@bindir@/galera_recovery`; [ $? -eq 0 ] \ - && echo _WSREP_START_POSITION=$VAR > @mysqlunixdir@/wsrep-start-position || exit 1" + && echo _WSREP_START_POSITION=$VAR > @INSTALL_RUNDATADIR@/wsrep-start-position || exit 1" # Needed to create system tables etc. # ExecStartPre=@scriptdir@/mysql_install_db -u mysql @@ -97,8 +97,8 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ # _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster ExecStart=@sbindir@/mariadbd $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION -# Unset _WSREP_START_POSITION environment variable. -ExecStartPost=/bin/rm -f @mysqlunixdir@/wsrep-start-position +# Unset _WSREP_START_POSITION/_WSREP_NEW_CLUSTER environment variable. +ExecStartPost=/bin/rm -f @INSTALL_RUNDATADIR@/wsrep-start-position @INSTALL_RUNDATADIR@/wsrep-new-cluster @SYSTEMD_EXECSTARTPOST@ diff --git a/support-files/tmpfiles.conf.in b/support-files/tmpfiles.conf.in index 03d66abc0c7..e67756f128a 100644 --- a/support-files/tmpfiles.conf.in +++ b/support-files/tmpfiles.conf.in @@ -1 +1,15 @@ -d @MYSQL_UNIX_DIR@ 0755 @MYSQLD_USER@ @MYSQLD_USER@ - +# This is the directory where the unix socket +# of MariaDB may be created. +# +# Under Galera this is where an envfile of +# the Galera start position is stored. +# +# Other temporary directories can be created here like: +# * tmpdir +# * innodb_tmpdir +# * innodb_temp_data_file_path +# * rocksdb_tmpdir +# etc. +# It shouldn't be used for datadir which is why it +# may be disabled. +@DISABLE_TMP@d @INSTALL_RUNDATADIR@ 0755 @MYSQLD_USER@ @MYSQLD_USER@ - From 6c835b1634158b120eb1da28baa0cbf87038b16d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Nov 2025 21:36:53 +0100 Subject: [PATCH 033/152] fix rpm upgrade tests after MDEV-37726 MDEV-37726 moved wsrep-start-position to INSTALL_RUNDATADIR and made the latter to be created by systemd-tmpfiles. Now postin scriptlet has to run systemd-tmpfiles explicitly to make sure INSTALL_RUNDATADIR exists before restarting the server. followup for 649216e70d87 --- support-files/rpm/server-postin.sh | 1 + support-files/rpm/server-posttrans.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index 5a66381d593..e08bce07530 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -1,5 +1,6 @@ if [ -f /usr/lib/systemd/system/mariadb.service -a -x /usr/bin/systemctl ]; then systemd_conf=/etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf + systemd-tmpfiles --create mariadb.conf if [ -x %{_bindir}/mariadb-service-convert -a ! -f "${systemd_conf}" ]; then # Either fresh install or upgrade non-systemd -> systemd mkdir -p /etc/systemd/system/mariadb.service.d diff --git a/support-files/rpm/server-posttrans.sh b/support-files/rpm/server-posttrans.sh index d91ff65e04f..e6c411e4aae 100644 --- a/support-files/rpm/server-posttrans.sh +++ b/support-files/rpm/server-posttrans.sh @@ -3,7 +3,7 @@ if [ -r %{restart_flag} ] ; then # only restart the server if it was already running if [ -x /usr/bin/systemctl ] ; then /usr/bin/systemctl daemon-reload > /dev/null 2>&1 - if /usr/bin/systemctl is-active mysql; then + if /usr/bin/systemctl -q is-active mysql; then /usr/bin/systemctl restart mysql > /dev/null 2>&1 else /usr/bin/systemctl try-restart mariadb.service > /dev/null 2>&1 From 2bccd1d506e3fde7cda0671e8a65516f251482f6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 30 Sep 2025 15:27:52 +1000 Subject: [PATCH 034/152] MDEV-15502 debian: systemd, with tmpfiles install not required With PermissionsStartOnly deprecated, remove this from the systemd service file. Replace Debian's ExecStartPre "install -d" with a tmpfile configuration directive creating the directory with this. Debian's ExecStartPost of the mariadb upgrade uses the ! special executable prefix added in systemd v231 to use root privs. --- cmake/systemd.cmake | 3 +-- debian/mariadb-server-10.6.install | 1 + debian/not-installed | 1 - support-files/CMakeLists.txt | 10 +++++++--- support-files/mariadb.service.in | 5 ----- support-files/tmpfiles.conf.in | 3 ++- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake index 0f37acd2afe..ff3499c87ad 100644 --- a/cmake/systemd.cmake +++ b/cmake/systemd.cmake @@ -50,8 +50,7 @@ MACRO(CHECK_SYSTEMD) SET(SYSTEMD_SCRIPTS ${SYSTEMD_SCRIPTS} galera_new_cluster galera_recovery) ENDIF() IF(DEB) - SET(SYSTEMD_EXECSTARTPRE "ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld") - SET(SYSTEMD_EXECSTARTPOST "ExecStartPost=/etc/mysql/debian-start") + SET(SYSTEMD_EXECSTARTPOST "ExecStartPost=!/etc/mysql/debian-start") ENDIF() IF(URING_FOUND) SET(SYSTEMD_LIMIT "# For liburing and io_uring_setup() diff --git a/debian/mariadb-server-10.6.install b/debian/mariadb-server-10.6.install index 236917d9d7c..8ab2441dab7 100644 --- a/debian/mariadb-server-10.6.install +++ b/debian/mariadb-server-10.6.install @@ -11,6 +11,7 @@ lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf lib/systemd/system/mysql.service lib/systemd/system/mysqld.service support-files/rpm/enable_encryption.preset etc/mysql/mariadb.conf.d/99-enable-encryption.cnf.preset +usr/lib/tmpfiles.d/mariadb.conf usr/bin/aria_chk usr/bin/aria_dump_log usr/bin/aria_ftdump diff --git a/debian/not-installed b/debian/not-installed index 6924c9ad1a5..4cef23373fa 100644 --- a/debian/not-installed +++ b/debian/not-installed @@ -11,7 +11,6 @@ usr/bin/sst_dump # Use the one from rocksdb-tools package usr/lib/mysql/plugin/JavaWrappers.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless usr/lib/mysql/plugin/JdbcInterface.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless usr/lib/sysusers.d/sysusers.conf -usr/lib/tmpfiles.d/tmpfiles.conf usr/lib/*/libdbbc.a # ColumnStore header file usr/lib/*/libidbboot.a # ColumnStore header file usr/lib/*/libprocessor.a # ColumnStore header file diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 9d947943bbf..86cfc06e8f0 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -197,11 +197,15 @@ IF(UNIX AND NOT WITHOUT_SERVER) RENAME mariadb.conf COMPONENT Server) ENDIF() - IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_TMPUSERS) AND INSTALL_SYSTEMD_TMPFILESDIR - AND INSTALL_RUNDATADIR) + IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_TMPUSERS) AND INSTALL_SYSTEMD_TMPFILESDIR) IF(MYSQL_DATADIR STREQUAL INSTALL_RUNDATADIR) - SET(DISABLE_TMP "#") + SET(DISABLE_RUNDATADIR "#") ENDIF() + get_filename_component(MYSQL_UNIX_ADDRDIR ${MYSQL_UNIX_ADDR} DIRECTORY) + IF(MYSQL_UNIX_ADDRDIR STREQUAL MYSQL_DATADIR OR MYSQL_UNIX_ADDRDIR STREQUAL INSTALL_RUNDATADIR) + SET(DISABLE_MYSQL_UNIX_ADDRDIR "#") + ENDIF() + CONFIGURE_FILE(tmpfiles.conf.in ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 2dc90af83c5..d832589dee5 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -66,17 +66,12 @@ ProtectSystem=full # Prevent accessing /home, /root and /run/user ProtectHome=true -# Execute pre and post scripts as root, otherwise it does it as User= -PermissionsStartOnly=true - # Use an environment file to pass variable _WSREP_NEW_CLUSTER EnvironmentFile=-@INSTALL_RUNDATADIR@/wsrep-new-cluster # Use an environment file to pass variable _WSREP_START_POSITION EnvironmentFile=-@INSTALL_RUNDATADIR@/wsrep-start-position -@SYSTEMD_EXECSTARTPRE@ - # Perform automatic wsrep recovery. When server is started without wsrep, # galera_recovery simply returns an empty string. In any case, however, # the script is not expected to return with a non-zero status. diff --git a/support-files/tmpfiles.conf.in b/support-files/tmpfiles.conf.in index e67756f128a..6a2a28b59a3 100644 --- a/support-files/tmpfiles.conf.in +++ b/support-files/tmpfiles.conf.in @@ -12,4 +12,5 @@ # etc. # It shouldn't be used for datadir which is why it # may be disabled. -@DISABLE_TMP@d @INSTALL_RUNDATADIR@ 0755 @MYSQLD_USER@ @MYSQLD_USER@ - +@DISABLE_RUNDATADIR@d @INSTALL_RUNDATADIR@ 0755 @MYSQLD_USER@ @MYSQLD_USER@ - +@DISABLE_MYSQL_UNIX_ADDRDIR@d @MYSQL_UNIX_ADDRDIR@ 0755 @MYSQLD_USER@ root - From c12e94a38bed688e668cc7d8eac06d79e6d21763 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 13 Jan 2026 13:29:43 +0100 Subject: [PATCH 035/152] fix sporadic failures on main.user_var --view --- mysql-test/main/user_var.result | 2 +- mysql-test/main/user_var.test | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/user_var.result b/mysql-test/main/user_var.result index 583f19b17ef..23a9f961801 100644 --- a/mysql-test/main/user_var.result +++ b/mysql-test/main/user_var.result @@ -568,7 +568,7 @@ SELECT @a; @a 1 DROP TABLE t1; -End of 5.5 tests +# End of 5.5 tests # # Check that used memory extends if we set a variable # diff --git a/mysql-test/main/user_var.test b/mysql-test/main/user_var.test index 5a88c888d1d..ef9fea244f6 100644 --- a/mysql-test/main/user_var.test +++ b/mysql-test/main/user_var.test @@ -498,7 +498,7 @@ SELECT DISTINCT POW(COUNT(distinct a), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 SELECT @a; DROP TABLE t1; ---echo End of 5.5 tests +--echo # End of 5.5 tests --echo # --echo # Check that used memory extends if we set a variable @@ -506,9 +506,9 @@ DROP TABLE t1; --disable_service_connection # Execute twice so number stablizes a bit -let $tmp= `select memory_used from information_schema.processlist`; +let $tmp= `select memory_used from information_schema.processlist where id=connection_id()`; set @var= repeat('a',30000); -let $tmp2= `select memory_used from information_schema.processlist`; +let $tmp2= `select memory_used from information_schema.processlist where id=connection_id()`; --disable_query_log --disable_column_names eval select $tmp < $tmp2; From 4e674a20c48cbe1009a660680f54ce316f110080 Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Thu, 8 Jan 2026 19:52:31 +0000 Subject: [PATCH 036/152] Simplify event filtering logic in server_audit plugin Replace if-else chain with a single bitwise AND check when filtering query events by type (DDL, DML, DCL, etc.). The removes the need for the goto statements. Additionally, we remove the orig_query variable as it served no purpose. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license --- plugin/server_audit/server_audit.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 7175239be82..ac8693a0f37 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -1686,20 +1686,10 @@ static int log_statement_ex(const struct connection_info *cn, if (query && !(events & EVENT_QUERY_ALL) && (events & EVENT_QUERY && !cn->log_always)) { - const char *orig_query= query; - - if (events & EVENT_QUERY_DDL && cmdtype & EVENT_QUERY_DDL) - goto do_log_query; - if (events & EVENT_QUERY_DML && cmdtype & EVENT_QUERY_DML) - goto do_log_query; - if (events & EVENT_QUERY_DML_NO_SELECT && cmdtype & EVENT_QUERY_DML_NO_SELECT) - goto do_log_query; - if (events & EVENT_QUERY_DCL && cmdtype & EVENT_QUERY_DCL) - goto do_log_query; - - return 0; -do_log_query: - query= orig_query; + if (!(events & cmdtype & + (EVENT_QUERY_DDL | EVENT_QUERY_DML | EVENT_QUERY_DML_NO_SELECT | + EVENT_QUERY_DCL))) + return 0; } csize= log_header(message, message_size-1, &ev_time, From d75734570303e02d31faac1b44c46697f36b21c1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 8 Jan 2026 19:57:30 +0000 Subject: [PATCH 037/152] Add test cases for comment handling in audit plugin The fix was implemented in 635559a. Previously with the hand-rolled SQL string parsing in the audit plugin, there were many simple ways to bypass server audit logging by placing comments strategically in the query string. The fix in 635559a removes the custom SQL string parser which addresses the issue. We now add MTRs for validation. --- .../suite/plugins/r/server_audit.result | 46 +++++++++++++++++++ mysql-test/suite/plugins/t/server_audit.test | 25 ++++++++++ 2 files changed, 71 insertions(+) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 588563b1b0e..a6253b1109e 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -177,6 +177,43 @@ select 2; /*comment*/ select 2; 2 2 +with foo as (select 1) select 6; +6 +6 +values (7, 'a'), (8, 'b'); +7 a +7 a +8 b +# +# Certain usage of comments and control characters in query strings bypass audit +# logging when filtering in QUERY_{DCL/DML/DDL} mode +# +-- A comment +select 1; +1 +1 +--A comment +select 2; +2 +2 +# A comment +select 3; +3 +3 +/*! SELECT 4 */; +4 +4 +/*M! SELECT 5 */; +5 +5 +/*!100100 SELECT 6 */; +6 +6 +/*!999999 SELECT 'should not log' */; +/*M!100100 SELECT 7 */; +7 +7 +/*M!999999 SELECT 'should not log' */; drop table t1; set global server_audit_events='query_dcl'; create table t1(id int); @@ -441,6 +478,15 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select 2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'(select 2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'with foo as (select 1) select 6',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'values (7, \'a\'), (8, \'b\')',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'-- A comment\nselect 1',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'--A comment\nselect 2',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'# A comment\nselect 3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! SELECT 4 */',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*M! SELECT 5 */',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*!100100 SELECT 6 */',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*M!100100 SELECT 7 */',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 8ba38a521e7..c701f915389 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -133,6 +133,31 @@ select 2; (select 2); /*! select 2*/; /*comment*/ select 2; +with foo as (select 1) select 6; +values (7, 'a'), (8, 'b'); + +--echo # +--echo # Certain usage of comments and control characters in query strings bypass audit +--echo # logging when filtering in QUERY_{DCL/DML/DDL} mode +--echo # + +query -- A comment +select 1; + +query --A comment +select 2; + +query # A comment +select 3; + +query /*! SELECT 4 */; +query /*M! SELECT 5 */; + +query /*!100100 SELECT 6 */; +query /*!999999 SELECT 'should not log' */; +query /*M!100100 SELECT 7 */; +query /*M!999999 SELECT 'should not log' */; + drop table t1; set global server_audit_events='query_dcl'; create table t1(id int); From 52a2b721a75c11eff8f286fb898384c9dece7e33 Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Thu, 8 Jan 2026 19:59:36 +0000 Subject: [PATCH 038/152] Add additional password obfuscation test cases for server audit plugin - GRANT SELECT ... IDENTIFIED BY - CHANGE MASTER ... MASTER_PASSWORD - CREATE SERVER ... PASSWORD - ALTER SERVER ... PASSWORD All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license --- .../suite/plugins/r/server_audit.result | 26 +++++++++++++++++++ mysql-test/suite/plugins/t/server_audit.test | 7 +++++ 2 files changed, 33 insertions(+) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index a6253b1109e..b9d2738220c 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -122,6 +122,13 @@ GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; SET PASSWORD FOR u1 = PASSWORD('pwd 098'); CREATE USER u3 IDENTIFIED BY ''; ALTER USER u3 IDENTIFIED BY 'pwd-456'; +GRANT SELECT ON sa_db.* TO pwd_test1 IDENTIFIED BY 'grantpwd789'; +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='repl', MASTER_PASSWORD='replsecret'; +CREATE SERVER pwd_server FOREIGN DATA WRAPPER mysql OPTIONS (HOST 'localhost', USER 'remote', PASSWORD 'serverpwd'); +ALTER SERVER pwd_server OPTIONS (PASSWORD 'newserverpwd'); +DROP USER pwd_test1; +DROP SERVER pwd_server; +RESET SLAVE ALL; drop user u1, u2, u3; set global server_audit_events='query_ddl'; create table t1(id int); @@ -454,6 +461,25 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *** TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'ALTER USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT SELECT ON sa_db.* TO pwd_test1 IDENTIFIED BY *****',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CHANGE MASTER TO MASTER_HOST=\'127.0.0.1\', MASTER_USER=\'repl\', MASTER_PASSWORD=*****',0 +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,servers, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE SERVER pwd_server FOREIGN DATA WRAPPER mysql OPTIONS (HOST \'localhost\', USER \'remote\', PASSWORD *****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,servers, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'ALTER SERVER pwd_server OPTIONS (PASSWORD *****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping, +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'DROP USER pwd_test1',0 +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,servers, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'DROP SERVER pwd_server',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'RESET SLAVE ALL',0 +TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv, diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index c701f915389..7373a973d62 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -102,6 +102,13 @@ GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; SET PASSWORD FOR u1 = PASSWORD('pwd 098'); CREATE USER u3 IDENTIFIED BY ''; ALTER USER u3 IDENTIFIED BY 'pwd-456'; +GRANT SELECT ON sa_db.* TO pwd_test1 IDENTIFIED BY 'grantpwd789'; +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='repl', MASTER_PASSWORD='replsecret'; +CREATE SERVER pwd_server FOREIGN DATA WRAPPER mysql OPTIONS (HOST 'localhost', USER 'remote', PASSWORD 'serverpwd'); +ALTER SERVER pwd_server OPTIONS (PASSWORD 'newserverpwd'); +DROP USER pwd_test1; +DROP SERVER pwd_server; +RESET SLAVE ALL; drop user u1, u2, u3; set global server_audit_events='query_ddl'; From 8437643a36bd5a04868e1b6f7f3a926456000863 Mon Sep 17 00:00:00 2001 From: Rophy Tsai Date: Mon, 12 Jan 2026 22:34:45 +0000 Subject: [PATCH 039/152] MDEV-38431: fix database pointer calculation for long passwords When a client connects with CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA capability and a password >= 251 bytes, the server incorrectly calculates the database name pointer. For passwords >= 251 bytes, LENENC uses a 3-byte prefix (0xFC + 2 bytes), but the old code assumed a 1-byte prefix. Fix by using the passwd pointer which has already been advanced past the length prefix by safe_net_field_length_ll(). Also fix db pointer calculation for old protocol (!CLIENT_SECURE_CONNECTION) where the password is null-terminated and needs +1 to skip the terminator. --- mysql-test/suite/plugins/r/mdev38431.result | 35 ++++++++++++ mysql-test/suite/plugins/t/mdev38431.test | 59 +++++++++++++++++++++ sql/sql_acl.cc | 22 +++++--- 3 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/plugins/r/mdev38431.result create mode 100644 mysql-test/suite/plugins/t/mdev38431.test diff --git a/mysql-test/suite/plugins/r/mdev38431.result b/mysql-test/suite/plugins/r/mdev38431.result new file mode 100644 index 00000000000..d3bff9a3ecc --- /dev/null +++ b/mysql-test/suite/plugins/r/mdev38431.result @@ -0,0 +1,35 @@ +# +# Setup +# +INSTALL PLUGIN IF NOT EXISTS cleartext_plugin_server SONAME ''; +Warnings: +Note 1968 Plugin 'cleartext_plugin_server' already installed +CREATE DATABASE mdev38431_db; +# +# Test 1: Short password - baseline test +# +CREATE USER shortuser IDENTIFIED VIA cleartext_plugin_server USING 'secret'; +GRANT ALL ON *.* TO shortuser; +db +mdev38431_db +# +# Test 2: Long password 260 bytes (triggers 3-byte LENENC) +# Before fix: ERROR 1044 Access denied to database 'X' (garbage char) +# After fix: Connects to mdev38431_db correctly +# +CREATE USER longuser IDENTIFIED VIA cleartext_plugin_server USING 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +GRANT ALL ON *.* TO longuser; +db +mdev38431_db +# +# Test 3: Even longer password 500 bytes +# +CREATE USER verylonguser IDENTIFIED VIA cleartext_plugin_server USING 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; +GRANT ALL ON *.* TO verylonguser; +db +mdev38431_db +# +# Cleanup +# +DROP USER shortuser, longuser, verylonguser; +DROP DATABASE mdev38431_db; diff --git a/mysql-test/suite/plugins/t/mdev38431.test b/mysql-test/suite/plugins/t/mdev38431.test new file mode 100644 index 00000000000..21b60078f4a --- /dev/null +++ b/mysql-test/suite/plugins/t/mdev38431.test @@ -0,0 +1,59 @@ +# +# MDEV-38431: Auth Switch with Long Password Corrupts Database Name +# +# When password >= 251 bytes with CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA, +# the length is encoded in 3 bytes (0xFC + 2 bytes). The server incorrectly +# calculated the database pointer, causing connection to wrong database. +# +# Fix: Use 'passwd + passwd_len' instead of 'db + passwd_len + 1' +# + +--source include/not_embedded.inc +--source include/have_plugin_auth.inc + +--echo # +--echo # Setup +--echo # +eval INSTALL PLUGIN IF NOT EXISTS cleartext_plugin_server SONAME '$PLUGIN_AUTH'; +CREATE DATABASE mdev38431_db; + +--echo # +--echo # Test 1: Short password - baseline test +--echo # +CREATE USER shortuser IDENTIFIED VIA cleartext_plugin_server USING 'secret'; +GRANT ALL ON *.* TO shortuser; + +# Connect with short password and verify database +--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u shortuser -p"secret" --database=mdev38431_db -e "SELECT DATABASE() AS db" + +--echo # +--echo # Test 2: Long password 260 bytes (triggers 3-byte LENENC) +--echo # Before fix: ERROR 1044 Access denied to database 'X' (garbage char) +--echo # After fix: Connects to mdev38431_db correctly +--echo # + +# Create password with 260 'a' characters +--let $long_pwd=`SELECT REPEAT('a', 260)` +eval CREATE USER longuser IDENTIFIED VIA cleartext_plugin_server USING '$long_pwd'; +GRANT ALL ON *.* TO longuser; + +# This connection uses --default-auth=mysql_clear_password to trigger auth switch +# With a password >= 251 bytes, the client sends password length in 3-byte format +# The bug caused the server to read database name from wrong offset +--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u longuser -p"$long_pwd" --database=mdev38431_db -e "SELECT DATABASE() AS db" + +--echo # +--echo # Test 3: Even longer password 500 bytes +--echo # +--let $very_long_pwd=`SELECT REPEAT('b', 500)` +eval CREATE USER verylonguser IDENTIFIED VIA cleartext_plugin_server USING '$very_long_pwd'; +GRANT ALL ON *.* TO verylonguser; + +--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u verylonguser -p"$very_long_pwd" --database=mdev38431_db -e "SELECT DATABASE() AS db" + +--echo # +--echo # Cleanup +--echo # +DROP USER shortuser, longuser, verylonguser; +DROP DATABASE mdev38431_db; +# Note: Do not uninstall cleartext_plugin_server as it was pre-loaded by MTR diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 422ea6b008b..512a0b055f7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -13846,25 +13846,31 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, Cast *passwd to an unsigned char, so that it doesn't extend the sign for *passwd > 127 and become 2**32-127+ after casting to uint. */ - ulonglong len; size_t passwd_len; if (!(thd->client_capabilities & CLIENT_SECURE_CONNECTION)) - len= strlen(passwd); + { + passwd_len= strlen(passwd); + db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? + passwd + passwd_len + 1 : 0; /* +1 to skip null terminator */ + } else if (!(thd->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)) - len= (uchar)(*passwd++); + { + passwd_len= (uchar)(*passwd++); + db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? + passwd + passwd_len : 0; + } else { - len= safe_net_field_length_ll((uchar**)&passwd, + ulonglong len= safe_net_field_length_ll((uchar**)&passwd, net->read_pos + pkt_len - (uchar*)passwd); if (len > pkt_len) return packet_error; + passwd_len= (size_t)len; + db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? + passwd + passwd_len : 0; } - passwd_len= (size_t)len; - db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? - db + passwd_len + 1 : 0; - if (passwd == NULL || passwd + passwd_len + MY_TEST(db) > (char*) net->read_pos + pkt_len) return packet_error; From db2606d5f96691643946c9956e36bb890c5ee324 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 5 Nov 2025 10:50:58 +0100 Subject: [PATCH 040/152] MDEV-37920 Out-of-Bounds memory access in File_parser::parse() correct the length check. remove assertions that a file read from disk contains a specific substring --- mysql-test/main/view.result | 6 +++++- mysql-test/main/view.test | 13 +++++++++++-- sql/parse_file.cc | 2 +- sql/sql_view.cc | 4 ---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index d00ff523f76..84c4fa77f86 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -7122,5 +7122,9 @@ ERROR HY000: The target table view1 of the INSERT is not insertable-into DROP VIEW view1; DROP TABLE table1; # -# End of 10.11 test +# MDEV-37920 Out-of-Bounds memory access in File_parser::parse() # +select * from v1; +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +drop view v1; +# End of 10.11 test diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 3964aec4a97..9bcc4ff8f7f 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -5238,7 +5238,6 @@ DROP TABLE t1, t2; create view v1 as select 1; ---let $MYSQLD_DATADIR= `select @@datadir` --let SEARCH_FILE= $MYSQLD_DATADIR/test/v1.frm --let SEARCH_RANGE= 50000 --let SEARCH_PATTERN=mariadb-version @@ -6892,5 +6891,15 @@ DROP VIEW view1; DROP TABLE table1; --echo # ---echo # End of 10.11 test +--echo # MDEV-37920 Out-of-Bounds memory access in File_parser::parse() --echo # +--write_file $MYSQLD_DATADIR/test/v1.frm +TYPE=VIEW +query=select `0_________1_________2_________3_________4_________5____` + +EOF +--error ER_VIEW_INVALID +select * from v1; +drop view v1; + +--echo # End of 10.11 test diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 8495f56c1fe..568bca5339a 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -814,7 +814,7 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root, { len= parameter->name.length; // check length - if (len < (size_t)(end-ptr) && ptr[len] != '=') + if (len >= (size_t)(end-ptr) || ptr[len] != '=') continue; // check keyword if (memcmp(parameter->name.str, ptr, len) == 0) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 58da2833ec1..1c67331ce49 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1272,7 +1272,6 @@ bool mariadb_view_version_get(TABLE_SHARE *share) share->db.str, share->table_name.str); return TRUE; } - DBUG_ASSERT(share->tabledef_version.length == MICROSECOND_TIMESTAMP_BUFFER_SIZE-1); return FALSE; } @@ -1392,11 +1391,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, required_view_parameters, &file_parser_dummy_hook))) goto end; - DBUG_ASSERT(share->tabledef_version.length); if (!table->tabledef_version.length) - { table->set_view_def_version(&table->hr_timestamp); - } /* check old format view .frm From 9134fea5d67475c10826bd69b768b5b1b0123541 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 7 Nov 2025 20:22:34 +0100 Subject: [PATCH 041/152] cleanup: move constraint tests from check.test to check_constraint.test --- mysql-test/main/check.result | 50 -------------- mysql-test/main/check.test | 46 ------------- mysql-test/main/check_constraint.result | 80 +++++++++++++++++++--- mysql-test/main/check_constraint.test | 88 +++++++++++++++++-------- 4 files changed, 131 insertions(+), 133 deletions(-) diff --git a/mysql-test/main/check.result b/mysql-test/main/check.result index d58c5044031..341c4411298 100644 --- a/mysql-test/main/check.result +++ b/mysql-test/main/check.result @@ -52,53 +52,3 @@ connection default; UNLOCK TABLES; DROP TABLE t1; disconnect con1; -# -# MDEV-15338 -# Assertion `!table || (!table->read_set || -# bitmap_is_set(table->read_set, field_index))' -# failed on dropping column with CHECK -# -CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,2),(3,4); -ALTER TABLE t1 DROP COLUMN a; -CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -ERROR 42S22: Unknown column 'b' in 'CHECK' -ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL, - `b` int(11) DEFAULT NULL, - `c` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL, - `c` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -DROP TABLE t1; -create temporary table t1 ( -id int not null auto_increment primary key, -f int not null default 0 -); -insert into t1 () values (); -alter ignore table t1 add constraint check (f > 0); -Warnings: -Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` -alter table t1; -drop table t1; -create temporary table t1 (a int default 0, check (a > 0)); -alter table t1 drop constraint if exists non_existing_constraint; -Warnings: -Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists -insert into t1 () values (); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` -drop table t1; diff --git a/mysql-test/main/check.test b/mysql-test/main/check.test index 29587a9f623..69202c944ba 100644 --- a/mysql-test/main/check.test +++ b/mysql-test/main/check.test @@ -76,51 +76,5 @@ UNLOCK TABLES; DROP TABLE t1; disconnect con1; - # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc - ---echo # ---echo # MDEV-15338 ---echo # Assertion `!table || (!table->read_set || ---echo # bitmap_is_set(table->read_set, field_index))' ---echo # failed on dropping column with CHECK ---echo # - -CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,2),(3,4); -ALTER TABLE t1 DROP COLUMN a; -CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; ---error ER_BAD_FIELD_ERROR -ALTER TABLE t1 DROP COLUMN b; -ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -DROP TABLE t1; - -# -# MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table -# -create temporary table t1 ( - id int not null auto_increment primary key, - f int not null default 0 -); -insert into t1 () values (); -alter ignore table t1 add constraint check (f > 0); -alter table t1; -drop table t1; - -# -# MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint -# -create temporary table t1 (a int default 0, check (a > 0)); -alter table t1 drop constraint if exists non_existing_constraint; ---error ER_CONSTRAINT_FAILED -insert into t1 () values (); -drop table t1; diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 9202e620dc3..fd6b662cca8 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -131,17 +131,29 @@ t1 CREATE TABLE `t1` ( CONSTRAINT `CONSTRAINT_2` CHECK (`a` > `b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; +# +# MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified +# create table t1(c1 int, c2 int as (c1 + 1), check (c2 > 2)); insert into t1(c1) values(1); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` insert into t1(c1) values(2); drop table t1; +# +# MDEV-11117 CHECK constraint fails on intermediate step of ALTER +# create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or c1 is null ) ); ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the CHECK clause of `c1` +# +# MDEV-12421 Check constraint with query crashes server and renders DB unusable +# create table t1 (a int check (@b in (select user from mysql.user))); ERROR 42000: CHECK does not support subqueries or stored functions create table t1 (a int check (a > @b)); ERROR HY000: Function or expression '@b' cannot be used in the CHECK clause of `a` +# +# MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL +# create table t1 (a int check (a = 1)); insert t1 values (1); insert t1 values (2); @@ -152,10 +164,16 @@ a 1 NULL drop table t1; +# +# MDEV-15141 Check constraint validation on a datetime field crashes the process +# create table t1 (id int auto_increment primary key, datecol datetime, check (datecol>'0001-01-01 00:00:00')); insert into t1 (datecol) values (now()); insert into t1 (datecol) values (now()); drop table t1; +# +# MDEV-15461 Check Constraints with binary logging makes insert inconsistent +# CREATE TABLE t1 ( EmployeeID SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, FirstName VARCHAR(30) NOT NULL CHECK (CHAR_LENGTH(FirstName > 2)) @@ -198,8 +216,7 @@ EmployeeID FirstName 6 Brian drop table t1; # -# MDEV-16630: Ambiguous error message when check constraint -# matches table name +# MDEV-16630: Ambiguous error message when check constraint matches table name # use test; drop table if exists t; @@ -279,8 +296,59 @@ Warning 1265 Data truncated for column 'v1' at row 1 Warning 1292 Truncated incorrect INTEGER value: 'x' drop table t1; # -# End of 10.2 tests +# MDEV-15338 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on dropping column with CHECK # +CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,2),(3,4); +ALTER TABLE t1 DROP COLUMN a; +CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +ERROR 42S22: Unknown column 'b' in 'CHECK' +ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +# +# MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table +# +create temporary table t1 ( +id int not null auto_increment primary key, +f int not null default 0 +); +insert into t1 () values (); +alter ignore table t1 add constraint check (f > 0); +Warnings: +Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +alter table t1; +drop table t1; +# +# MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint +# +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +Warnings: +Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists +insert into t1 () values (); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +drop table t1; +# End of 10.2 tests # # MDEV-26061 MariaDB server crash at Field::set_default # @@ -292,10 +360,8 @@ t1 CREATE TABLE `t1` ( `1` int(1) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; -# # End of 10.3 tests # -# # MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error # create table t1 (id varchar(2), constraint id check (id regexp '[a-z]')); @@ -317,10 +383,8 @@ insert t1 (a) values (1); insert t1 (a) values (-1); ERROR 23000: CONSTRAINT `t1.b` failed for `test`.`t1` drop table t1; -# # End of 10.4 tests # -# # MDEV-36662 CHECK constraint does not repeat in case of error # create table t1 (d date check (d > 2020-01-01)); @@ -375,6 +439,4 @@ ERROR 22007: Truncated incorrect DECIMAL value: 'a' insert into t1 values ("b"); ERROR 22007: Truncated incorrect DECIMAL value: 'b' drop table t1; -# # End of 10.11 tests -# diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index f99da0536c7..e9cf64e0bd9 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -69,32 +69,32 @@ create or replace table t1 (a int, b int, show create table t1; drop table t1; -# -# MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified -# +--echo # +--echo # MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified +--echo # create table t1(c1 int, c2 int as (c1 + 1), check (c2 > 2)); --error ER_CONSTRAINT_FAILED insert into t1(c1) values(1); insert into t1(c1) values(2); drop table t1; -# -# MDEV-11117 CHECK constraint fails on intermediate step of ALTER -# +--echo # +--echo # MDEV-11117 CHECK constraint fails on intermediate step of ALTER +--echo # -- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or c1 is null ) ); -# -# MDEV-12421 Check constraint with query crashes server and renders DB unusable -# +--echo # +--echo # MDEV-12421 Check constraint with query crashes server and renders DB unusable +--echo # --error ER_SUBQUERIES_NOT_SUPPORTED create table t1 (a int check (@b in (select user from mysql.user))); --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create table t1 (a int check (a > @b)); -# -# MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL -# +--echo # +--echo # MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL +--echo # create table t1 (a int check (a = 1)); insert t1 values (1); --error ER_CONSTRAINT_FAILED @@ -103,17 +103,17 @@ insert t1 values (NULL); select * from t1; drop table t1; -# -# MDEV-15141 Check constraint validation on a datetime field crashes the process -# +--echo # +--echo # MDEV-15141 Check constraint validation on a datetime field crashes the process +--echo # create table t1 (id int auto_increment primary key, datecol datetime, check (datecol>'0001-01-01 00:00:00')); insert into t1 (datecol) values (now()); insert into t1 (datecol) values (now()); drop table t1; -# -# MDEV-15461 Check Constraints with binary logging makes insert inconsistent -# +--echo # +--echo # MDEV-15461 Check Constraints with binary logging makes insert inconsistent +--echo # CREATE TABLE t1 ( EmployeeID SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, @@ -136,8 +136,7 @@ select * from t1; drop table t1; --echo # ---echo # MDEV-16630: Ambiguous error message when check constraint ---echo # matches table name +--echo # MDEV-16630: Ambiguous error message when check constraint matches table name --echo # use test; @@ -208,9 +207,49 @@ insert ignore into t1 values ( 'x' , 'x' ) ; drop table t1; --echo # ---echo # End of 10.2 tests +--echo # MDEV-15338 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on dropping column with CHECK --echo # +CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,2),(3,4); +ALTER TABLE t1 DROP COLUMN a; +CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t1 DROP COLUMN b; +ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table +--echo # +create temporary table t1 ( + id int not null auto_increment primary key, + f int not null default 0 +); +insert into t1 () values (); +alter ignore table t1 add constraint check (f > 0); +alter table t1; +drop table t1; + +--echo # +--echo # MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint +--echo # +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +--error ER_CONSTRAINT_FAILED +insert into t1 () values (); +drop table t1; + +--echo # End of 10.2 tests + --echo # --echo # MDEV-26061 MariaDB server crash at Field::set_default --echo # @@ -219,9 +258,7 @@ create table t1 (d timestamp not null default now() check (default (d) is true)) show create table t1; drop table t1; ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error @@ -244,9 +281,7 @@ insert t1 (a) values (1); insert t1 (a) values (-1); drop table t1; ---echo # --echo # End of 10.4 tests ---echo # --echo # --echo # MDEV-36662 CHECK constraint does not repeat in case of error @@ -304,7 +339,4 @@ insert into t1 values ("a"); insert into t1 values ("b"); drop table t1; ---echo # --echo # End of 10.11 tests ---echo # - From bc977fb0084cb81d481a86eff1763d81e01f8611 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 7 Nov 2025 20:34:33 +0100 Subject: [PATCH 042/152] MDEV-37971 CHECK TABLE command can be executed by users with the table-level CREATE but not with global CREATE CHECK TABLE was inconsistently requiring SELECT privilege on global/db level or any privilege on the table/column level. Change to require any table-applicable privilege on any level. --- mysql-test/main/check.result | 25 ++++++++++++++++++++++--- mysql-test/main/check.test | 34 +++++++++++++++++++++------------- mysql-test/main/grant4.result | 7 ++----- mysql-test/main/grant4.test | 5 +---- sql/sql_admin.cc | 9 +++++++-- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/mysql-test/main/check.result b/mysql-test/main/check.result index 341c4411298..b5315279875 100644 --- a/mysql-test/main/check.result +++ b/mysql-test/main/check.result @@ -1,8 +1,6 @@ connect con1,localhost,root,,; connect con2,localhost,root,,; connection con1; -drop table if exists t1,t2; -drop view if exists v1; create table t1(n int not null, key(n), key(n), key(n), key(n)); Warnings: Note 1831 Duplicate index `n_2`. This is deprecated and will be disallowed in a future release @@ -39,7 +37,6 @@ DROP TABLE t1; # Bug#56422 CHECK TABLE run when the table is locked reports corruption # along with timeout # -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT); LOCK TABLE t1 WRITE; connect con1, localhost, root; @@ -52,3 +49,25 @@ connection default; UNLOCK TABLES; DROP TABLE t1; disconnect con1; +# +# MDEV-37971 CHECK TABLE command can be executed by users with the table-level CREATE but not with global CREATE +# +create table t1 (a int); +create user table_level_priv; +create user global_level_priv; +grant create on *.* to global_level_priv; +grant create on test.t1 to table_level_priv; +connect g,localhost,global_level_priv; +check table test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +connect t,localhost,table_level_priv; +check table test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +disconnect g; +disconnect t; +connection default; +drop table t1; +drop user table_level_priv, global_level_priv; +# End of 10.11 tests diff --git a/mysql-test/main/check.test b/mysql-test/main/check.test index 69202c944ba..582d8dffc30 100644 --- a/mysql-test/main/check.test +++ b/mysql-test/main/check.test @@ -1,13 +1,6 @@ -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; ---disable_warnings -drop table if exists t1,t2; -drop view if exists v1; ---enable_warnings # Add a lot of keys to slow down check create table t1(n int not null, key(n), key(n), key(n), key(n)); @@ -60,10 +53,6 @@ DROP TABLE t1; --echo # along with timeout --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1(a INT); LOCK TABLE t1 WRITE; @@ -76,5 +65,24 @@ UNLOCK TABLES; DROP TABLE t1; disconnect con1; -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc +--echo # +--echo # MDEV-37971 CHECK TABLE command can be executed by users with the table-level CREATE but not with global CREATE +--echo # +create table t1 (a int); +create user table_level_priv; +create user global_level_priv; +grant create on *.* to global_level_priv; +grant create on test.t1 to table_level_priv; + +connect g,localhost,global_level_priv; +check table test.t1; + +connect t,localhost,table_level_priv; +check table test.t1; +disconnect g; +disconnect t; +connection default; +drop table t1; +drop user table_level_priv, global_level_priv; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/grant4.result b/mysql-test/main/grant4.result index 3c8c752d885..daad4d67335 100644 --- a/mysql-test/main/grant4.result +++ b/mysql-test/main/grant4.result @@ -107,7 +107,7 @@ Table Op Msg_type Msg_text mysqltest_db1.t6 check status OK ** With no privileges access is naturally denied: CHECK TABLE t5; -ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t5` +ERROR 42000: CHECK TABLE command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t5` ** CHECKSUM TABLE requires SELECT privileges on the table. The following should fail: CHECKSUM TABLE t6; ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t6` @@ -151,7 +151,7 @@ ERROR HY000: Cannot load from mysql.user. The table is probably corrupted drop table mysql.user; rename table mysql.user1 to mysql.user; # switching back from mysql.user to mysql.global_priv -End of 5.5 tests +# End of 5.5 tests # # Additional coverage for refactoring which is made as part # of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege @@ -193,9 +193,6 @@ mysqltest_db1.t1 check error Corrupt # Otherwise info about such repair will be missing from its result-set. repair table mysqltest_db1.t1, mysqltest_db1.t2; ERROR 42000: SELECT, INSERT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t2` -# The same is true for CHECK TABLE statement. -check table mysqltest_db1.t1, mysqltest_db1.t2; -ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t2` check table mysqltest_db1.t1; Table Op Msg_type Msg_text mysqltest_db1.t1 check warning Table is marked as crashed diff --git a/mysql-test/main/grant4.test b/mysql-test/main/grant4.test index 6179af8cee2..2623d8b39db 100644 --- a/mysql-test/main/grant4.test +++ b/mysql-test/main/grant4.test @@ -178,7 +178,7 @@ drop table mysql.user; rename table mysql.user1 to mysql.user; source include/switch_to_mysql_global_priv.inc; ---echo End of 5.5 tests +--echo # End of 5.5 tests --echo # --echo # Additional coverage for refactoring which is made as part @@ -223,9 +223,6 @@ check table mysqltest_db1.t1; --echo # Otherwise info about such repair will be missing from its result-set. --error ER_TABLEACCESS_DENIED_ERROR repair table mysqltest_db1.t1, mysqltest_db1.t2; ---echo # The same is true for CHECK TABLE statement. ---error ER_TABLEACCESS_DENIED_ERROR -check table mysqltest_db1.t1, mysqltest_db1.t2; check table mysqltest_db1.t1; repair table mysqltest_db1.t1; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index bb318355422..360bdd408cf 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1589,9 +1589,14 @@ bool Sql_cmd_check_table::execute(THD *thd) bool res= TRUE; DBUG_ENTER("Sql_cmd_check_table::execute"); - if (check_table_access(thd, SELECT_ACL, first_table, - TRUE, UINT_MAX, FALSE)) + if (check_some_access(thd, TABLE_ACLS, first_table)) + { + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "CHECK TABLE", + thd->security_ctx->priv_user, + thd->security_ctx->host_or_ip, + first_table->db.str, first_table->table_name.str); goto error; /* purecov: inspected */ + } res= mysql_admin_table(thd, first_table, &m_lex->check_opt, &msg_check, lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0, From 7b276c0282a9be7a867accd38f67e627df63ac8a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 9 Nov 2025 12:11:44 +0100 Subject: [PATCH 043/152] MDEV-38001 NULL dereference in Trigger_creation_ctx::create() don't trust the content of a file read from disk --- include/m_string.h | 3 +++ mysql-test/main/trigger-compat.result | 22 ++++++++++------ mysql-test/main/trigger-compat.test | 36 +++++++++++++-------------- sql/sql_trigger.cc | 21 ++++++---------- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/include/m_string.h b/include/m_string.h index 4461533cd7c..4ccf55dcbe8 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -315,6 +315,9 @@ static inline int safe_strcat(char *dst, size_t dst_size, const char *src) #ifdef __cplusplus static inline char *safe_str(char *str) { return str ? str : const_cast(""); } + +static inline const char *safe_str(const LEX_CSTRING *lcs) +{ return lcs && lcs->str ? lcs->str : ""; } #endif static inline const char *safe_str(const char *str) diff --git a/mysql-test/main/trigger-compat.result b/mysql-test/main/trigger-compat.result index dae865ec95c..019eabd7061 100644 --- a/mysql-test/main/trigger-compat.result +++ b/mysql-test/main/trigger-compat.result @@ -1,9 +1,3 @@ -DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%'; -FLUSH PRIVILEGES; -DROP DATABASE IF EXISTS mysqltest_db1; CREATE DATABASE mysqltest_db1; CREATE USER mysqltest_dfn@localhost; CREATE USER mysqltest_inv@localhost; @@ -55,7 +49,6 @@ USE test; # # Bug#45235: 5.1 does not support 5.0-only syntax triggers in any way # -DROP TABLE IF EXISTS t1, t2, t3; CREATE TABLE t1 ( a INT ); CREATE TABLE t2 ( a INT ); CREATE TABLE t3 ( a INT ); @@ -445,3 +438,18 @@ DROP TABLE t1; # Listing trigger files # Listing trigger files done # END: Total triggers 2, broken triggers 1, using DROP TRIGGER +# +# MDEV-38001 NULL dereference in Trigger_creation_ctx::create() +# +call mtr.add_suppression('Trigger for table ''test''.''mdev38801'''); +create table mdev38801 (a int); +insert into mdev38801 values (1); +show triggers like 'mdev38801'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +Warnings: +Warning 1604 Trigger creation context of table `test`.`mdev38801` is invalid +drop table mdev38801; +Warnings: +Warning 1603 Triggers for table `test`.`mdev38801` have no creation context +Warning 1604 Trigger creation context of table `test`.`mdev38801` is invalid +# End of 10.11 tests diff --git a/mysql-test/main/trigger-compat.test b/mysql-test/main/trigger-compat.test index f927a744c0a..f78459060ac 100644 --- a/mysql-test/main/trigger-compat.test +++ b/mysql-test/main/trigger-compat.test @@ -17,19 +17,6 @@ # ########################################################################### -# -# Prepare environment. -# -DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%'; -DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%'; -FLUSH PRIVILEGES; - ---disable_warnings -DROP DATABASE IF EXISTS mysqltest_db1; ---enable_warnings - CREATE DATABASE mysqltest_db1; CREATE USER mysqltest_dfn@localhost; @@ -109,11 +96,6 @@ USE test; --echo # --echo # Bug#45235: 5.1 does not support 5.0-only syntax triggers in any way --echo # -let $MYSQLD_DATADIR=`SELECT @@datadir`; - ---disable_warnings -DROP TABLE IF EXISTS t1, t2, t3; ---enable_warnings CREATE TABLE t1 ( a INT ); CREATE TABLE t2 ( a INT ); @@ -503,3 +485,21 @@ DROP TABLE t1; --echo # Listing trigger files done --echo # END: Total triggers 2, broken triggers 1, using DROP TRIGGER + +--echo # +--echo # MDEV-38001 NULL dereference in Trigger_creation_ctx::create() +--echo # +call mtr.add_suppression('Trigger for table ''test''.''mdev38801'''); +create table mdev38801 (a int); +insert into mdev38801 values (1); + +--write_file $MYSQLD_DATADIR/test/mdev38801.TRG +TYPE=TRIGGERS +triggers='' +client_cs_names='' +EOF + +show triggers like 'mdev38801'; +drop table mdev38801; + +--echo # End of 10.11 tests diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 98d53b33cfd..b251334d1a6 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -119,39 +119,33 @@ Trigger_creation_ctx::create(THD *thd, bool invalid_creation_ctx= FALSE; myf utf8_flag= thd->get_utf8_flag(); - if (resolve_charset(client_cs_name->str, + if (resolve_charset(safe_str(client_cs_name), thd->variables.character_set_client, &client_cs, MYF(utf8_flag))) { sql_print_warning("Trigger for table '%s'.'%s': " "invalid character_set_client value (%s).", - (const char *) db_name, - (const char *) table_name, - (const char *) client_cs_name->str); + db_name, table_name, safe_str(client_cs_name)); invalid_creation_ctx= TRUE; } - if (resolve_collation(connection_cl_name->str, + if (resolve_collation(safe_str(connection_cl_name), thd->variables.collation_connection, &connection_cl,MYF(utf8_flag))) { sql_print_warning("Trigger for table '%s'.'%s': " "invalid collation_connection value (%s).", - (const char *) db_name, - (const char *) table_name, - (const char *) connection_cl_name->str); + db_name, table_name, safe_str(connection_cl_name)); invalid_creation_ctx= TRUE; } - if (resolve_collation(db_cl_name->str, NULL, &db_cl, MYF(utf8_flag))) + if (resolve_collation(safe_str(db_cl_name), NULL, &db_cl, MYF(utf8_flag))) { sql_print_warning("Trigger for table '%s'.'%s': " "invalid database_collation value (%s).", - (const char *) db_name, - (const char *) table_name, - (const char *) db_cl_name->str); + db_name, table_name, safe_str(db_cl_name)); invalid_creation_ctx= TRUE; } @@ -162,8 +156,7 @@ Trigger_creation_ctx::create(THD *thd, Sql_condition::WARN_LEVEL_WARN, ER_TRG_INVALID_CREATION_CTX, ER_THD(thd, ER_TRG_INVALID_CREATION_CTX), - (const char *) db_name, - (const char *) table_name); + db_name, table_name); } /* From b9ae75d661ca33d59f630878f793ab30f6b9ba09 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 9 Nov 2025 10:44:55 +0100 Subject: [PATCH 044/152] MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail don't copy field default values and check constraints in CREATE ... SELECT. CREATE ... SELECT means a table is created from a *result set* not from some other table. For backward compatibility, though, let's keep copying constant default values and the "compressed" attribute. --- mysql-test/main/create_select.result | 18 +++++++++++++++++- mysql-test/main/create_select.test | 15 ++++++++++++++- mysql-test/main/default.result | 2 +- sql/sql_insert.cc | 8 ++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/create_select.result b/mysql-test/main/create_select.result index bf879192736..cbb276b61d3 100644 --- a/mysql-test/main/create_select.result +++ b/mysql-test/main/create_select.result @@ -56,6 +56,22 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING drop table t1; set sql_mode=default; -# # End of 10.4 tests # +# MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail +# +create table t1( +i int not null check(i > 0), +j int default (i+1), +primary key(i), +check (2*i>1) +); +create table t2 (select i as a,j from t1); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL, + `j` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t1, t2; +# End of 12.1 tests diff --git a/mysql-test/main/create_select.test b/mysql-test/main/create_select.test index d91f71133a0..c464744390b 100644 --- a/mysql-test/main/create_select.test +++ b/mysql-test/main/create_select.test @@ -63,6 +63,19 @@ show create table t1; drop table t1; set sql_mode=default; ---echo # --echo # End of 10.4 tests + --echo # +--echo # MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail +--echo # +create table t1( + i int not null check(i > 0), + j int default (i+1), + primary key(i), + check (2*i>1) +); +create table t2 (select i as a,j from t1); +show create table t2; +drop table t1, t2; + +--echo # End of 12.1 tests diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index 03b02d37ce5..49c19f750a1 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3121,7 +3121,7 @@ create table t3 as select max(a), max(b), max(c) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` int(11) DEFAULT 5 CHECK (`a` > 10), + `a` int(11) DEFAULT 5, `b` int(11) DEFAULT (5 + 5), `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index abc2a0f3cc8..e59f5ba596f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4842,6 +4842,14 @@ TABLE *select_create::create_table_from_items(THD *thd, List *items, Create_field *cr_field= new (thd->mem_root) Create_field(thd, tmp_field, table_field); + /* + rather inconsistently we copy constant defaults and compression + from the original field, but not default expression or check constraint + */ + if (table_field && table_field->default_value && + !table_field->default_value->expr->const_item()) + cr_field->default_value= 0; + cr_field->check_constraint= 0; if (!cr_field) DBUG_RETURN(NULL); From cf842c8c4d47413c282f168fa612e0e9f0959c27 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 14 Nov 2025 17:25:50 +0100 Subject: [PATCH 045/152] MDEV-38096 Server crashes after INSERT.. ON duplicate KEY UPDATE i = DEFAULT VALUE() should only use table->insert_values when table->insert_values contains row values. table->insert_values gets row values for the ODKU clause so if VALUE() is used before that it shouldn't use table->insert_values --- mysql-test/main/insert_update.result | 23 +++++++++++++++++++-- mysql-test/main/insert_update.test | 31 ++++++++++++++++++++++++---- sql/item.cc | 3 ++- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/insert_update.result b/mysql-test/main/insert_update.result index 3549aba9446..bfb89449368 100644 --- a/mysql-test/main/insert_update.result +++ b/mysql-test/main/insert_update.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B)); INSERT t1 VALUES (1,2,10), (3,4,20); INSERT t1 VALUES (5,6,30) ON DUPLICATE KEY UPDATE c=c+100; @@ -451,6 +450,26 @@ pk val ts 5 val1 2000-10-20 03:00:00 drop table t1; set timestamp=default; -# # End of 10.4 tests # +# MDEV-38096 Server crashes after INSERT.. ON duplicate KEY UPDATE i = DEFAULT; +# +create sequence s; +create table t1 (i varchar(10) default nextval(s), j text, key(i)); +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (i varchar(10) default nextval(s), j text, key(i)) engine=innodb; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (i varchar(10) default nextval(s), j varchar(10), key(i)) engine=myisam; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (j text default 5, i varchar(10) as (j), key(i)); +insert into t1 set j = (value (j)) on duplicate key update i = default; +insert into t1 set j = (value (j)) on duplicate key update i = default; +drop table t1; +drop sequence s; +# End of 10.11 tests diff --git a/mysql-test/main/insert_update.test b/mysql-test/main/insert_update.test index bb56f04c532..eb8faad4f6c 100644 --- a/mysql-test/main/insert_update.test +++ b/mysql-test/main/insert_update.test @@ -1,6 +1,4 @@ ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings +source include/have_innodb.inc; CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B)); INSERT t1 VALUES (1,2,10), (3,4,20); @@ -335,6 +333,31 @@ select * from t1; drop table t1; set timestamp=default; ---echo # --echo # End of 10.4 tests + --echo # +--echo # MDEV-38096 Server crashes after INSERT.. ON duplicate KEY UPDATE i = DEFAULT; +--echo # +create sequence s; +create table t1 (i varchar(10) default nextval(s), j text, key(i)); +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (i varchar(10) default nextval(s), j text, key(i)) engine=innodb; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (i varchar(10) default nextval(s), j varchar(10), key(i)) engine=myisam; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (j text default 5, i varchar(10) as (j), key(i)); +insert into t1 set j = (value (j)) on duplicate key update i = default; +insert into t1 set j = (value (j)) on duplicate key update i = default; +drop table t1; +drop sequence s; + +--echo # End of 10.11 tests diff --git a/sql/item.cc b/sql/item.cc index da3219d7545..0f7aff680f7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -10123,7 +10123,8 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) Item_field *field_arg= (Item_field *)arg; - if (field_arg->field->table->insert_values) + if (field_arg->field->table->insert_values && + thd->where != THD_WHERE::VALUES_CLAUSE) { Field *def_field= (Field*) thd->alloc(field_arg->field->size_of()); if (!def_field) From 2d12bcd28e9368b650db50f68d82159892567985 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 18 Nov 2025 11:53:15 +0100 Subject: [PATCH 046/152] MDEV-38028 Userstat Plugin CPU_TIME much higher than BUSY_TIME in versions 10.11.X and beyond my_getcputime() returns "cpu time in 1/10th on a microsecond (1e-7 s)" --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e517084def0..1cfca806f36 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1444,7 +1444,7 @@ void THD::update_all_stats() end_cpu_time= my_getcputime(); end_utime= microsecond_interval_timer(); busy_time= end_utime - start_utime; - cpu_time= end_cpu_time - start_cpu_time; + cpu_time= (end_cpu_time - start_cpu_time+5)/10; /* In case there are bad values, 2629743 is the #seconds in a month. */ if (cpu_time > 2629743000000ULL) cpu_time= 0; From 1bb660008f1aa7287f52df5a5671b0f9bb5bb33f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 19 Nov 2025 12:21:15 +0100 Subject: [PATCH 047/152] fix the test to not leave $datadir/test/imp_t1.ibd around otherwise it causes random failures in some later test that lists files in $datadir/test --- mysql-test/suite/innodb/t/import_bugs.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/import_bugs.test b/mysql-test/suite/innodb/t/import_bugs.test index bab4a37e22a..1b7edcf8f73 100644 --- a/mysql-test/suite/innodb/t/import_bugs.test +++ b/mysql-test/suite/innodb/t/import_bugs.test @@ -96,7 +96,7 @@ let $datadir=`select @@datadir`; UNLOCK TABLES; ALTER TABLE t2 DISCARD TABLESPACE; ALTER TABLE t2 ADD c3 INT FIRST; ---copy_file $datadir/test/imp_t1.ibd $datadir/test/t2.ibd +--move_file $datadir/test/imp_t1.ibd $datadir/test/t2.ibd --replace_regex /opening '.*\/test\//opening '.\/test\// ALTER TABLE t2 IMPORT TABLESPACE; From 65bdb573e6b6684ee039f504fca2252923ca8dcb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 24 Nov 2025 15:30:29 +0100 Subject: [PATCH 048/152] MDEV-38168 Lots of joins can crash the server don't let the parser create ridiculously deep joins that will be rejected later anyway --- mysql-test/main/join_optimizer.result | 11 +++++++++-- mysql-test/main/join_optimizer.test | 22 +++++++++++++++++----- sql/sql_yacc.yy | 8 ++++++-- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/mysql-test/main/join_optimizer.result b/mysql-test/main/join_optimizer.result index 238825ec46f..a46e0ed0d99 100644 --- a/mysql-test/main/join_optimizer.result +++ b/mysql-test/main/join_optimizer.result @@ -1,4 +1,3 @@ -drop table if exists t0,t1,t2,t3; # # BUG#38049 incorrect rows estimations with references from preceding table # @@ -56,4 +55,12 @@ explain select * from t1 where col1=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref idx1 idx1 5 const 1 Using index drop table t1; -End of 10.5 tests +# End of 10.5 tests +# +# MDEV-38168 Lots of joins can crash the server +# +create table t1 (x int) engine=innodb; +$many_joins; +ERROR HY000: Too many tables; MariaDB can only use 61 tables in a join +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/join_optimizer.test b/mysql-test/main/join_optimizer.test index 1c55304a2b0..ec93597933e 100644 --- a/mysql-test/main/join_optimizer.test +++ b/mysql-test/main/join_optimizer.test @@ -1,7 +1,3 @@ ---disable_warnings -drop table if exists t0,t1,t2,t3; ---enable_warnings - --source include/have_innodb.inc --echo # @@ -68,4 +64,20 @@ explain select * from t1 where col1=1; drop table t1; ---echo End of 10.5 tests +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-38168 Lots of joins can crash the server +--echo # +create table t1 (x int) engine=innodb; +let $many_joins=SELECT * FROM t1; +let $b=8192; +while ($b) { + let $many_joins=$many_joins JOIN t1 x$b; + dec $b; +} +--error ER_TOO_MANY_TABLES +evalp $many_joins; +drop table t1; + +--echo # End of 10.11 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3517fed44d6..35f81d02942 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11339,8 +11339,12 @@ table_ref: table_factor { $$= $1; } | join_table { - LEX *lex= Lex; - if (unlikely(!($$= lex->current_select->nest_last_join(thd)))) + if (Lex->current_select->table_list.elements > MAX_TABLES) + { + my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast(MAX_TABLES)); + MYSQL_YYABORT; + } + if (!($$= Lex->current_select->nest_last_join(thd))) { thd->parse_error(); MYSQL_YYABORT; From 5e7c391dcbfd415313693dbed811fbc4fd44bf7b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 29 Nov 2025 23:16:55 +0100 Subject: [PATCH 049/152] fix main.mysqld_option_err test that didn't work for years the "Test that bad value for plugin enum option is rejected correctly" needed multiple fixes: 1. don't set plugin-dir based on $MYSQLTEST_VARDIR, all plugins are in var/plugins, but $MYSQLTEST_VARDIR is var/1/, var/2/, etc if --parallel is used (that is, practically always), thus the ha_example.so cannot be loaded, because cannot be found. Test fails with "unknown option --plugin-example-enum" as the plugin is not loaded 2. force --plugin-maturity=experimental, otherwise even if not parallel the plugin will fail to load because of low maturity, test still fails with "unknown option --plugin-example-enum" 3. don't specify .so extension explicitly otherwise the plugin still doesn't load on windows, even if paths and maturity are fixed 4. set --plugin-example=FORCE otherwise plugin fails to load after reading --plugin-example-enum-var=noexist because of unknown enum value, the server ignores the failure and starts normally. the test hangs. 5. This needs the fix in sql_plugin.cc to detect that the plugin is forced even when some options failed to parse. It used to consider plugin forced only if all options parsed correctly, which was wrong. Now the test passes, testing what it was supposed to test - failure to parse an enum value of a plugin option. Without these fixes the test hanged as in 4 when run on the main branch in non-prarallel (e.g. one test only) mode. --- mysql-test/main/mysqld_option_err.result | 1 + mysql-test/main/mysqld_option_err.test | 7 +++++-- sql/sql_plugin.cc | 22 ++++++++++++---------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mysql-test/main/mysqld_option_err.result b/mysql-test/main/mysqld_option_err.result index 157edb58532..85e78fa790d 100644 --- a/mysql-test/main/mysqld_option_err.result +++ b/mysql-test/main/mysqld_option_err.result @@ -14,6 +14,7 @@ FOUND 1 /option '--bootstrap' cannot take an argument/ in mysqltest.log FOUND 1 /Integer value out of range for uint64: '18446744073709551616' for binlog_cache_size/ in mysqltest.log FOUND 1 /Unknown suffix 'y' used for variable 'bulk_insert_buffer_size' \(value '123y'\). Legal suffix characters are: K, M, G, T, P, E/ in mysqltest.log FOUND 1 /Error while setting value '123y' to 'bulk_insert_buffer_size'/ in mysqltest.log +FOUND 1 /Error while setting value 'noexist' to 'plugin-example-enum-var'/ in mysqltest.log Test that --help --verbose works Test that --not-known-option --help --verbose gives error Done. diff --git a/mysql-test/main/mysqld_option_err.test b/mysql-test/main/mysqld_option_err.test index c2b943bafa1..dda0d7e4365 100644 --- a/mysql-test/main/mysqld_option_err.test +++ b/mysql-test/main/mysqld_option_err.test @@ -43,8 +43,8 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; # variable in mysqld command-line option. # See also Bug#32034. --echo Test that bad value for plugin enum option is rejected correctly. ---error 7 ---exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-dir=$MYSQLTEST_VARDIR/plugins --plugin-load=example=ha_example.so --plugin-example-enum-var=noexist >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 +--error 1 +--exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-maturity=experimental --plugin-load=example=ha_example --plugin-example=FORCE --plugin-example-enum-var=noexist >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 --let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log @@ -75,6 +75,9 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --source include/search_pattern_in_file.inc --let SEARCH_PATTERN=Error while setting value '123y' to 'bulk_insert_buffer_size' --source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Error while setting value 'noexist' to 'plugin-example-enum-var' +--source include/search_pattern_in_file.inc + # # Test that an wrong option with --help --verbose gives an error diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 03f89c3de9f..a5ffabc4a37 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -4178,7 +4178,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, int *argc, char **argv) { struct sys_var_chain chain= { NULL, NULL }; - bool disable_plugin; + bool disable_plugin= false; enum_plugin_load_option plugin_load_option= tmp->load_option; MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ? @@ -4286,23 +4286,25 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, error= handle_options(argc, &argv, opts, mark_changed); (*argc)++; /* add back one for the program name */ + /* + Set plugin loading policy from option value. First element in the option + list is always the option value. + */ + if (!plugin_is_forced(tmp)) + { + plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value; + disable_plugin= (plugin_load_option == PLUGIN_OFF); + tmp->load_option= plugin_load_option; + } + if (unlikely(error)) { sql_print_error("Parsing options for plugin '%s' failed. Disabling plugin", tmp->name.str); goto err; } - /* - Set plugin loading policy from option value. First element in the option - list is always the option value. - */ - if (!plugin_is_forced(tmp)) - plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value; } - disable_plugin= (plugin_load_option == PLUGIN_OFF); - tmp->load_option= plugin_load_option; - error= 1; /* From b998e3a7b9508bce339759f01e1d416e44aa4a76 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 2 Dec 2025 19:21:00 +0100 Subject: [PATCH 050/152] MDEV-38203 Hashicorp plugin lets keys timeout and doesn't use cached keys on vault errors * let use_cache_on_timeout apply to other errors * enable use_cache_on_timeout by default and deprecate it * increase cache_timeout to max and deprecate it * change it from long to portable longlong * delete both in 13.3 --- .../hashicorp_key_management_plugin.cc | 24 ++++++++++--------- .../r/hashicorp_cache_timeout_update.result | 4 ++++ .../vault/r/hashicorp_encode.result | 4 ++-- .../vault/r/hashicorp_key_rotation_age.result | 4 ++-- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc index 2c2d96cb1ff..b51bac9e7d5 100644 --- a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc +++ b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc @@ -343,9 +343,11 @@ static int timeout; static int max_retries; static char caching_enabled; static char check_kv_version; -static long cache_timeout; // for KEY_MAP key_info_cache -static long cache_version_timeout; // for VER_MAP latest_version_cache +#if MYSQL_VERSION_ID < 130300 +static long long cache_timeout; // for KEY_MAP key_info_cache static char use_cache_on_timeout; +#endif +static long cache_version_timeout; // for VER_MAP latest_version_cache static MYSQL_SYSVAR_STR(vault_ca, vault_ca, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -391,15 +393,15 @@ static void cache_timeout_update (MYSQL_THD thd, void *var_ptr, const void *save) { - long timeout = * (long *) save; - * (long *) var_ptr = timeout; + long long timeout = * (long long *) save; + * (long long *) var_ptr = timeout; cache_max_time = ms_to_ticks(timeout); } -static MYSQL_SYSVAR_LONG(cache_timeout, cache_timeout, - PLUGIN_VAR_RQCMDARG, +static MYSQL_SYSVAR_LONGLONG(cache_timeout, cache_timeout, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_DEPRECATED, "Cache timeout for key data (in milliseconds)", - NULL, cache_timeout_update, 24*60*60*1000, 0, LONG_MAX, 1); + NULL, cache_timeout_update, INT64_MAX, 0, INT64_MAX, 1); static void cache_version_timeout_update (MYSQL_THD thd, @@ -418,10 +420,10 @@ static MYSQL_SYSVAR_LONG(cache_version_timeout, cache_version_timeout, NULL, cache_version_timeout_update, 60*1000, 0, LONG_MAX, 1); static MYSQL_SYSVAR_BOOL(use_cache_on_timeout, use_cache_on_timeout, - PLUGIN_VAR_RQCMDARG, - "In case of timeout (when accessing the vault server) " + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_DEPRECATED, + "In case of an error when accessing the vault server " "use the value taken from the cache", - NULL, NULL, 0); + NULL, NULL, 1); static struct st_mysql_sys_var *settings[] = { MYSQL_SYSVAR(vault_url), @@ -532,7 +534,7 @@ int HCData::curl_run (const char *url, std::string *response, &http_code)) != CURLE_OK) { curl_easy_cleanup(curl); - if (soft_timeout && curl_res == CURLE_OPERATION_TIMEDOUT) + if (soft_timeout) { return OPERATION_TIMEOUT; } diff --git a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_cache_timeout_update.result b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_cache_timeout_update.result index a26b813a3e7..2e91a7bffa4 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_cache_timeout_update.result +++ b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_cache_timeout_update.result @@ -6,12 +6,16 @@ SELECT SET GLOBAL HASHICORP_KEY_MANAGEMENT_CACHE_VERSION_TIMEOUT= 1, HASHICORP_KEY_MANAGEMENT_CACHE_TIMEOUT= 1; +Warnings: +Warning 1287 '@@hashicorp_key_management_cache_timeout' is deprecated and will be removed in a future release SELECT @@HASHICORP_KEY_MANAGEMENT_CACHE_VERSION_TIMEOUT, @@HASHICORP_KEY_MANAGEMENT_CACHE_TIMEOUT; @@HASHICORP_KEY_MANAGEMENT_CACHE_VERSION_TIMEOUT @@HASHICORP_KEY_MANAGEMENT_CACHE_TIMEOUT 1 1 SET GLOBAL HASHICORP_KEY_MANAGEMENT_CACHE_VERSION_TIMEOUT=0, HASHICORP_KEY_MANAGEMENT_CACHE_TIMEOUT=180000; +Warnings: +Warning 1287 '@@hashicorp_key_management_cache_timeout' is deprecated and will be removed in a future release SELECT @@HASHICORP_KEY_MANAGEMENT_CACHE_VERSION_TIMEOUT, @@HASHICORP_KEY_MANAGEMENT_CACHE_TIMEOUT; diff --git a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_encode.result b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_encode.result index 6264e69a464..802cfe9c460 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_encode.result +++ b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_encode.result @@ -1,12 +1,12 @@ SHOW GLOBAL variables LIKE "hashicorp%"; Variable_name Value -hashicorp_key_management_cache_timeout 86400000 +hashicorp_key_management_cache_timeout 9223372036854775807 hashicorp_key_management_cache_version_timeout 60000 hashicorp_key_management_caching_enabled ON hashicorp_key_management_check_kv_version OFF hashicorp_key_management_max_retries 3 hashicorp_key_management_timeout 60 -hashicorp_key_management_use_cache_on_timeout OFF +hashicorp_key_management_use_cache_on_timeout ON hashicorp_key_management_vault_ca hashicorp_key_management_vault_url VAULT_ADDR/v1/mariadbtest/ create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; diff --git a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_key_rotation_age.result b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_key_rotation_age.result index 969d35262df..d782f7e83fd 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_key_rotation_age.result +++ b/plugin/hashicorp_key_management/mysql-test/vault/r/hashicorp_key_rotation_age.result @@ -1,12 +1,12 @@ SHOW GLOBAL variables LIKE "hashicorp%"; Variable_name Value -hashicorp_key_management_cache_timeout 86400000 +hashicorp_key_management_cache_timeout 9223372036854775807 hashicorp_key_management_cache_version_timeout 0 hashicorp_key_management_caching_enabled ON hashicorp_key_management_check_kv_version OFF hashicorp_key_management_max_retries 3 hashicorp_key_management_timeout 60 -hashicorp_key_management_use_cache_on_timeout OFF +hashicorp_key_management_use_cache_on_timeout ON hashicorp_key_management_vault_ca hashicorp_key_management_vault_url VAULT_ADDR/v1/mariadbtest/ # Restart the server with encryption From 84eec86b37789394af684455af67bda15556c92c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Dec 2025 18:36:05 +0100 Subject: [PATCH 051/152] mysqldump --no-autocommit * put autocommit/commit outside of LOCK/UNLOCK. * use uppercase like all other commands * restore the old value of autocommit --- client/mysqldump.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index d758164c142..f41f8d3567e 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4295,6 +4295,11 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, fprintf(md_result_file,"/*M!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;\n"); check_io(md_result_file); } + if (opt_autocommit) + { + fprintf(md_result_file, "SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0;\n"); + check_io(md_result_file); + } if (opt_lock) { fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table); @@ -4315,11 +4320,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, if (opt_xml) print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table, NullS); - if (opt_autocommit) - { - fprintf(md_result_file, "set autocommit=0;\n"); - check_io(md_result_file); - } while ((row= mysql_fetch_row(res))) { @@ -4589,7 +4589,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, } if (opt_autocommit) { - fprintf(md_result_file, "commit;\n"); + fprintf(md_result_file, "COMMIT;\nSET AUTOCOMMIT=@OLD_AUTOCOMMIT;\n"); check_io(md_result_file); } if (versioned && !opt_xml && opt_dump_history) From 0bfe10e2b797b016ec17919d3ab449cf11798bef Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 5 Dec 2025 20:27:31 +0100 Subject: [PATCH 052/152] MDEV-38087 Unexpected error `Unknown column '???' in 'GROUP BY'` with `ORDER BY number` if the number doesn't refer to a valid result column, use this number in the error message not '???'. --- mysql-test/main/order_by.result | 10 ++++++++++ mysql-test/main/order_by.test | 12 ++++++++++++ mysql-test/main/ps_2myisam.result | 2 +- mysql-test/main/ps_3innodb.result | 2 +- mysql-test/main/ps_4heap.result | 2 +- mysql-test/main/ps_5merge.result | 4 ++-- mysql-test/suite/maria/ps_maria.result | 2 +- sql/sql_select.cc | 8 ++++---- 8 files changed, 32 insertions(+), 10 deletions(-) diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 1e0c6e37cc6..647d41cfb6b 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -4734,3 +4734,13 @@ a b c 6 2 26 6 3 36 drop table t1; +# +# MDEV-38087 Unexpected error `Unknown column '???' in 'GROUP BY'` +# +SELECT 1 FROM (select 1) dt GROUP BY -1; +ERROR 42S22: Unknown column '-1' in 'GROUP BY' +SELECT 1 FROM (select 1) dt order BY -5; +ERROR 42S22: Unknown column '-5' in 'ORDER BY' +SELECT 1 FROM (select 1) dt order BY 50; +ERROR 42S22: Unknown column '50' in 'ORDER BY' +# End of 10.11 tests diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test index 1869b367b69..8caef0b6586 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -2804,3 +2804,15 @@ explain select * from t1 force index(r) order by a,b limit 20; explain select * from t1 force index(r) order by a desc,b limit 20; select * from t1 force index(r) order by a desc,b limit 20; drop table t1; + +--echo # +--echo # MDEV-38087 Unexpected error `Unknown column '???' in 'GROUP BY'` +--echo # +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM (select 1) dt GROUP BY -1; +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM (select 1) dt order BY -5; +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM (select 1) dt order BY 50; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/ps_2myisam.result b/mysql-test/main/ps_2myisam.result index d6552d81cb9..683f6bf3d90 100644 --- a/mysql-test/main/ps_2myisam.result +++ b/mysql-test/main/ps_2myisam.result @@ -440,7 +440,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; diff --git a/mysql-test/main/ps_3innodb.result b/mysql-test/main/ps_3innodb.result index 320d767fecd..85bfc0a269d 100644 --- a/mysql-test/main/ps_3innodb.result +++ b/mysql-test/main/ps_3innodb.result @@ -440,7 +440,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; diff --git a/mysql-test/main/ps_4heap.result b/mysql-test/main/ps_4heap.result index 6c81e1cb0fd..a04f9b2fffe 100644 --- a/mysql-test/main/ps_4heap.result +++ b/mysql-test/main/ps_4heap.result @@ -441,7 +441,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; diff --git a/mysql-test/main/ps_5merge.result b/mysql-test/main/ps_5merge.result index 16c68a3872d..c3cbdd4805b 100644 --- a/mysql-test/main/ps_5merge.result +++ b/mysql-test/main/ps_5merge.result @@ -484,7 +484,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; @@ -3852,7 +3852,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; diff --git a/mysql-test/suite/maria/ps_maria.result b/mysql-test/suite/maria/ps_maria.result index 1cbc46e8943..3dc4f712415 100644 --- a/mysql-test/suite/maria/ps_maria.result +++ b/mysql-test/suite/maria/ps_maria.result @@ -440,7 +440,7 @@ a b 4 four set @arg00=0 ; execute stmt1 using @arg00; -ERROR 42S22: Unknown column '?' in 'ORDER BY' +ERROR 42S22: Unknown column '0' in 'ORDER BY' set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a025b7484b5..5371a9fecad 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -27208,15 +27208,15 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array, if (order_item->is_order_clause_position() && !from_window_spec) { /* Order by position */ - uint count; + int count; if (order->counter_used) count= order->counter; // counter was once resolved else count= (uint) order_item->val_int(); - if (!count || count > fields.elements) + if (count <= 0 || count > (int)fields.elements) { - my_error(ER_BAD_FIELD_ERROR, MYF(0), - order_item->full_name(), thd_where(thd)); + char buf[64]; + my_error(ER_BAD_FIELD_ERROR, MYF(0), llstr(count, buf), thd_where(thd)); return TRUE; } thd->change_item_tree((Item **)&order->item, (Item *)&ref_pointer_array[count - 1]); From 87fdb5ac62dbbf6278595fcc3eed7c8f31350d71 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 26 Dec 2025 13:55:52 +0100 Subject: [PATCH 053/152] MDEV-26618 OPTIMIZE table not replicating restore OPTIMIZE/ANALYZE replication under @read_only that was disabled in b62101f84be4 --- mysql-test/suite/binlog/r/read_only.result | 6 ++++++ mysql-test/suite/binlog/r/read_only_statement.result | 6 ++++++ sql/sql_admin.cc | 3 +-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/binlog/r/read_only.result b/mysql-test/suite/binlog/r/read_only.result index 1084970d11a..065291f6e8f 100644 --- a/mysql-test/suite/binlog/r/read_only.result +++ b/mysql-test/suite/binlog/r/read_only.result @@ -111,6 +111,12 @@ drop table tmp4,tmp5; # row-logged include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; analyze table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; optimize table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; repair table t1 master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL diff --git a/mysql-test/suite/binlog/r/read_only_statement.result b/mysql-test/suite/binlog/r/read_only_statement.result index 1084970d11a..065291f6e8f 100644 --- a/mysql-test/suite/binlog/r/read_only_statement.result +++ b/mysql-test/suite/binlog/r/read_only_statement.result @@ -111,6 +111,12 @@ drop table tmp4,tmp5; # row-logged include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; analyze table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; optimize table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; repair table t1 master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 360bdd408cf..85132722fd6 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1451,8 +1451,7 @@ send_result_message: } thd->resume_subsequent_commits(suspended_wfc); DBUG_EXECUTE_IF("inject_analyze_table_sleep", my_sleep(500000);); - if (is_table_modified && is_cmd_replicated && - (!opt_readonly || thd->slave_thread) && !thd->lex->no_write_to_binlog) + if (is_table_modified && is_cmd_replicated && !thd->lex->no_write_to_binlog) { thd->get_stmt_da()->set_overwrite_status(true); auto res= write_bin_log(thd, true, thd->query(), thd->query_length()); From edda8d54c1c93df22114d7748904acabcc620167 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 26 Dec 2025 16:34:23 +0100 Subject: [PATCH 054/152] MDEV-38133 Package mariadb-common conflicts with mysql-common --- cmake/cpack_rpm.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index e2dad545315..816ce849065 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -210,6 +210,10 @@ SETA(CPACK_RPM_client_PACKAGE_CONFLICTS SETA(CPACK_RPM_common_PACKAGE_CONFLICTS "MariaDB-server < 10.6.1") +SETA(CPACK_RPM_common_PACKAGE_OBSOLETES + "mysql-common") +SETA(CPACK_RPM_common_PACKAGE_PROVIDES + "mysql-common") SETA(CPACK_RPM_devel_PACKAGE_OBSOLETES "MySQL-devel") From 32c846e9fcff6cdbde23dc99326f761251c84255 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Dec 2025 19:56:58 +0100 Subject: [PATCH 055/152] MDEV-38237 Incorrect BuildRequires entry in RHEL10 srpm apparently a file can be present in *more than one* rpm, e.g. /usr/bin/dtrace on rhel10 is present *both* in systemtap-sdt-dtrace and in systemtap-sdt-devel. Make sure there's a separator between entries. --- cmake/build_depends.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/build_depends.cmake b/cmake/build_depends.cmake index 5adaee33740..758ba184628 100644 --- a/cmake/build_depends.cmake +++ b/cmake/build_depends.cmake @@ -32,7 +32,7 @@ IF(RPM) GET_PROPERTY(T CACHE ${V} PROPERTY TYPE) IF ((T STREQUAL FILEPATH OR V MATCHES "^CMAKE_COMMAND$") AND ${V} MATCHES "^/") IF (RPM) - FIND_DEP(${V} rpm -q --qf "%{NAME}" -f ${${V}}) + FIND_DEP(${V} rpm -q --qf "%{NAME} " -f ${${V}}) ELSE() # must be DEB MESSAGE(FATAL_ERROR "Not implemented") ENDIF () From c26d7b9d0f3e5be3f086c8e1d9964f2acd620d3e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 24 Nov 2025 19:33:35 +0100 Subject: [PATCH 056/152] MDEV-36668 main.mysqld--help-aria test failure when no MAC address don't use such a greedy regex_replace pattern --- mysql-test/main/mysqld--help-aria.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/mysqld--help-aria.test b/mysql-test/main/mysqld--help-aria.test index 4f0da282040..6dab8e7f1af 100644 --- a/mysql-test/main/mysqld--help-aria.test +++ b/mysql-test/main/mysqld--help-aria.test @@ -6,7 +6,7 @@ flush tables; --let $args=--table-cache=5 --max-connections=10 --log-warnings=1 --silent-startup --lower-case-table-names=1 --help --verbose --exec $MYSQLD_CMD $args > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --echo # @@ -14,7 +14,7 @@ flush tables; --echo # --exec $MYSQLD_CMD $args --datadir=$MYSQL_TMP_DIR/help > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --echo # @@ -23,7 +23,7 @@ flush tables; --mkdir $MYSQL_TMP_DIR/help --exec $MYSQLD_CMD $args --datadir=$MYSQL_TMP_DIR/help > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --list_files $MYSQL_TMP_DIR/help From 0db178da5ede814c947118a5e1a58138a820e534 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 26 Dec 2025 23:59:01 +0100 Subject: [PATCH 057/152] MDEV-38124 event scheduler spams the error log event scheduler was printing a lot of info in [Note] in error log. change to print its startup/shutdown notes only when log_warnings>0. and runtime notes only when log_warnings>2. one note was an abnormal error, change to [Error]. --- sql/event_data_objects.cc | 5 +++-- sql/event_queue.cc | 9 +++++---- sql/event_scheduler.cc | 32 +++++++++++++++++--------------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 18fa9d43737..4fdfad925a7 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1476,8 +1476,9 @@ end: We must do it here since here we're under the right authentication ID of the event definer. */ - sql_print_information("Event Scheduler: Dropping %s.%s", - (const char *) dbname.str, (const char *) name.str); + if (global_system_variables.log_warnings > 2) + sql_print_information("Event Scheduler: Dropping %s.%s", + dbname.str, name.str); /* Construct a query for the binary log, to ensure the event is dropped on the slave diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 37c2fb52a42..4056ef7da46 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -517,7 +517,7 @@ Event_queue::empty_queue() DBUG_ENTER("Event_queue::empty_queue"); DBUG_PRINT("enter", ("Purging the queue. %u element(s)", queue.elements)); - if (queue.elements) + if (queue.elements && global_system_variables.log_warnings > 2) sql_print_information("Event Scheduler: Purging the queue. %u events", queue.elements); /* empty the queue */ @@ -668,9 +668,10 @@ Event_queue::get_top_for_execution_if_time(THD *thd, if (top->status == Event_parse_data::DISABLED) { DBUG_PRINT("info", ("removing from the queue")); - sql_print_information("Event Scheduler: Last execution of %s.%s. %s", - top->dbname.str, top->name.str, - top->dropped? "Dropping.":""); + if (global_system_variables.log_warnings > 2) + sql_print_information("Event Scheduler: Last execution of %s.%s. %s", + top->dbname.str, top->name.str, + top->dropped? "Dropping.":""); delete top; queue_remove_top(&queue); } diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 0b1b1bfc77c..7ba3c644355 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -319,10 +319,9 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) print_warnings(thd, &job_data); - if (res) - sql_print_information("Event Scheduler: " - "[%s].[%s.%s] event execution failed.", - job_data.definer.str, + if (res && global_system_variables.log_warnings > 2) + sql_print_information("Event Scheduler: [%s].[%s.%s] event execution " + "failed.", job_data.definer.str, job_data.dbname.str, job_data.name.str); end: #ifdef HAVE_PSI_STATEMENT_INTERFACE @@ -471,8 +470,9 @@ Event_scheduler::run(THD *thd) int res= FALSE; DBUG_ENTER("Event_scheduler::run"); - sql_print_information("Event Scheduler: scheduler thread started with id %lu", - (ulong) thd->thread_id); + if (global_system_variables.log_warnings) + sql_print_information("Event Scheduler: scheduler thread started with " + "id %llu", (ulonglong) thd->thread_id); /* Recalculate the values in the queue because there could have been stops in executions of the scheduler and some times could have passed by. @@ -486,9 +486,8 @@ Event_scheduler::run(THD *thd) /* Gets a minimized version */ if (queue->get_top_for_execution_if_time(thd, &event_name)) { - sql_print_information("Event Scheduler: " - "Serious error during getting next " - "event to execute. Stopping"); + sql_print_error("Event Scheduler: Serious error during getting next " + "event to execute. Stopping"); break; } @@ -660,14 +659,16 @@ Event_scheduler::stop() DBUG_PRINT("info", ("Scheduler thread has id %lu", (ulong) scheduler_thd->thread_id)); /* This will wake up the thread if it waits on Queue's conditional */ - sql_print_information("Event Scheduler: Killing the scheduler thread, " - "thread id %lu", - (ulong) scheduler_thd->thread_id); + if (global_system_variables.log_warnings) + sql_print_information("Event Scheduler: Killing the scheduler thread, " + "thread id %llu", + (ulonglong) scheduler_thd->thread_id); scheduler_thd->awake(KILL_CONNECTION); /* thd could be 0x0, when shutting down */ - sql_print_information("Event Scheduler: " - "Waiting for the scheduler thread to reply"); + if (global_system_variables.log_warnings > 1) + sql_print_information("Event Scheduler: " + "Waiting for the scheduler thread to reply"); /* Wait only 2 seconds, as there is a small chance the thread missed the @@ -678,7 +679,8 @@ Event_scheduler::stop() COND_STATE_WAIT(thd, &top_time, &stage_waiting_for_scheduler_to_stop); } while (state == STOPPING); DBUG_PRINT("info", ("Scheduler thread has cleaned up. Set state to INIT")); - sql_print_information("Event Scheduler: Stopped"); + if (global_system_variables.log_warnings) + sql_print_information("Event Scheduler: Stopped"); end: UNLOCK_DATA(); DBUG_RETURN(FALSE); From 0dcec66416b38c6b0a8f75a68704dfa173a91de5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 2 Jan 2026 15:08:57 +0100 Subject: [PATCH 058/152] MDEV-38233 Inconsistent results for make_set of cast if ((res=item->val_str(str)) != str) is incorrect way to detect whether res can be safely used, because Item_char_typecast::val_str() can return res which is different from str, but shares the same buffer. --- mysql-test/main/func_str.result | 9 +++++++ mysql-test/main/func_str.test | 8 ++++++ sql/item_strfunc.cc | 44 ++++++++++++++++----------------- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index c90eb5caee7..a41382d9c43 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5640,4 +5640,13 @@ NULL select group_concat(v) from ( select '$a' as v union all select '$b' as v) t; group_concat(v) a...aaaaa,b...bbbbb +# +# MDEV-38233 Inconsistent results for make_set of cast +# +create table t1 (c1 int); +insert into t1 values (9067); +select cast(make_set(3, cast(c1 as binary), 0) as char) from t1; +cast(make_set(3, cast(c1 as binary), 0) as char) +9067,0 +drop table t1; # End of 10.11 tests diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 05d9a5061c1..d4f494823f1 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2588,4 +2588,12 @@ let $b=`select repeat('b', 65540)`; replace_regex /a{65535}/a.../ /b{65535}/b.../; evalp select group_concat(v) from ( select '$a' as v union all select '$b' as v) t; +--echo # +--echo # MDEV-38233 Inconsistent results for make_set of cast +--echo # +create table t1 (c1 int); +insert into t1 values (9067); +select cast(make_set(3, cast(c1 as binary), 0) as char) from t1; +drop table t1; + --echo # End of 10.11 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e212a350b0d..93bbb9682f4 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3187,32 +3187,32 @@ String *Item_func_make_set::val_str(String *str) if (bits & 1) { String *res= (*ptr)->val_str(str); - if (res) // Skip nulls + if (res) // Skip nulls { - if (!first_found) - { // First argument - first_found=1; - if (res != str) - result=res; // Use original string - else - { - if (tmp_str.copy(*res)) // Don't use 'str' + if (!first_found) + { // First argument + first_found=1; + if (res->ptr() != str->ptr()) + result=res; // Use original string + else + { + if (tmp_str.copy(*res)) // Don't use 'str' return make_empty_result(str); - result= &tmp_str; - } - } - else - { - if (result != &tmp_str) - { // Copy data to tmp_str - if (tmp_str.alloc(result->length()+res->length()+1) || - tmp_str.copy(*result)) + result= &tmp_str; + } + } + else + { + if (result != &tmp_str) + { // Copy data to tmp_str + if (tmp_str.alloc(result->length()+res->length()+1) || + tmp_str.copy(*result)) return make_empty_result(str); - result= &tmp_str; - } - if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res)) + result= &tmp_str; + } + if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res)) return make_empty_result(str); - } + } } } } From 5349220b2e82ea4abe6b39d5c2629ea7c670349b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 7 Nov 2025 20:45:21 +0100 Subject: [PATCH 059/152] MDEV-37979 sys.ps_setup_save does not restore SQL_LOG_BIN after error, causes replication discrepancy --- .../suite/sysschema/r/pr_ps_setup_save.result | 12 ++++++++++++ mysql-test/suite/sysschema/t/pr_ps_setup_save.test | 14 ++++++++++++++ scripts/sys_schema/procedures/ps_setup_save.sql | 12 ++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/sysschema/r/pr_ps_setup_save.result create mode 100644 mysql-test/suite/sysschema/t/pr_ps_setup_save.test diff --git a/mysql-test/suite/sysschema/r/pr_ps_setup_save.result b/mysql-test/suite/sysschema/r/pr_ps_setup_save.result new file mode 100644 index 00000000000..030d325ab4d --- /dev/null +++ b/mysql-test/suite/sysschema/r/pr_ps_setup_save.result @@ -0,0 +1,12 @@ +# +# MDEV-37979 sys.ps_setup_save does not restore SQL_LOG_BIN after error, causes replication discrepancy +# +select @@sql_log_bin; +@@sql_log_bin +1 +call sys.ps_setup_save(-1); +ERROR 90000: Could not lock the sys.ps_setup_save user lock, another thread has a saved configuration +select @@sql_log_bin; +@@sql_log_bin +1 +# End of 10.11 tests diff --git a/mysql-test/suite/sysschema/t/pr_ps_setup_save.test b/mysql-test/suite/sysschema/t/pr_ps_setup_save.test new file mode 100644 index 00000000000..2cd0277bf33 --- /dev/null +++ b/mysql-test/suite/sysschema/t/pr_ps_setup_save.test @@ -0,0 +1,14 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-37979 sys.ps_setup_save does not restore SQL_LOG_BIN after error, causes replication discrepancy +--echo # + +select @@sql_log_bin; + +--error ER_SIGNAL_EXCEPTION +call sys.ps_setup_save(-1); + +select @@sql_log_bin; + +--echo # End of 10.11 tests diff --git a/scripts/sys_schema/procedures/ps_setup_save.sql b/scripts/sys_schema/procedures/ps_setup_save.sql index b7843ecd1f2..71844e781cd 100644 --- a/scripts/sys_schema/procedures/ps_setup_save.sql +++ b/scripts/sys_schema/procedures/ps_setup_save.sql @@ -54,7 +54,7 @@ CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE ps_setup_save ( Query OK, 0 rows affected (0.08 sec) mysql> UPDATE performance_schema.setup_instruments - -> SET enabled = \'YES\', timed = \'YES\'; + -> SET enabled = ''YES'', timed = ''YES''; Query OK, 547 rows affected (0.40 sec) Rows matched: 784 Changed: 547 Warnings: 0 @@ -69,12 +69,12 @@ CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE ps_setup_save ( BEGIN DECLARE v_lock_result INT; - SET @log_bin := @@sql_log_bin; - SET sql_log_bin = 0; - SELECT GET_LOCK('sys.ps_setup_save', in_timeout) INTO v_lock_result; IF v_lock_result THEN + SET @log_bin := @@sql_log_bin; + SET sql_log_bin = 0; + DROP TEMPORARY TABLE IF EXISTS tmp_setup_actors; DROP TEMPORARY TABLE IF EXISTS tmp_setup_consumers; DROP TEMPORARY TABLE IF EXISTS tmp_setup_instruments; @@ -86,12 +86,12 @@ BEGIN CREATE TEMPORARY TABLE tmp_threads (THREAD_ID bigint unsigned NOT NULL PRIMARY KEY, INSTRUMENTED enum('YES','NO') NOT NULL); INSERT INTO tmp_threads SELECT THREAD_ID, INSTRUMENTED FROM performance_schema.threads; + + SET sql_log_bin = @log_bin; ELSE SIGNAL SQLSTATE VALUE '90000' SET MESSAGE_TEXT = 'Could not lock the sys.ps_setup_save user lock, another thread has a saved configuration'; END IF; - - SET sql_log_bin = @log_bin; END$$ DELIMITER ; From 2c983b5ebb3a98fce48d00b7d7793b4264217ae8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 9 Nov 2025 19:36:58 +0100 Subject: [PATCH 060/152] MDEV-38006 Inconsistent behaviors when casting into time number-to-time conversion was too eagerly capping the value. A string "9000090" was invalid time, because of 90 seconds. But number-to-time was capping first, validating later, to 9000090->time worked. Let's fix it. also, let's make invalid time values in a string field include the field name in the warning message, just like invalid time values in a numeric field do. --- mysql-test/main/ctype_latin1.result | 8 +- mysql-test/main/dyncol.result | 4 +- mysql-test/main/func_extract.result | 110 ++--- mysql-test/main/func_hybrid_type.result | 12 +- mysql-test/main/func_time.result | 34 +- mysql-test/main/func_time.test | 10 +- mysql-test/main/func_time_round.result | 381 ++++++++++-------- mysql-test/main/type_binary.result | 62 +-- mysql-test/main/type_bit.result | 62 +-- mysql-test/main/type_bit_innodb.result | 62 +-- mysql-test/main/type_blob.result | 124 +++--- mysql-test/main/type_date.result | 4 +- mysql-test/main/type_date_round.result | 6 +- mysql-test/main/type_datetime.result | 12 +- mysql-test/main/type_datetime_round.result | 6 +- mysql-test/main/type_enum.result | 160 ++++---- mysql-test/main/type_interval.result | 8 +- mysql-test/main/type_set.result | 160 ++++---- mysql-test/main/type_temporal_innodb.result | 12 +- mysql-test/main/type_time.result | 24 +- mysql-test/main/type_time_hires.result | 14 +- mysql-test/main/type_time_round.result | 62 ++- mysql-test/main/type_timestamp.result | 4 +- mysql-test/main/type_timestamp_round.result | 4 +- mysql-test/main/type_varchar.result | 62 +-- .../suite/funcs_1/r/innodb_func_view.result | 192 ++++----- .../suite/funcs_1/r/memory_func_view.result | 192 ++++----- .../suite/funcs_1/r/myisam_func_view.result | 192 ++++----- .../suite/gcol/r/gcol_bug20746926.result | 8 +- .../suite/versioning/r/partition.result | 8 +- sql-common/my_time.c | 26 +- sql/field.cc | 4 +- 32 files changed, 1071 insertions(+), 958 deletions(-) diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index 16c0e6d79ae..1497c53df4d 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -8160,12 +8160,12 @@ SELECT * FROM t1 WHERE (a,a)=('2001-01-01x',DATE'2001-01-01'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=(DATE'2001-01-01','2001-01-01x'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=('2001-01-01',DATE'2001-01-01'); a 2001-01-01 @@ -8185,12 +8185,12 @@ SELECT * FROM t1 WHERE (a,a)=('2001-01-01x',DATE'2001-01-01'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=(DATE'2001-01-01','2001-01-01x'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=('2001-01-01',DATE'2001-01-01'); a 2001-01-01 diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index 562e0ef835b..7c734454c2d 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1427,9 +1427,9 @@ SELECT column_get(column_create(1, -999999999999999 AS int), 1 AS TIME) AS t1, column_get(column_create(1, -9223372036854775808 AS int), 1 AS TIME) AS t2; t1 t2 --838:59:59 -838:59:59 +NULL -838:59:59 Warnings: -Warning 1292 Truncated incorrect time value: '-999999999999999' +Warning 1292 Incorrect time value: '-999999999999999' Warning 1292 Truncated incorrect time value: '-9223372036854775808' # # end of 5.3 tests diff --git a/mysql-test/main/func_extract.result b/mysql-test/main/func_extract.result index 86b6f13a0ed..21961618e22 100644 --- a/mysql-test/main/func_extract.result +++ b/mysql-test/main/func_extract.result @@ -74,16 +74,22 @@ INSERT INTO t1 VALUES # Expect empty sets SELECT a, b, EXTRACT(DAY_HOUR FROM a), EXTRACT(DAY_HOUR FROM b) FROM t1 WHERE NOT (EXTRACT(DAY_HOUR FROM a)<=>EXTRACT(DAY_HOUR FROM b)); a b EXTRACT(DAY_HOUR FROM a) EXTRACT(DAY_HOUR FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(DAY FROM a), EXTRACT(DAY FROM b) FROM t1 WHERE NOT (EXTRACT(DAY FROM a)<=>EXTRACT(DAY FROM b)); a b EXTRACT(DAY FROM a) EXTRACT(DAY FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(HOUR FROM a), EXTRACT(HOUR FROM b) FROM t1 WHERE NOT (EXTRACT(HOUR FROM a)<=>EXTRACT(HOUR FROM b)); a b EXTRACT(HOUR FROM a) EXTRACT(HOUR FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(MINUTE FROM a), EXTRACT(MINUTE FROM b) FROM t1 WHERE NOT (EXTRACT(MINUTE FROM a)<=>EXTRACT(MINUTE FROM b)); a b EXTRACT(MINUTE FROM a) EXTRACT(MINUTE FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(SECOND FROM a), EXTRACT(SECOND FROM b) FROM t1 WHERE NOT (EXTRACT(SECOND FROM a)<=>EXTRACT(SECOND FROM b)); a b EXTRACT(SECOND FROM a) EXTRACT(SECOND FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(MICROSECOND FROM a), EXTRACT(MICROSECOND FROM b) FROM t1 WHERE NOT (EXTRACT(MICROSECOND FROM a)<=>EXTRACT(MICROSECOND FROM b)); a b EXTRACT(MICROSECOND FROM a) EXTRACT(MICROSECOND FROM b) +0.999999 0.999999000 999999 NULL # Detailed results SELECT a, @@ -118,32 +124,32 @@ Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '9999-12-31 23:59:59.123456' Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '2001-01-01 10:20:30.123456' Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 SELECT b, CAST(b AS INTERVAL DAY_SECOND(6)) AS cidm, @@ -166,7 +172,7 @@ b cidm dh EXTRACT(DAY_HOUR FROM b) EXTRACT(DAY FROM b) EXTRACT(HOUR FROM b) EXTR 99995959.123456000 416 15:59:59.123456 9999 41615 416 15 59 59 123456 99990101.123456000 416 15:01:01.123456 9999 41615 416 15 1 1 123456 99990101.000000000 416 15:01:01.000000 9999 41615 416 15 1 1 0 -0.999999000 00:00:00.999999 0 0 0 0 0 0 999999 +0.999999000 00:00:00.999999 NULL NULL NULL NULL NULL NULL NULL 0.999990000 00:00:00.999990 0 0 0 0 0 0 999990 0.999900000 00:00:00.999900 0 0 0 0 0 0 999900 0.999000000 00:00:00.999000 0 0 0 0 0 0 999000 @@ -209,6 +215,14 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99995959.123456000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99990101.123456000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99990101.000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999999000' +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999990000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999900000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999000000' @@ -252,15 +266,15 @@ a cidm EXTRACT(DAY_HOUR FROM a) EXTRACT(DAY_MINUTE FROM a) EXTRACT(DAY_SECOND FR NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; # Backward compatibility # This still parses as DATETIME @@ -568,26 +582,26 @@ EXTRACT(DAY FROM a) EXTRACT(DAY_SECOND FROM a) a cidm 0 10203 01:02:03/ 01:02:03.000000 20 20102030 20 10:20:30 20 10:20:30.000000 Warnings: -Warning 1292 Truncated incorrect time value: '2024:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '2024:01:03 garbage /////' +Warning 1292 Incorrect time value: '2024:01:03 garbage /////' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '2024:01:03 garbage /////' for column `test`.`t1`.`a` at row 1 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '2024:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '24:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '24:01:03 garbage /////' +Warning 1292 Incorrect time value: '24:01:03 garbage /////' for column `test`.`t1`.`a` at row 2 +Warning 1292 Incorrect time value: '24:01:03 garbage /////' for column `test`.`t1`.`a` at row 2 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '24:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:01:03 garbage /////' +Warning 1292 Incorrect time value: '01:01:03 garbage /////' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect time value: '01:01:03 garbage /////' for column `test`.`t1`.`a` at row 3 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '01:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:02:03:' -Warning 1292 Truncated incorrect time value: '01:02:03:' +Warning 1292 Incorrect time value: '01:02:03:' for column `test`.`t1`.`a` at row 8 +Warning 1292 Incorrect time value: '01:02:03:' for column `test`.`t1`.`a` at row 8 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03:' -Warning 1292 Truncated incorrect time value: '01:02:03-' -Warning 1292 Truncated incorrect time value: '01:02:03-' +Warning 1292 Incorrect time value: '01:02:03-' for column `test`.`t1`.`a` at row 9 +Warning 1292 Incorrect time value: '01:02:03-' for column `test`.`t1`.`a` at row 9 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '01:02:03-' -Warning 1292 Truncated incorrect time value: '01:02:03;' -Warning 1292 Truncated incorrect time value: '01:02:03;' +Warning 1292 Incorrect time value: '01:02:03;' for column `test`.`t1`.`a` at row 10 +Warning 1292 Incorrect time value: '01:02:03;' for column `test`.`t1`.`a` at row 10 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03;' -Warning 1292 Truncated incorrect time value: '01:02:03/' -Warning 1292 Truncated incorrect time value: '01:02:03/' +Warning 1292 Incorrect time value: '01:02:03/' for column `test`.`t1`.`a` at row 11 +Warning 1292 Incorrect time value: '01:02:03/' for column `test`.`t1`.`a` at row 11 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03/' DROP TABLE t1; # diff --git a/mysql-test/main/func_hybrid_type.result b/mysql-test/main/func_hybrid_type.result index e7cce49fe47..e1dede07d1a 100644 --- a/mysql-test/main/func_hybrid_type.result +++ b/mysql-test/main/func_hybrid_type.result @@ -3456,8 +3456,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS DATETIME ) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Truncated incorrect datetime value: 'foo' -Warning 1292 Truncated incorrect datetime value: 'bar' +Warning 1292 Incorrect datetime value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect datetime value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; CREATE TABLE t1 (b LONGBLOB); INSERT IGNORE INTO t1 VALUES ('foo'),('bar'); @@ -3465,8 +3465,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS TIME) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Incorrect time value: 'foo' -Warning 1292 Incorrect time value: 'bar' +Warning 1292 Incorrect time value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect time value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; CREATE TABLE t1 (b LONGBLOB); INSERT IGNORE INTO t1 VALUES ('foo'),('bar'); @@ -3474,8 +3474,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS DATE) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Truncated incorrect datetime value: 'foo' -Warning 1292 Truncated incorrect datetime value: 'bar' +Warning 1292 Incorrect datetime value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect datetime value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; # # End of 10.1 tests diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 5b6977d48af..1c1f3b7a329 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -501,12 +501,12 @@ SELECT month(updated) from t1; month(updated) NULL Warnings: -Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`updated` at row 1 SELECT year(updated) from t1; year(updated) NULL Warnings: -Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`updated` at row 1 drop table t1; create table t1 (d date, dt datetime, t timestamp, c char(10)); insert into t1 values ("0000-00-00", "0000-00-00", "0000-00-00", "0000-00-00"); @@ -515,7 +515,7 @@ dayofyear("0000-00-00") dayofyear(d) dayofyear(dt) dayofyear(t) dayofyear(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select dayofmonth("0000-00-00"),dayofmonth(d),dayofmonth(dt),dayofmonth(t),dayofmonth(c) from t1; dayofmonth("0000-00-00") dayofmonth(d) dayofmonth(dt) dayofmonth(t) dayofmonth(c) 0 0 0 0 0 @@ -530,7 +530,7 @@ week("0000-00-00") week(d) week(dt) week(t) week(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select year("0000-00-00"),year(d),year(dt),year(t),year(c) from t1; year("0000-00-00") year(d) year(dt) year(t) year(c) 0 0 0 0 0 @@ -539,13 +539,13 @@ yearweek("0000-00-00") yearweek(d) yearweek(dt) yearweek(t) yearweek(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1; to_days("0000-00-00") to_days(d) to_days(dt) to_days(t) to_days(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1; extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c) 0 0 0 0 0 @@ -1386,9 +1386,9 @@ SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a); COUNT(*) 2 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; # # Bug#11766112 59151:UNINITIALIZED VALUES IN EXTRACT_DATE_TIME WITH STR_TO_DATE(SPACE(..) ... @@ -6435,6 +6435,20 @@ a NULL SET @@time_zone=DEFAULT; DROP TABLE t1; -# # End of 10.5 tests # +# MDEV-38006 Inconsistent behaviors when casting into time +# +create table t1 (c1 char(20), c2 mediumint unsigned); +insert into t1 values (9430886, 9430886), (9430816, 9430816); +select cast(c1 as time), cast(c2 as time) from t1; +cast(c1 as time) cast(c2 as time) +NULL NULL +838:59:59 838:59:59 +Warnings: +Warning 1292 Incorrect time value: '9430886' for column `test`.`t1`.`c1` at row 1 +Warning 1292 Incorrect time value: '9430886' for column `test`.`t1`.`c2` at row 1 +Warning 1292 Incorrect time value: '9430816' for column `test`.`t1`.`c1` at row 2 +Warning 1292 Incorrect time value: '9430816' for column `test`.`t1`.`c2` at row 2 +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index cad21b03788..8b1aafd5580 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -3277,6 +3277,14 @@ SELECT UNIX_TIMESTAMP(MAX(a)) AS a FROM t1; SET @@time_zone=DEFAULT; DROP TABLE t1; ---echo # --echo # End of 10.5 tests + --echo # +--echo # MDEV-38006 Inconsistent behaviors when casting into time +--echo # +create table t1 (c1 char(20), c2 mediumint unsigned); +insert into t1 values (9430886, 9430886), (9430816, 9430816); +select cast(c1 as time), cast(c2 as time) from t1; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/func_time_round.result b/mysql-test/main/func_time_round.result index b335cf393ba..b86457d5046 100644 --- a/mysql-test/main/func_time_round.result +++ b/mysql-test/main/func_time_round.result @@ -98,14 +98,14 @@ GREATEST(TIME'00:00:00', a) 838:59:59.999999 838:59:59.999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 SELECT GREATEST(TIME'00:00:00', a) FROM t1_time_in_decimal; GREATEST(TIME'00:00:00', a) 00:00:00.000000 @@ -114,23 +114,27 @@ GREATEST(TIME'00:00:00', a) 00:00:00.999000 00:00:00.999900 00:00:00.999990 -00:00:00.999999 -00:00:01.000000 -838:00:00.000000 +NULL +NULL +NULL 838:59:59.000000 838:59:59.900000 838:59:59.990000 838:59:59.999000 838:59:59.999900 838:59:59.999990 -838:59:59.999999 -838:59:59.999999 -838:59:59.999999 +NULL +NULL +NULL NULL NULL NULL NULL Warnings: +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 Warning 1292 Incorrect time value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 @@ -167,8 +171,8 @@ SECOND(a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MINUTE(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; MINUTE(a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -180,8 +184,8 @@ MINUTE(a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT HOUR(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; HOUR(a) CAST(a AS TIME(6)) a 23 23:59:59.000000 2000-12-31 23:59:59 @@ -193,8 +197,8 @@ HOUR(a) CAST(a AS TIME(6)) a 23 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(SECOND FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(SECOND FROM a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -206,8 +210,8 @@ EXTRACT(SECOND FROM a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(MINUTE FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(MINUTE FROM a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -219,8 +223,8 @@ EXTRACT(MINUTE FROM a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(HOUR FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(HOUR FROM a) CAST(a AS TIME(6)) a 23 23:59:59.000000 2000-12-31 23:59:59 @@ -232,8 +236,8 @@ EXTRACT(HOUR FROM a) CAST(a AS TIME(6)) a 23 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; TIME_TO_SEC(a) CAST(a AS TIME(6)) a 86399.000000 23:59:59.000000 2000-12-31 23:59:59 @@ -245,8 +249,8 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 86399.999999 23:59:59.999999 2000-12-31 23:59:59.999999 0.000000 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 # # Functions with a single TIME input, conversion from DATETIME-in-DECIMAL # @@ -356,41 +360,41 @@ EXTRACT(DAY FROM a) EXTRACT(HOUR FROM a) EXTRACT(MINUTE FROM a) EXTRACT(SECOND F 3652058 23 59 59 999999 3652058 23:59:59.999999 87649415:59:59.999999 3652058 23 59 59 999999 3652058 23:59:59.999999 87649415:59:59.9999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649415:59:59.9999999' SELECT TIME_TO_SEC(a), @@ -421,22 +425,22 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 3020399.999999 838:59:59.999999 87649415:59:59.999999 3020399.999999 838:59:59.999999 87649415:59:59.9999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 # # Functions with a single TIME interval input, conversion from TIME-interval-in-DECIMAL # @@ -456,22 +460,22 @@ EXTRACT(DAY FROM a) EXTRACT(HOUR FROM a) EXTRACT(MINUTE FROM a) EXTRACT(SECOND F 0 0 0 0 999000 00:00:00.999000 0.9990000000 0 0 0 0 999900 00:00:00.999900 0.9999000000 0 0 0 0 999990 00:00:00.999990 0.9999900000 -0 0 0 0 999999 00:00:00.999999 0.9999990000 -0 0 0 1 0 00:00:01.000000 0.9999999000 -34 22 0 0 0 34 22:00:00.000000 8375959.9999999000 +NULL NULL NULL NULL NULL 00:00:00.999999 0.9999990000 +NULL NULL NULL NULL NULL 00:00:01.000000 0.9999999000 +NULL NULL NULL NULL NULL 34 22:00:00.000000 8375959.9999999000 34 22 59 59 0 34 22:59:59.000000 8385959.0000000000 34 22 59 59 900000 34 22:59:59.900000 8385959.9000000000 34 22 59 59 990000 34 22:59:59.990000 8385959.9900000000 34 22 59 59 999000 34 22:59:59.999000 8385959.9990000000 34 22 59 59 999900 34 22:59:59.999900 8385959.9999000000 34 22 59 59 999990 34 22:59:59.999990 8385959.9999900000 -34 22 59 59 999999 34 22:59:59.999999 8385959.9999990000 -34 23 0 0 0 34 23:00:00.000000 8385959.9999999000 -35 0 0 0 0 35 00:00:00.000000 8395959.9999999000 -3652058 22 59 59 999999 3652058 22:59:59.999999 876494145959.9999990000 -3652058 23 0 0 0 3652058 23:00:00.000000 876494145959.9999999000 -3652058 23 59 59 999999 3652058 23:59:59.999999 876494155959.9999990000 -3652058 23 59 59 999999 3652058 23:59:59.999999 876494155959.9999999000 +NULL NULL NULL NULL NULL 34 22:59:59.999999 8385959.9999990000 +NULL NULL NULL NULL NULL 34 23:00:00.000000 8385959.9999999000 +NULL NULL NULL NULL NULL 35 00:00:00.000000 8395959.9999999000 +NULL NULL NULL NULL NULL 3652058 22:59:59.999999 876494145959.9999990000 +NULL NULL NULL NULL NULL 3652058 23:00:00.000000 876494145959.9999999000 +NULL NULL NULL NULL NULL 3652058 23:59:59.999999 876494155959.9999990000 +NULL NULL NULL NULL NULL 3652058 23:59:59.999999 876494155959.9999999000 Warnings: Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.0000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9000000000' @@ -479,8 +483,23 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9900000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9990000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999900000' +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999990000' +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999999000' +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8375959.9999999000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.0000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9000000000' @@ -488,18 +507,40 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9900000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9990000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999900000' +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999990000' +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999999000' +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8395959.9999999000' +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494145959.9999990000' +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494145959.9999999000' -Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494155959.9999990000' -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '876494155959.9999999000' +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), @@ -512,23 +553,31 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 0.999000 00:00:00.999000 0.9990000000 0.999900 00:00:00.999900 0.9999000000 0.999990 00:00:00.999990 0.9999900000 -0.999999 00:00:00.999999 0.9999990000 -1.000000 00:00:01.000000 0.9999999000 -3016800.000000 838:00:00.000000 8375959.9999999000 +NULL NULL 0.9999990000 +NULL NULL 0.9999999000 +NULL NULL 8375959.9999999000 3020399.000000 838:59:59.000000 8385959.0000000000 3020399.900000 838:59:59.900000 8385959.9000000000 3020399.990000 838:59:59.990000 8385959.9900000000 3020399.999000 838:59:59.999000 8385959.9990000000 3020399.999900 838:59:59.999900 8385959.9999000000 3020399.999990 838:59:59.999990 8385959.9999900000 -3020399.999999 838:59:59.999999 8385959.9999990000 -3020399.999999 838:59:59.999999 8385959.9999999000 -3020399.999999 838:59:59.999999 8395959.9999999000 +NULL NULL 8385959.9999990000 +NULL NULL 8385959.9999999000 +NULL NULL 8395959.9999999000 NULL NULL 876494145959.9999990000 NULL NULL 876494145959.9999999000 NULL NULL 876494155959.9999990000 NULL NULL 876494155959.9999999000 Warnings: +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 @@ -555,8 +604,8 @@ QUARTER(a) CAST(a AS DATE) a 4 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAY(a) CAST(a AS DATE) a 31 2000-12-31 2000-12-31 23:59:59 @@ -568,8 +617,8 @@ DAY(a) CAST(a AS DATE) a 31 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MONTH(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; MONTH(a) CAST(a AS DATE) a 12 2000-12-31 2000-12-31 23:59:59 @@ -581,8 +630,8 @@ MONTH(a) CAST(a AS DATE) a 12 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT YEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; YEAR(a) CAST(a AS DATE) a 2000 2000-12-31 2000-12-31 23:59:59 @@ -594,8 +643,8 @@ YEAR(a) CAST(a AS DATE) a 2000 2000-12-31 2000-12-31 23:59:59.999999 2001 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAYNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAYNAME(a) CAST(a AS DATE) a Sunday 2000-12-31 2000-12-31 23:59:59 @@ -607,8 +656,8 @@ Sunday 2000-12-31 2000-12-31 23:59:59.99999 Sunday 2000-12-31 2000-12-31 23:59:59.999999 Monday 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MONTHNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; MONTHNAME(a) CAST(a AS DATE) a December 2000-12-31 2000-12-31 23:59:59 @@ -620,8 +669,8 @@ December 2000-12-31 2000-12-31 23:59:59.99999 December 2000-12-31 2000-12-31 23:59:59.999999 January 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT LAST_DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; LAST_DAY(a) CAST(a AS DATE) a 2000-12-31 2000-12-31 2000-12-31 23:59:59 @@ -633,8 +682,8 @@ LAST_DAY(a) CAST(a AS DATE) a 2000-12-31 2000-12-31 2000-12-31 23:59:59.999999 2000-12-31 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT TO_DAYS(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; TO_DAYS(a) CAST(a AS DATE) a 730850 2000-12-31 2000-12-31 23:59:59 @@ -646,8 +695,8 @@ TO_DAYS(a) CAST(a AS DATE) a 730850 2000-12-31 2000-12-31 23:59:59.999999 730851 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAYOFYEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAYOFYEAR(a) CAST(a AS DATE) a 366 2000-12-31 2000-12-31 23:59:59 @@ -659,8 +708,8 @@ DAYOFYEAR(a) CAST(a AS DATE) a 366 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 CREATE TABLE t1 (a VARCHAR(32)); INSERT INTO t1 VALUES ('2002-01-05 23:59:59'), @@ -672,21 +721,21 @@ YEARWEEK(a) a 200152 2002-01-05 23:59:59.999999 200201 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 SELECT WEEK(a), a FROM t1; WEEK(a) a 0 2002-01-05 23:59:59 0 2002-01-05 23:59:59.999999 1 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 SELECT WEEKDAY(a), a FROM t1; WEEKDAY(a) a 5 2002-01-05 23:59:59 5 2002-01-05 23:59:59.999999 6 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(32,9)); INSERT INTO t1 VALUES @@ -836,8 +885,8 @@ TO_SECONDS(a) CAST(a AS DATETIME(6)) a 63145526399 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 63145526400 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SET time_zone='+00:00'; SELECT UNIX_TIMESTAMP(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; UNIX_TIMESTAMP(a) CAST(a AS DATETIME(6)) a @@ -850,8 +899,8 @@ UNIX_TIMESTAMP(a) CAST(a AS DATETIME(6)) a 978307199.999999 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 978307200.000000 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SET time_zone=DEFAULT; SELECT CONVERT_TZ(a, '+00:00','+00:00'), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; CONVERT_TZ(a, '+00:00','+00:00') CAST(a AS DATETIME(6)) a @@ -864,8 +913,8 @@ CONVERT_TZ(a, '+00:00','+00:00') CAST(a AS DATETIME(6)) a 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 2001-01-01 00:00:00.000000 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 # # Functions with a single DATETIME input, conversion from DATETIME-in-DECIMAL # @@ -1049,22 +1098,22 @@ dt6 2018-01-01 00:00:00.000000 Warnings: Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(32,9)); INSERT INTO t1 VALUES @@ -1149,13 +1198,13 @@ TIMESTAMP(t1.a, t2.a) a a 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 00:00:00.999999 2018-01-01 00:00:01.000000 2017-12-31 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' SELECT ADDTIME(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a; ADDTIME(t1.a, t2.a) a a @@ -1176,13 +1225,13 @@ ADDTIME(t1.a, t2.a) a a 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 00:00:00.999999 2018-01-01 00:00:01 2017-12-31 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); @@ -1216,14 +1265,14 @@ TIMEDIFF(t1.a, t2.a) a a 23:59:59.000001 23:59:59.9999999 00:00:00.999999 23:59:59.000000 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); CREATE TABLE t2 (a VARCHAR(64)); @@ -1256,14 +1305,14 @@ TIMESTAMPDIFF(MICROSECOND,t1.a, t2.a) a a -1 2001-12-31 23:59:59.9999999 2001-12-31 23:59:59.999999 0 2001-12-31 23:59:59.9999999 2001-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); CREATE TABLE t2 (a VARCHAR(64)); @@ -1296,14 +1345,14 @@ TIMEDIFF(t1.a, t2.a) a a 23:59:59.000001 23:59:59.9999999 00:00:00.999999 23:59:59.000000 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; # # STR_TO_DATE behaviour is questionable in MySQL 5.6 (MySQL Bug #92474) @@ -1367,8 +1416,8 @@ a b DATE_ADD(a, INTERVAL b SECOND) 2017-12-31 23:59:59.9999999 0.999999000 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 0.999999900 2018-01-01 00:00:00.999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 DROP TABLE t1, t2; diff --git a/mysql-test/main/type_binary.result b/mysql-test/main/type_binary.result index 32593cb728b..43af3ac7bd2 100644 --- a/mysql-test/main/type_binary.result +++ b/mysql-test/main/type_binary.result @@ -261,37 +261,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `varchar` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: diff --git a/mysql-test/main/type_bit.result b/mysql-test/main/type_bit.result index 543e46b6270..24d96d80ef3 100644 --- a/mysql-test/main/type_bit.result +++ b/mysql-test/main/type_bit.result @@ -1936,37 +1936,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bit` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: diff --git a/mysql-test/main/type_bit_innodb.result b/mysql-test/main/type_bit_innodb.result index fc932c8749e..645ee2cec31 100644 --- a/mysql-test/main/type_bit_innodb.result +++ b/mysql-test/main/type_bit_innodb.result @@ -456,37 +456,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bit` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result index 14685bcf149..fb6132e74b7 100644 --- a/mysql-test/main/type_blob.result +++ b/mysql-test/main/type_blob.result @@ -1200,37 +1200,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `blob` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: @@ -1281,37 +1281,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `blob` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index 2dee720e3e4..3e77500977b 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -1271,8 +1271,8 @@ INSERT INTO t2 VALUES (0x30),(0x31); SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: -Warning 1292 Incorrect datetime value: '0' -Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t2`.`not_indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '1' for column `test`.`t2`.`not_indexed_col` at row 1 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARCHAR(32)); INSERT INTO t2 VALUES ('2001-01-01'),('2001-01-02'); diff --git a/mysql-test/main/type_date_round.result b/mysql-test/main/type_date_round.result index 0da78c6afe5..c7bd1c53c93 100644 --- a/mysql-test/main/type_date_round.result +++ b/mysql-test/main/type_date_round.result @@ -54,7 +54,7 @@ INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999'); ALTER TABLE t1 MODIFY a DATE; Warnings: Note 1265 Data truncated for column 'a' at row 1 -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 2 Note 1265 Data truncated for column 'a' at row 2 SELECT a FROM t1; a @@ -90,7 +90,7 @@ a CAST(a AS DATE) 2000-12-31 23:59:59.9999 2000-12-31 2000-12-31 23:59:59.9999999 2000-12-31 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(38,10)); INSERT INTO t1 VALUES(20001231235959.9999); @@ -151,7 +151,7 @@ SELECT * FROM t1 WHERE a=DATE'2001-01-02'; a 2001-01-01 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2001-01-01 23:59:59.9999999' for column `test`.`t1`.`a` at row 1 SELECT * FROM t1 WHERE CONCAT(a)=DATE'2001-01-02'; a 2001-01-01 23:59:59.9999999 diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 043b6ad6c5a..9b9c46ad23f 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -1571,15 +1571,15 @@ pk 17 18 Warnings: -Warning 1292 Truncated incorrect datetime value: '' -Warning 1292 Truncated incorrect datetime value: 'k' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect datetime value: 'k' for column `test`.`t1`.`x2` at row 2 SELECT pk FROM v1 WHERE x1 >x2; pk 17 18 Warnings: -Warning 1292 Truncated incorrect datetime value: '' -Warning 1292 Truncated incorrect datetime value: 'k' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect datetime value: 'k' for column `test`.`t1`.`x2` at row 2 DROP VIEW v1; DROP TABLE t1; # @@ -1692,8 +1692,8 @@ INSERT INTO t2 VALUES (0x30),(0x31); SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: -Warning 1292 Incorrect datetime value: '0' -Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t2`.`not_indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '1' for column `test`.`t2`.`not_indexed_col` at row 1 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARCHAR(32)); INSERT INTO t2 VALUES ('2001-01-01'),('2001-01-02'); diff --git a/mysql-test/main/type_datetime_round.result b/mysql-test/main/type_datetime_round.result index c6584223268..177ca05ccf4 100644 --- a/mysql-test/main/type_datetime_round.result +++ b/mysql-test/main/type_datetime_round.result @@ -45,7 +45,7 @@ INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999'); INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999'); ALTER TABLE t1 MODIFY a DATETIME(3); Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 2 SELECT a FROM t1; a 2001-01-01 00:00:00.000 @@ -116,7 +116,7 @@ a CAST(a AS DATETIME(3)) 2000-12-31 23:59:59.9999 2001-01-01 00:00:00.000 2000-12-31 23:59:59.9999999 2001-01-01 00:00:00.000 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(38,10)); INSERT INTO t1 VALUES(20001231235959.9999); @@ -174,7 +174,7 @@ SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-02 00:00:00'; a 2001-01-01 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2001-01-01 23:59:59.9999999' for column `test`.`t1`.`a` at row 1 SELECT * FROM t1 WHERE CONCAT(a)=TIMESTAMP'2001-01-02 00:00:00'; a 2001-01-01 23:59:59.9999999 diff --git a/mysql-test/main/type_enum.result b/mysql-test/main/type_enum.result index b3ef6b5b56f..f5c6dbae2ad 100644 --- a/mysql-test/main/type_enum.result +++ b/mysql-test/main/type_enum.result @@ -2399,16 +2399,16 @@ SELECT * FROM t1 WHERE indexed_col=DATE'2001-01-01'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `enum` = "DATE'2001-01-01'" of type `date` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: @@ -2417,16 +2417,16 @@ SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `enum` = "TIMESTAMP'2001-01-01 10:20:30'" of type `datetime` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 SELECT * FROM t1 WHERE indexed_col=0x00; indexed_col SELECT * FROM t1 WHERE indexed_col=_utf8mb3'0' COLLATE utf8mb3_bin; @@ -2474,26 +2474,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `enum` = "`t2`.`not_indexed_col`" of type `date` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col DATETIME); INSERT INTO t2 VALUES ('2023-01-01 00:00:00'),('2023-01-01 00:00:01'); @@ -2501,26 +2501,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `enum` = "`t2`.`not_indexed_col`" of type `datetime` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col TIMESTAMP); INSERT INTO t2 VALUES ('2023-01-01 00:00:00'),('2023-01-01 00:00:01'); @@ -2528,26 +2528,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `enum` = "`t2`.`not_indexed_col`" of type `timestamp` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARBINARY(32)); INSERT INTO t2 VALUES (0x30),(0x31); diff --git a/mysql-test/main/type_interval.result b/mysql-test/main/type_interval.result index 65c84022210..32b4de43b45 100644 --- a/mysql-test/main/type_interval.result +++ b/mysql-test/main/type_interval.result @@ -34,11 +34,11 @@ d h a cast_itds NULL NULL 87649416:00:00 NULL NULL NULL 3652059 00:00:00 NULL Warnings: -Warning 1292 Incorrect interval value: '87649416:00:00' -Warning 1292 Incorrect interval value: '87649416:00:00' +Warning 1292 Incorrect interval value: '87649416:00:00' for column `test`.`t1`.`a` at row 9 +Warning 1292 Incorrect interval value: '87649416:00:00' for column `test`.`t1`.`a` at row 9 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649416:00:00' -Warning 1292 Incorrect interval value: '3652059 00:00:00' -Warning 1292 Incorrect interval value: '3652059 00:00:00' +Warning 1292 Incorrect interval value: '3652059 00:00:00' for column `test`.`t1`.`a` at row 10 +Warning 1292 Incorrect interval value: '3652059 00:00:00' for column `test`.`t1`.`a` at row 10 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '3652059 00:00:00' DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(32,9)); diff --git a/mysql-test/main/type_set.result b/mysql-test/main/type_set.result index e5e0426ba7d..e35aa66f9b6 100644 --- a/mysql-test/main/type_set.result +++ b/mysql-test/main/type_set.result @@ -489,16 +489,16 @@ SELECT * FROM t1 WHERE indexed_col=DATE'2001-01-01'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `set` = "DATE'2001-01-01'" of type `date` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: @@ -507,16 +507,16 @@ SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `set` = "TIMESTAMP'2001-01-01 10:20:30'" of type `datetime` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 SELECT * FROM t1 WHERE indexed_col=0x00; indexed_col SELECT * FROM t1 WHERE indexed_col=_utf8mb3'0' COLLATE utf8mb3_bin; @@ -564,26 +564,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `set` = "`t2`.`not_indexed_col`" of type `date` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col DATETIME); INSERT INTO t2 VALUES ('2023-01-01 00:00:00'),('2023-01-01 00:00:01'); @@ -591,26 +591,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `set` = "`t2`.`not_indexed_col`" of type `datetime` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col TIMESTAMP); INSERT INTO t2 VALUES ('2023-01-01 00:00:00'),('2023-01-01 00:00:01'); @@ -618,26 +618,26 @@ SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `set` = "`t2`.`not_indexed_col`" of type `timestamp` -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' -Warning 1292 Truncated incorrect datetime value: '2001' -Warning 1292 Truncated incorrect datetime value: '2002' -Warning 1292 Truncated incorrect datetime value: '2003' -Warning 1292 Truncated incorrect datetime value: '2004' -Warning 1292 Truncated incorrect datetime value: '2005' -Warning 1292 Truncated incorrect datetime value: '2006' -Warning 1292 Truncated incorrect datetime value: '2007' -Warning 1292 Truncated incorrect datetime value: '2008' -Warning 1292 Truncated incorrect datetime value: '2009' -Warning 1292 Truncated incorrect datetime value: '2010' +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect datetime value: '2001' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '2002' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect datetime value: '2003' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect datetime value: '2004' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect datetime value: '2005' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect datetime value: '2006' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect datetime value: '2007' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect datetime value: '2008' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect datetime value: '2009' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect datetime value: '2010' for column `test`.`t1`.`indexed_col` at row 10 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARBINARY(32)); INSERT INTO t2 VALUES (0x30),(0x31); diff --git a/mysql-test/main/type_temporal_innodb.result b/mysql-test/main/type_temporal_innodb.result index f801baceb83..110b9d3c4af 100644 --- a/mysql-test/main/type_temporal_innodb.result +++ b/mysql-test/main/type_temporal_innodb.result @@ -24,7 +24,7 @@ SELECT * FROM t1 WHERE a=b; a b c 00:00:00 0 Warnings: -Warning 1292 Truncated incorrect time value: '' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 @@ -45,7 +45,7 @@ SELECT * FROM t1 WHERE a=b; a b c 00:00:00 0 Warnings: -Warning 1292 Truncated incorrect time value: '' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 @@ -75,7 +75,7 @@ SELECT * FROM t1 WHERE a=b; a b c 0000-00-00 0 Warnings: -Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 @@ -96,7 +96,7 @@ SELECT * FROM t1 WHERE a=b; a b c 0000-00-00 0 Warnings: -Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 @@ -126,7 +126,7 @@ SELECT * FROM t1 WHERE a=b; a b c 0000-00-00 00:00:00 0 Warnings: -Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 @@ -147,7 +147,7 @@ SELECT * FROM t1 WHERE a=b; a b c 0000-00-00 00:00:00 0 Warnings: -Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`a` at row 1 SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b; 1 1 diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result index dc5ebc46c0f..c8c23c52e1a 100644 --- a/mysql-test/main/type_time.result +++ b/mysql-test/main/type_time.result @@ -2217,15 +2217,15 @@ pk 17 70 Warnings: -Warning 1292 Truncated incorrect time value: 'k' -Warning 1292 Truncated incorrect time value: 'k' +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 2 SELECT pk FROM v1 WHERE x1 >x2; pk 17 70 Warnings: -Warning 1292 Truncated incorrect time value: 'k' -Warning 1292 Truncated incorrect time value: 'k' +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 2 DROP VIEW v1; DROP TABLE t1; CREATE TABLE t1 (pk int, x1 time, x2 varchar(1)); @@ -2236,15 +2236,15 @@ pk 17 70 Warnings: -Warning 1292 Truncated incorrect time value: '' -Warning 1292 Truncated incorrect time value: 'k' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 2 SELECT pk FROM v1 WHERE x1 >x2; pk 17 70 Warnings: -Warning 1292 Truncated incorrect time value: '' -Warning 1292 Truncated incorrect time value: 'k' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`x2` at row 1 +Warning 1292 Incorrect time value: 'k' for column `test`.`t1`.`x2` at row 2 DROP VIEW IF EXISTS v1; DROP TABLE IF EXISTS t1; # @@ -2591,16 +2591,16 @@ INSERT INTO t2 VALUES ('2001-01-01'),('2001-01-02'); SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: -Warning 1292 Truncated incorrect time value: '2001-01-01' -Warning 1292 Truncated incorrect time value: '2001-01-02' +Warning 1292 Incorrect time value: '2001-01-01' for column `test`.`t2`.`not_indexed_col` at row 1 +Warning 1292 Incorrect time value: '2001-01-02' for column `test`.`t2`.`not_indexed_col` at row 1 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARCHAR(32) CHARACTER SET utf8mb3); INSERT INTO t2 VALUES ('2001-01-01'),('2001-01-02'); SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: -Warning 1292 Truncated incorrect time value: '2001-01-01' -Warning 1292 Truncated incorrect time value: '2001-01-02' +Warning 1292 Incorrect time value: '2001-01-01' for column `test`.`t2`.`not_indexed_col` at row 1 +Warning 1292 Incorrect time value: '2001-01-02' for column `test`.`t2`.`not_indexed_col` at row 1 DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; diff --git a/mysql-test/main/type_time_hires.result b/mysql-test/main/type_time_hires.result index a5270c98c24..8dba6ce58b1 100644 --- a/mysql-test/main/type_time_hires.result +++ b/mysql-test/main/type_time_hires.result @@ -17,46 +17,46 @@ Warnings: Note 1265 Data truncated for column 'a' at row 1 insert ignore t1 values (99991231235959e1); Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +Warning 1265 Data truncated for column 'a' at row 1 select * from t1; a +00:00:00.000 00:20:03.123 01:02:03.456 03:04:05.789 15:47:11.123 -838:59:59.999 select cast(a AS double(30,6)) from t1; cast(a AS double(30,6)) +0.000000 2003.123000 10203.456000 30405.789062 154711.123000 -8385959.999000 select a DIV 1 from t1; a DIV 1 +0 2003 10203 30405 154711 -8385959 select group_concat(distinct a) from t1; group_concat(distinct a) -00:20:03.123,01:02:03.456,03:04:05.789,15:47:11.123,838:59:59.999 +00:00:00.000,00:20:03.123,01:02:03.456,03:04:05.789,15:47:11.123 alter table t1 engine=innodb; select * from t1 order by a; a +00:00:00.000 00:20:03.123 01:02:03.456 03:04:05.789 15:47:11.123 -838:59:59.999 select * from t1 order by a+0; a +00:00:00.000 00:20:03.123 01:02:03.456 03:04:05.789 15:47:11.123 -838:59:59.999 drop table t1; create table t1 (a time(4)) engine=innodb; insert t1 values ('2010-12-11 01:02:03.456789'); diff --git a/mysql-test/main/type_time_round.result b/mysql-test/main/type_time_round.result index 31e97c888db..e1b52622d48 100644 --- a/mysql-test/main/type_time_round.result +++ b/mysql-test/main/type_time_round.result @@ -25,19 +25,23 @@ CREATE TABLE t1 (a TIME(3), b DECIMAL(38,10)); INSERT INTO t1 VALUES(NULL,0.9999); INSERT INTO t1 VALUES(NULL,0.9999999); UPDATE t1 SET a=b; +Warnings: +Warning 1265 Data truncated for column 'a' at row 2 SELECT a FROM t1; a 00:00:01.000 -00:00:01.000 +00:00:00.000 DROP TABLE t1; CREATE TABLE t1 (a TIME(3), b DOUBLE); INSERT INTO t1 VALUES(NULL,0.9999); INSERT INTO t1 VALUES(NULL,0.9999999); UPDATE t1 SET a=b; +Warnings: +Warning 1265 Data truncated for column 'a' at row 2 SELECT a FROM t1; a 00:00:01.000 -00:00:01.000 +00:00:00.000 DROP TABLE t1; CREATE TABLE t1 (a TIME(6), b VARCHAR(64)); INSERT INTO t1 VALUES(NULL,'00:00:00.9999999'); @@ -51,16 +55,20 @@ DROP TABLE t1; CREATE TABLE t1 (a TIME(6), b DECIMAL(38,10)); INSERT INTO t1 VALUES(NULL,0.9999999); UPDATE t1 SET a=b; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 SELECT a FROM t1; a -00:00:01.000000 +00:00:00.000000 DROP TABLE t1; CREATE TABLE t1 (a TIME(6), b DOUBLE); INSERT INTO t1 VALUES(NULL,0.9999999); UPDATE t1 SET a=b; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 SELECT a FROM t1; a -00:00:01.000000 +00:00:00.000000 DROP TABLE t1; # # TIME: ALTER @@ -77,7 +85,7 @@ INSERT INTO t1 VALUES('00:00:00.9999'); INSERT INTO t1 VALUES('00:00:00.9999999'); ALTER TABLE t1 MODIFY a TIME(3); Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1`.`a` at row 2 SELECT a FROM t1; a 00:00:01.000 @@ -87,10 +95,12 @@ CREATE TABLE t1 (a DECIMAL(38,10)); INSERT INTO t1 VALUES(0.9999); INSERT INTO t1 VALUES(0.9999999); ALTER TABLE t1 MODIFY a TIME(3); +Warnings: +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1`.`a` at row 2 SELECT a FROM t1; a 00:00:01.000 -00:00:01.000 +00:00:00.000 DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); INSERT INTO t1 VALUES(0.9999); @@ -120,7 +130,7 @@ a CAST(a AS TIME(3)) 00:00:00.9999 00:00:01.000 00:00:00.9999999 00:00:01.000 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(38,10)); INSERT INTO t1 VALUES(0.9999); @@ -128,7 +138,9 @@ INSERT INTO t1 VALUES(0.9999999); SELECT a, CAST(a AS TIME(3)) FROM t1; a CAST(a AS TIME(3)) 0.9999000000 00:00:01.000 -0.9999999000 00:00:01.000 +0.9999999000 NULL +Warnings: +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); INSERT INTO t1 VALUES(0.9999); @@ -136,7 +148,9 @@ INSERT INTO t1 VALUES(0.9999999); SELECT a, CAST(a AS TIME(3)) FROM t1; a CAST(a AS TIME(3)) 0.9999 00:00:01.000 -0.9999999 00:00:01.000 +0.9999999 NULL +Warnings: +Warning 1292 Incorrect time value: '0.9999999' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(64)); INSERT INTO t1 VALUES('00:00:00.9999999'); @@ -144,19 +158,23 @@ SELECT a, CAST(a AS TIME(6)) FROM t1; a CAST(a AS TIME(6)) 00:00:00.9999999 00:00:01.000000 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(38,10)); INSERT INTO t1 VALUES(0.9999999); SELECT a, CAST(a AS TIME(6)) FROM t1; a CAST(a AS TIME(6)) -0.9999999000 00:00:01.000000 +0.9999999000 NULL +Warnings: +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); INSERT INTO t1 VALUES(0.9999999); SELECT a, CAST(a AS TIME(6)) FROM t1; a CAST(a AS TIME(6)) -0.9999999 00:00:01.000000 +0.9999999 NULL +Warnings: +Warning 1292 Incorrect time value: '0.9999999' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; # # NOW @@ -184,24 +202,28 @@ SET time_zone=DEFAULT; # CREATE TABLE t1 (a TIME(6)); INSERT INTO t1 VALUES (0.999999); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 INSERT INTO t1 VALUES (0.9999999); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 SELECT * FROM t1 WHERE a=0.9999999; a -00:00:01.000000 +00:00:00.000000 +00:00:00.000000 +Warnings: +Warning 1292 Truncated incorrect time value: '0.9999999' SELECT * FROM t1 WHERE a='0.9999999'; a -00:00:01.000000 Warnings: Note 1292 Truncated incorrect time value: '0.9999999' SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999'; a -00:00:01.000000 Warnings: Note 1292 Truncated incorrect time value: '0.9999999' Note 1292 Truncated incorrect time value: '0.9999999' SELECT * FROM t1 WHERE a='0.9999999' AND CONCAT(a)='00:00:01.000000'; a -00:00:01.000000 Warnings: Note 1292 Truncated incorrect time value: '0.9999999' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999'; @@ -227,7 +249,7 @@ SELECT * FROM t1 WHERE a=TIME'23:00:00'; a 22:59:59.9999999 Warnings: -Note 1292 Truncated incorrect time value: '22:59:59.9999999' +Note 1292 Incorrect time value: '22:59:59.9999999' for column `test`.`t1`.`a` at row 1 SELECT * FROM t1 WHERE CONCAT(a)=TIME'23:00:00'; a 22:59:59.9999999 @@ -243,10 +265,12 @@ CREATE TABLE t1 (a DECIMAL(32,7)); INSERT t1 VALUES (225959.9999999); SELECT * FROM t1 WHERE a=TIME'23:00:00'; a -225959.9999999 +Warnings: +Warning 1292 Incorrect time value: '225959.9999999' for column `test`.`t1`.`a` at row 1 SELECT * FROM t1 WHERE COALESCE(a)=TIME'23:00:00'; a -225959.9999999 +Warnings: +Warning 1292 Truncated incorrect time value: '225959.9999999' DROP TABLE t1; # # Literal corner case diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index 1fce10064b4..9097037d59a 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -1588,8 +1588,8 @@ INSERT INTO t2 VALUES (0x30),(0x31); SELECT * FROM t1, t2 WHERE indexed_col=not_indexed_col; indexed_col not_indexed_col Warnings: -Warning 1292 Incorrect datetime value: '0' -Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t2`.`not_indexed_col` at row 1 +Warning 1292 Incorrect datetime value: '1' for column `test`.`t2`.`not_indexed_col` at row 1 DROP TABLE t2; CREATE TABLE t2 (not_indexed_col VARCHAR(32)); INSERT INTO t2 VALUES ('2001-01-01'),('2001-01-02'); diff --git a/mysql-test/main/type_timestamp_round.result b/mysql-test/main/type_timestamp_round.result index 7931aa0ff5b..e142a86a536 100644 --- a/mysql-test/main/type_timestamp_round.result +++ b/mysql-test/main/type_timestamp_round.result @@ -45,7 +45,7 @@ INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999'); INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999'); ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL; Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 2 SELECT a FROM t1; a 2001-01-01 00:00:00.000 @@ -139,7 +139,7 @@ SELECT * FROM t1,t2 WHERE t1.a=t2.a; a a 2001-01-01 23:59:59.9999999 2001-01-02 00:00:00 Warnings: -Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2001-01-01 23:59:59.9999999' for column `test`.`t1`.`a` at row 1 SELECT * FROM t1,t2 WHERE CONCAT(t1.a)=t2.a; a a 2001-01-01 23:59:59.9999999 2001-01-02 00:00:00 diff --git a/mysql-test/main/type_varchar.result b/mysql-test/main/type_varchar.result index 0b3426161ac..a39f0f3a71d 100644 --- a/mysql-test/main/type_varchar.result +++ b/mysql-test/main/type_varchar.result @@ -814,37 +814,37 @@ SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col Warnings: Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `varchar` = "TIME'10:20:30'" of type `time` -Warning 1292 Truncated incorrect time value: '20230101' -Warning 1292 Truncated incorrect time value: '20230102' -Warning 1292 Truncated incorrect time value: '20230103' -Warning 1292 Truncated incorrect time value: '20230104' -Warning 1292 Truncated incorrect time value: '20230105' -Warning 1292 Truncated incorrect time value: '20230106' -Warning 1292 Truncated incorrect time value: '20230107' -Warning 1292 Truncated incorrect time value: '20230108' -Warning 1292 Truncated incorrect time value: '20230109' -Warning 1292 Truncated incorrect time value: '20230110' -Warning 1292 Truncated incorrect time value: '20230111' -Warning 1292 Truncated incorrect time value: '20230112' -Warning 1292 Truncated incorrect time value: '20230113' -Warning 1292 Truncated incorrect time value: '20230114' -Warning 1292 Truncated incorrect time value: '20230115' -Warning 1292 Truncated incorrect time value: '20230116' -Warning 1292 Truncated incorrect time value: '20230117' -Warning 1292 Truncated incorrect time value: '20230118' -Warning 1292 Truncated incorrect time value: '20230119' -Warning 1292 Truncated incorrect time value: '20230120' -Warning 1292 Truncated incorrect time value: '20230121' -Warning 1292 Truncated incorrect time value: '20230122' -Warning 1292 Truncated incorrect time value: '20230123' -Warning 1292 Truncated incorrect time value: '20230124' -Warning 1292 Truncated incorrect time value: '20230125' -Warning 1292 Truncated incorrect time value: '20230126' -Warning 1292 Truncated incorrect time value: '20230127' -Warning 1292 Truncated incorrect time value: '20230128' -Warning 1292 Truncated incorrect time value: '20230129' -Warning 1292 Truncated incorrect time value: '20230130' -Warning 1292 Truncated incorrect time value: '20230131' +Warning 1292 Incorrect time value: '20230101' for column `test`.`t1`.`indexed_col` at row 1 +Warning 1292 Incorrect time value: '20230102' for column `test`.`t1`.`indexed_col` at row 2 +Warning 1292 Incorrect time value: '20230103' for column `test`.`t1`.`indexed_col` at row 3 +Warning 1292 Incorrect time value: '20230104' for column `test`.`t1`.`indexed_col` at row 4 +Warning 1292 Incorrect time value: '20230105' for column `test`.`t1`.`indexed_col` at row 5 +Warning 1292 Incorrect time value: '20230106' for column `test`.`t1`.`indexed_col` at row 6 +Warning 1292 Incorrect time value: '20230107' for column `test`.`t1`.`indexed_col` at row 7 +Warning 1292 Incorrect time value: '20230108' for column `test`.`t1`.`indexed_col` at row 8 +Warning 1292 Incorrect time value: '20230109' for column `test`.`t1`.`indexed_col` at row 9 +Warning 1292 Incorrect time value: '20230110' for column `test`.`t1`.`indexed_col` at row 10 +Warning 1292 Incorrect time value: '20230111' for column `test`.`t1`.`indexed_col` at row 11 +Warning 1292 Incorrect time value: '20230112' for column `test`.`t1`.`indexed_col` at row 12 +Warning 1292 Incorrect time value: '20230113' for column `test`.`t1`.`indexed_col` at row 13 +Warning 1292 Incorrect time value: '20230114' for column `test`.`t1`.`indexed_col` at row 14 +Warning 1292 Incorrect time value: '20230115' for column `test`.`t1`.`indexed_col` at row 15 +Warning 1292 Incorrect time value: '20230116' for column `test`.`t1`.`indexed_col` at row 16 +Warning 1292 Incorrect time value: '20230117' for column `test`.`t1`.`indexed_col` at row 17 +Warning 1292 Incorrect time value: '20230118' for column `test`.`t1`.`indexed_col` at row 18 +Warning 1292 Incorrect time value: '20230119' for column `test`.`t1`.`indexed_col` at row 19 +Warning 1292 Incorrect time value: '20230120' for column `test`.`t1`.`indexed_col` at row 20 +Warning 1292 Incorrect time value: '20230121' for column `test`.`t1`.`indexed_col` at row 21 +Warning 1292 Incorrect time value: '20230122' for column `test`.`t1`.`indexed_col` at row 22 +Warning 1292 Incorrect time value: '20230123' for column `test`.`t1`.`indexed_col` at row 23 +Warning 1292 Incorrect time value: '20230124' for column `test`.`t1`.`indexed_col` at row 24 +Warning 1292 Incorrect time value: '20230125' for column `test`.`t1`.`indexed_col` at row 25 +Warning 1292 Incorrect time value: '20230126' for column `test`.`t1`.`indexed_col` at row 26 +Warning 1292 Incorrect time value: '20230127' for column `test`.`t1`.`indexed_col` at row 27 +Warning 1292 Incorrect time value: '20230128' for column `test`.`t1`.`indexed_col` at row 28 +Warning 1292 Incorrect time value: '20230129' for column `test`.`t1`.`indexed_col` at row 29 +Warning 1292 Incorrect time value: '20230130' for column `test`.`t1`.`indexed_col` at row 30 +Warning 1292 Incorrect time value: '20230131' for column `test`.`t1`.`indexed_col` at row 31 SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col Warnings: diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result index 1e63c2e012f..fb8c86316d0 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -3757,9 +3757,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as time) AS `CAST(my_varbinary_1000 AS TIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3774,9 +3774,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -3793,11 +3793,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 22 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as time) AS `CAST(my_binary_30 AS TIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3812,11 +3812,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -3833,9 +3833,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as time) AS `CAST(my_varchar_1000 AS TIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3850,9 +3850,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -3869,9 +3869,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as time) AS `CAST(my_char_30 AS TIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3886,9 +3886,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4111,10 +4111,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as datetime) AS `CAST(my_varbinary_1000 AS DATETIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4129,10 +4129,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4149,11 +4149,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 16 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as datetime) AS `CAST(my_binary_30 AS DATETIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4168,11 +4168,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4189,10 +4189,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as datetime) AS `CAST(my_varchar_1000 AS DATETIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4207,10 +4207,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4227,10 +4227,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as datetime) AS `CAST(my_char_30 AS DATETIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4245,10 +4245,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4467,10 +4467,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as date) AS `CAST(my_varbinary_1000 AS DATE)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4485,10 +4485,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4505,11 +4505,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 10 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as date) AS `CAST(my_binary_30 AS DATE)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4524,11 +4524,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4545,10 +4545,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as date) AS `CAST(my_varchar_1000 AS DATE)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4563,10 +4563,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4583,10 +4583,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as date) AS `CAST(my_char_30 AS DATE)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4601,10 +4601,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result index 84af1109454..2ac58b245a4 100644 --- a/mysql-test/suite/funcs_1/r/memory_func_view.result +++ b/mysql-test/suite/funcs_1/r/memory_func_view.result @@ -3758,9 +3758,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as time) AS `CAST(my_varbinary_1000 AS TIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3775,9 +3775,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -3794,11 +3794,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as time) AS `CAST(my_binary_30 AS TIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3813,11 +3813,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -3834,9 +3834,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as time) AS `CAST(my_varchar_1000 AS TIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3851,9 +3851,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -3870,9 +3870,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as time) AS `CAST(my_char_30 AS TIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3887,9 +3887,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4112,10 +4112,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as datetime) AS `CAST(my_varbinary_1000 AS DATETIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4130,10 +4130,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4150,11 +4150,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as datetime) AS `CAST(my_binary_30 AS DATETIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4169,11 +4169,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4190,10 +4190,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as datetime) AS `CAST(my_varchar_1000 AS DATETIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4208,10 +4208,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4228,10 +4228,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as datetime) AS `CAST(my_char_30 AS DATETIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4246,10 +4246,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4468,10 +4468,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as date) AS `CAST(my_varbinary_1000 AS DATE)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4486,10 +4486,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4506,11 +4506,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as date) AS `CAST(my_binary_30 AS DATE)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4525,11 +4525,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4546,10 +4546,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as date) AS `CAST(my_varchar_1000 AS DATE)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4564,10 +4564,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4584,10 +4584,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as date) AS `CAST(my_char_30 AS DATE)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4602,10 +4602,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result index 84af1109454..2ac58b245a4 100644 --- a/mysql-test/suite/funcs_1/r/myisam_func_view.result +++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result @@ -3758,9 +3758,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as time) AS `CAST(my_varbinary_1000 AS TIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3775,9 +3775,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 23 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -3794,11 +3794,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as time) AS `CAST(my_binary_30 AS TIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3813,11 +3813,11 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 22 Warnings: -Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect time value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect time value: '1 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -3834,9 +3834,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as time) AS `CAST(my_varchar_1000 AS TIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3851,9 +3851,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 21 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -3870,9 +3870,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as time) AS `CAST(my_char_30 AS TIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3887,9 +3887,9 @@ NULL ---äÖüß@µ*$-- 4 -00:00:01 -1 5 41:58:00 1 17:58 20 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '<--------30 characters------->' -Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' +Warning 1292 Incorrect time value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect time value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4112,10 +4112,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as datetime) AS `CAST(my_varbinary_1000 AS DATETIME)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4130,10 +4130,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 17 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4150,11 +4150,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as datetime) AS `CAST(my_binary_30 AS DATETIME)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4169,11 +4169,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 16 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '2005-06-27 17:58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4190,10 +4190,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as datetime) AS `CAST(my_varchar_1000 AS DATETIME)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4208,10 +4208,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 15 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4228,10 +4228,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as datetime) AS `CAST(my_char_30 AS DATETIME)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4246,10 +4246,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 17:58:00 2005-06-27 17:58 14 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; @@ -4468,10 +4468,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as date) AS `CAST(my_varbinary_1000 AS DATE)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4486,10 +4486,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 11 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varbinary_1000` at row 1 DROP VIEW v1; @@ -4506,11 +4506,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 4 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 5 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 6 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_binary_30` as date) AS `CAST(my_binary_30 AS DATE)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4525,11 +4525,11 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 10 Warnings: -Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' -Warning 1292 Truncated incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +Warning 1292 Incorrect datetime value: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect datetime value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 +Warning 1292 Incorrect date value: '2005-06-27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for column `test`.`t1_values`.`my_binary_30` at row 1 DROP VIEW v1; @@ -4546,10 +4546,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 2 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as date) AS `CAST(my_varchar_1000 AS DATE)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4564,10 +4564,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 9 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '<---------1000 characters----------------------------------------------------------------------------------------------------...' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$-- ' for column `test`.`t1_values`.`my_varchar_1000` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_varchar_1000` at row 1 DROP VIEW v1; @@ -4584,10 +4584,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 2 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 3 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 4 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 5 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_char_30` as date) AS `CAST(my_char_30 AS DATE)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -4602,10 +4602,10 @@ NULL ---äÖüß@µ*$-- 4 NULL -1 5 2005-06-27 2005-06-27 8 Warnings: -Warning 1292 Incorrect datetime value: '' -Warning 1292 Incorrect datetime value: '<--------30 characters------->' -Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' -Warning 1292 Incorrect datetime value: '-1' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '<--------30 characters------->' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: ' ---\xC3\xA4\xC3\x96\xC3\xBC\xC3\x9F@\xC2\xB5*$--' for column `test`.`t1_values`.`my_char_30` at row 1 +Warning 1292 Incorrect datetime value: '-1' for column `test`.`t1_values`.`my_char_30` at row 1 DROP VIEW v1; diff --git a/mysql-test/suite/gcol/r/gcol_bug20746926.result b/mysql-test/suite/gcol/r/gcol_bug20746926.result index 590caf02503..b076d8aa094 100644 --- a/mysql-test/suite/gcol/r/gcol_bug20746926.result +++ b/mysql-test/suite/gcol/r/gcol_bug20746926.result @@ -11,22 +11,22 @@ c timestamp generated always as ((a not in (b,b))) stored insert t1(a) values(7777777777); Warnings: Warning 1265 Data truncated for column 'a' at row 1 -Warning 1292 Truncated incorrect datetime value: '0' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t1`.`b` at row 1 show warnings; Level Code Message Warning 1265 Data truncated for column 'a' at row 1 -Warning 1292 Truncated incorrect datetime value: '0' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t1`.`b` at row 1 disconnect con1; connect con2,localhost,root,,; set sql_mode=''; insert t1(a) values(6666666666); Warnings: Warning 1265 Data truncated for column 'a' at row 1 -Warning 1292 Truncated incorrect datetime value: '0' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t1`.`b` at row 1 show warnings; Level Code Message Warning 1265 Data truncated for column 'a' at row 1 -Warning 1292 Truncated incorrect datetime value: '0' +Warning 1292 Incorrect datetime value: '0' for column `test`.`t1`.`b` at row 1 drop table t1; disconnect con2; connection default; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 337de9e15a7..6f690f21675 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -327,7 +327,7 @@ partition_name partition_ordinal_position partition_method timediff(partition_de p0 1 SYSTEM_TIME 00:00:00.000000 pn 2 SYSTEM_TIME NULL Warnings: -Warning 1292 Incorrect time value: 'CURRENT' +Warning 1292 Incorrect time value: 'CURRENT' for column `information_schema`.`(temporary)`.`PARTITION_DESCRIPTION` at row 2 alter table t1 add partition (partition p1 history, partition p2 history); select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) @@ -336,7 +336,7 @@ p1 2 SYSTEM_TIME 01:00:00.000000 p2 3 SYSTEM_TIME 02:00:00.000000 pn 4 SYSTEM_TIME NULL Warnings: -Warning 1292 Incorrect time value: 'CURRENT' +Warning 1292 Incorrect time value: 'CURRENT' for column `information_schema`.`(temporary)`.`PARTITION_DESCRIPTION` at row 4 alter table t1 drop partition p0; select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) @@ -344,7 +344,7 @@ p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 pn 3 SYSTEM_TIME NULL Warnings: -Warning 1292 Incorrect time value: 'CURRENT' +Warning 1292 Incorrect time value: 'CURRENT' for column `information_schema`.`(temporary)`.`PARTITION_DESCRIPTION` at row 3 alter table t1 drop partition p2; ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; @@ -353,7 +353,7 @@ p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 pn 3 SYSTEM_TIME NULL Warnings: -Warning 1292 Incorrect time value: 'CURRENT' +Warning 1292 Incorrect time value: 'CURRENT' for column `information_schema`.`(temporary)`.`PARTITION_DESCRIPTION` at row 3 set timestamp=unix_timestamp('2001-02-03 10:20:30'); create or replace table t1 (i int) with system versioning partition by system_time interval 1 day diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 2f74235614c..35206ff7b88 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1909,30 +1909,32 @@ longlong number_to_datetime_or_date(longlong nr, ulong sec_part, int number_to_time_only(my_bool neg, ulonglong nr, ulong sec_part, ulong max_hour, MYSQL_TIME *ltime, int *was_cut) { - static const ulonglong TIME_MAX_mmss= TIME_MAX_MINUTE*100 + TIME_MAX_SECOND; - ulonglong time_max_value= max_hour * 10000ULL + TIME_MAX_mmss; *was_cut= 0; ltime->year= ltime->month= ltime->day= 0; ltime->time_type= MYSQL_TIMESTAMP_TIME; ltime->neg= neg; - if (nr > time_max_value) - { - nr= time_max_value; - sec_part= TIME_MAX_SECOND_PART; - *was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE; - } ltime->hour = (uint)(nr/100/100); ltime->minute= nr/100%100; ltime->second= nr%100; ltime->second_part= sec_part; - if (ltime->minute < 60 && ltime->second < 60 && sec_part <= TIME_MAX_SECOND_PART) - return 0; + if (ltime->minute >= 60 || ltime->second >= 60 || sec_part >= TIME_MAX_SECOND_PART) + { + *was_cut= MYSQL_TIME_WARN_TRUNCATED; + return -1; + } + if (ltime->hour > max_hour) + { + ltime->hour = max_hour; + ltime->minute= TIME_MAX_MINUTE; + ltime->second= TIME_MAX_SECOND; + ltime->second_part= TIME_MAX_SECOND_PART; + *was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE; + } - *was_cut= MYSQL_TIME_WARN_TRUNCATED; - return -1; + return 0; } diff --git a/sql/field.cc b/sql/field.cc index 9d864e5d1c8..2550d444b93 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2522,7 +2522,9 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) bool Field::get_date(MYSQL_TIME *to, date_mode_t mode) { StringBuffer<40> tmp; - Temporal::Warn_push warn(get_thd(), nullptr, nullptr, nullptr, to, mode); + Temporal::Warn_push warn(get_thd(), table ? table->s->db.str : nullptr, + table ? table->s->table_name.str : nullptr, + field_name.str, to, mode); Temporal_hybrid *t= new(to) Temporal_hybrid(get_thd(), &warn, val_str(&tmp), mode); return !t->is_valid_temporal(); From d12a5333fde1a5f3fe599f12cb6449a93bc938e5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 18 Nov 2025 11:30:45 +0100 Subject: [PATCH 061/152] MDEV-37888 unexpected type changing after changing AVG to MAX set collation for AVG, like it's done for MAX --- mysql-test/main/func_group.result | 19 ++++++++++++++++++- mysql-test/main/func_group.test | 12 +++++++++++- sql/item_sum.cc | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index 27845af7164..6c5e3571342 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -2570,6 +2570,23 @@ concat(a,":",group_concat(b)) 1:2,7 4:5 drop table t1; -# # End of 10.3 tests # +# MDEV-37888 unexpected type changing after changing AVG to MAX +# +SELECT 1, MAX(1), AVG(1); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def 1 3 1 1 N 32897 0 63 +def MAX(1) 8 1 1 Y 32896 0 63 +def AVG(1) 246 7 6 Y 32896 4 63 +1 MAX(1) AVG(1) +1 1 1.0000 +SELECT 1, MAX(1), AVG(1) UNION ALL SELECT 'one', 'max', 'avg'; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def 1 253 3 3 N 1 39 8 +def MAX(1) 253 3 3 Y 0 39 8 +def AVG(1) 253 7 7 Y 0 39 8 +1 MAX(1) AVG(1) +1 1 1.00000 +one max avg +# End of 10.11 tests diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index e1023405b96..045ddfeb7e1 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -1802,6 +1802,16 @@ insert t1 values (1,2,3),(4,5,6),(1,7,8); select concat(a,":",group_concat(b)) from t1 group by a; drop table t1; ---echo # --echo # End of 10.3 tests + --echo # +--echo # MDEV-37888 unexpected type changing after changing AVG to MAX +--echo # +enable_metadata; +disable_view_protocol; +SELECT 1, MAX(1), AVG(1); +SELECT 1, MAX(1), AVG(1) UNION ALL SELECT 'one', 'max', 'avg'; +enable_view_protocol; +disable_metadata; + +--echo # End of 10.11 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 08c4114c4d2..580a13e1c54 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1115,6 +1115,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) if (init_sum_func_check(thd)) return TRUE; + collation= DTCollation_numeric(); decimals=0; set_maybe_null(sum_func() != COUNT_FUNC); for (uint i=0 ; i < arg_count ; i++) From 65720c604eb572df2d25b55ca4bafcff72470a1e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 26 Dec 2025 11:08:08 +0100 Subject: [PATCH 062/152] MDEV-38110 Sever shutdown prevented by RocksDB setting rocksdb_pause_background_work enable background threads on shutdown, so that they could respond to signals and free resources --- storage/rocksdb/ha_rocksdb.cc | 3 +++ .../rocksdb/r/pause_background_work.result | 10 ++++++++++ .../mysql-test/rocksdb/t/pause_background_work.test | 13 +++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 storage/rocksdb/mysql-test/rocksdb/r/pause_background_work.result create mode 100644 storage/rocksdb/mysql-test/rocksdb/t/pause_background_work.test diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 5e27ddc3cf1..bef1a8bfe43 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5819,6 +5819,9 @@ static int rocksdb_init_func(void *const p) { static int rocksdb_done_func(void *const p) { DBUG_ENTER_FUNC(); + if (rocksdb_pause_background_work) + rdb->ContinueBackgroundWork(); + // signal the drop index thread to stop rdb_drop_idx_thread.signal(true); diff --git a/storage/rocksdb/mysql-test/rocksdb/r/pause_background_work.result b/storage/rocksdb/mysql-test/rocksdb/r/pause_background_work.result new file mode 100644 index 00000000000..a6aa2e5e0ad --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/r/pause_background_work.result @@ -0,0 +1,10 @@ +# +# MDEV-38110 Sever shutdown prevented by RocksDB setting rocksdb_pause_background_work +# +install soname 'ha_rocksdb'; +set global rocksdb_pause_background_work=1; +# restart +select 'ok'; +ok +ok +# End of 10.11 tests diff --git a/storage/rocksdb/mysql-test/rocksdb/t/pause_background_work.test b/storage/rocksdb/mysql-test/rocksdb/t/pause_background_work.test new file mode 100644 index 00000000000..3b0504daadd --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/t/pause_background_work.test @@ -0,0 +1,13 @@ +--echo # +--echo # MDEV-38110 Sever shutdown prevented by RocksDB setting rocksdb_pause_background_work +--echo # + +install soname 'ha_rocksdb'; + +set global rocksdb_pause_background_work=1; + +source include/restart_mysqld.inc; + +select 'ok'; + +--echo # End of 10.11 tests From 7fed0143081988e9fbaf01c9e07aa261ec1f06be Mon Sep 17 00:00:00 2001 From: Mohammad Tafzeel Shams Date: Fri, 5 Dec 2025 15:18:44 +0530 Subject: [PATCH 063/152] MDEV-38140: InnoDB index corruption after UPDATE affecting virtual columns Issue: - Purge thread attempts to purge a secondary index record that is not delete-marked. Root Cause: - When a secondary index includes a virtual column whose v_pos is greater than the number of fields in the clustered index record, the virtual column is incorrectly skipped while reading from the undo record. - This leads the purge logic to incorrectly assume it is safe to purge the secondary index record. - The code also confuses the nth virtual column with the nth stored column when writing ordering columns at the end of the undo record. Fix: - In trx_undo_update_rec_get_update(): Skip a virtual column only when v_pos == FIL_NULL, not when v_pos is greater than the number of fields. - In trx_undo_page_report_modify(): Ensure ordering columns are written based on the correct stored-column positions, without confusing them with virtual-column positions. --- .../innodb/r/innodb-virtual-columns.result | 37 +++++++++++++++ .../innodb/t/innodb-virtual-columns.test | 46 +++++++++++++++++++ storage/innobase/trx/trx0rec.cc | 9 ++-- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result index b97eaac7565..f91c4615af0 100644 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result @@ -351,3 +351,40 @@ SELECT * FROM t1; a b c 1 foo 1 DROP TABLE t1; +CREATE TABLE t1 ( +id int primary key,value varchar(2), +vcomplete int AS (cast(substr(value,1,1) as int)), +va int AS (null),vb int AS (null),vc int AS (null), +vresult char(1) AS (substr(value,2)), +KEY key1(vresult,vcomplete) +) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1(id,value) VALUES (1,'0F'); +UPDATE t1 SET value = '1S'; +UPDATE t1 SET value = '0F'; +COMMIT; +SET GLOBAL innodb_max_purge_lag_wait=0; +SELECT * FROM t1; +id value vcomplete va vb vc vresult +1 0F 0 NULL NULL NULL F +DROP TABLE t1; +CREATE TABLE t1 ( +col1 int primary key, +col2 int, +col3 int, +col4 varchar(5), +v_col1 char(1) AS (substr(col4,1,1)), +v_col2 char(1) AS (substr(col4,2,1)), +v_col3 char(1) AS (substr(col4,3,1)), +v_col4 char(1) AS (substr(col4,4,1)), +v_col5 char(1) AS (substr(col4,5,1)), +KEY key1(v_col2, v_col1, v_col3, v_col4, v_col5), +KEY key2(col2, col3) +) ENGINE=InnoDB; +INSERT INTO t1(col1,col2,col3,col4) VALUES (1,1,1,'ABCDE'); +UPDATE t1 SET col2=2, col4 = 'PQRST'; +SET GLOBAL innodb_max_purge_lag_wait=0; +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns.test b/mysql-test/suite/innodb/t/innodb-virtual-columns.test index faf542645fb..6bb9ddc8dc4 100644 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns.test +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns.test @@ -317,3 +317,49 @@ INSERT INTO t1 (a,b) VALUES (1,'foo'); ALTER TABLE t1 ADD FULLTEXT KEY(b); SELECT * FROM t1; DROP TABLE t1; + +# +# MDEV-38140 : InnoDB index corruption after UPDATE affecting virtual columns +# + +CREATE TABLE t1 ( + id int primary key,value varchar(2), + vcomplete int AS (cast(substr(value,1,1) as int)), + va int AS (null),vb int AS (null),vc int AS (null), + vresult char(1) AS (substr(value,2)), + KEY key1(vresult,vcomplete) +) ENGINE=InnoDB; + +BEGIN; +INSERT INTO t1(id,value) VALUES (1,'0F'); +UPDATE t1 SET value = '1S'; +UPDATE t1 SET value = '0F'; +COMMIT; + +SET GLOBAL innodb_max_purge_lag_wait=0; +SELECT * FROM t1; + +DROP TABLE t1; + +# Test to check if all the stale secondary records are purged +CREATE TABLE t1 ( + col1 int primary key, + col2 int, + col3 int, + col4 varchar(5), + v_col1 char(1) AS (substr(col4,1,1)), + v_col2 char(1) AS (substr(col4,2,1)), + v_col3 char(1) AS (substr(col4,3,1)), + v_col4 char(1) AS (substr(col4,4,1)), + v_col5 char(1) AS (substr(col4,5,1)), + KEY key1(v_col2, v_col1, v_col3, v_col4, v_col5), + KEY key2(col2, col3) +) ENGINE=InnoDB; + + +INSERT INTO t1(col1,col2,col3,col4) VALUES (1,1,1,'ABCDE'); +UPDATE t1 SET col2=2, col4 = 'PQRST'; +SET GLOBAL innodb_max_purge_lag_wait=0; + +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 37c64d21532..5d854ebd5e5 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1222,9 +1222,12 @@ store_len: columns that were updated. */ for (i = 0; i < update->n_fields; i++) { + const upd_field_t* fld = + upd_get_nth_field(update, i); + if (upd_fld_is_virtual_col(fld)) + continue; const ulint field_no - = upd_get_nth_field(update, i) - ->field_no; + = fld->field_no; if (field_no >= index->n_fields || dict_index_get_nth_field( index, field_no)->col @@ -1524,7 +1527,7 @@ trx_undo_update_rec_get_update( &field_no); first_v_col = false; /* This column could be dropped or no longer indexed */ - if (field_no >= index->n_fields) { + if (field_no == FIL_NULL) { /* Mark this is no longer needed */ upd_field->field_no = REC_MAX_N_FIELDS; From 13aad4ed2b115396d6c9b3e94177227a047cc1c8 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Thu, 23 Oct 2025 22:22:39 +0200 Subject: [PATCH 064/152] MDEV-20586: Incorrect commit of transaction in GTID table processing The initial scanning of the GTID pos table in find_gtid_pos_tables_cb() used the wrong call to commit the transaction, ha_commit_trans(thd, TRUE) instead of trans_commit(thd). This could cause an assertion Assertion '!thd->in_active_multi_stmt_transaction() || thd->in_multi_stmt_transaction_mode()' failed in mysql_execute_command and possibly other issues due to incorrect state in the SQL thread THD. Similar problem in rpl_slave_state::truncate_state_table() also fixed. Note there is a sister patch cd88b0831f7bea7e313af7d0bd96b7050f6c9d60 which applied this same pattern which fixed a hang due to locks not being released in the ha_commit_trans(thd, TRUE) call. Test-case-by: Alice Sherepa Reviewed-by: Brandon Nesterenko Signed-off-by: Kristian Nielsen --- .../suite/rpl/r/rpl_autocommit_off.result | 16 +++++++++++ mysql-test/suite/rpl/t/rpl_autocommit_off.cnf | 4 +++ .../suite/rpl/t/rpl_autocommit_off.test | 27 +++++++++++++++++++ sql/rpl_gtid.cc | 3 ++- sql/rpl_rli.cc | 2 +- 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_autocommit_off.result create mode 100644 mysql-test/suite/rpl/t/rpl_autocommit_off.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_autocommit_off.test diff --git a/mysql-test/suite/rpl/r/rpl_autocommit_off.result b/mysql-test/suite/rpl/r/rpl_autocommit_off.result new file mode 100644 index 00000000000..f1f189662b0 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_autocommit_off.result @@ -0,0 +1,16 @@ +include/rpl_init.inc [topology=1->2] +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +connection server_1; +CREATE TABLE t1 (a INT); +connection server_2; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, +MASTER_USE_GTID=CURRENT_POS; +include/start_slave.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_1; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_autocommit_off.cnf b/mysql-test/suite/rpl/t/rpl_autocommit_off.cnf new file mode 100644 index 00000000000..5ff056e6133 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_autocommit_off.cnf @@ -0,0 +1,4 @@ +!include ../my.cnf + +[mysqld] +autocommit=0 diff --git a/mysql-test/suite/rpl/t/rpl_autocommit_off.test b/mysql-test/suite/rpl/t/rpl_autocommit_off.test new file mode 100644 index 00000000000..c71da9de61c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_autocommit_off.test @@ -0,0 +1,27 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT); + +--connection server_2 +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +--source include/start_slave.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--connection server_1 +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 3a17b467b62..31b8ed7c6cb 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -29,6 +29,7 @@ #include "rpl_rli.h" #include "slave.h" #include "log_event.h" +#include "transaction.h" const LEX_CSTRING rpl_gtid_slave_state_table_name= { STRING_WITH_LEN("gtid_slave_pos") }; @@ -457,7 +458,7 @@ rpl_slave_state::truncate_state_table(THD *thd) { ha_commit_trans(thd, FALSE); close_thread_tables(thd); - ha_commit_trans(thd, TRUE); + trans_commit(thd); } thd->release_transactional_locks(); } diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index c16980e57c9..320937ed829 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -2004,7 +2004,7 @@ end: if (table) { ha_commit_trans(thd, FALSE); - ha_commit_trans(thd, TRUE); + trans_commit(thd); close_thread_tables(thd); thd->release_transactional_locks(); } From eee6c91fdf6b874dc01bec760cb07919e1691c3e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 16 Jan 2026 20:20:48 +0100 Subject: [PATCH 065/152] Windows,CMake - remove invalid use of MESSAGE_ONCE --- win/packaging/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index a4d951bfa5c..c84550dc915 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -90,7 +90,6 @@ SET(CPACK_WIX_UPGRADE_CODE_x64 "2331E7BD-EE58-431B-9E18-B2B918BCEB1B") SET(CPACK_WIX_UPGRADE_CODE ${CPACK_WIX_UPGRADE_CODE_${WIX_ARCH}}) IF(NOT CPACK_WIX_UPGRADE_CODE) - MESSAGE_ONCE("unknown upgrade code for arch ${WIX_ARCH}") CANT_BUILD_MSI("unknown upgrade code for arch ${WIX_ARCH}") ENDIF() From c69ea9b286aceee1e72ffe3713db543633115cbe Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 16 Jan 2026 23:33:22 +0100 Subject: [PATCH 066/152] Skip main.mysql_options_err, if ha_example plugin is missing This fixes Appveyor build. --- mysql-test/main/mysqld_option_err.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/main/mysqld_option_err.test b/mysql-test/main/mysqld_option_err.test index dda0d7e4365..b03a5f271e0 100644 --- a/mysql-test/main/mysqld_option_err.test +++ b/mysql-test/main/mysqld_option_err.test @@ -9,6 +9,7 @@ # --source include/not_embedded.inc +--source include/have_example_plugin.inc # mysqld refuses to run as root normally. -- source include/not_as_root.inc From 8c6ebbaccec05e514d474c787272dd8f70738541 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Sun, 18 Jan 2026 20:11:56 +0530 Subject: [PATCH 067/152] MDEV-25148: Unexpected success and result set upon erroneous JSON_VALUE call Analysis: When scanning json and reaching a path, the path type is JSON_PATH_ARRAY_WILD. So it should not return any value. But the code does not check that. Fix: Use path_setup_nwc() to check for range queries because json_value() should not accept range queries. --- mysql-test/main/func_json.result | 21 ++++++++++++++------- mysql-test/main/func_json.test | 7 +++++++ sql/item_jsonfunc.cc | 4 ++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index dc11f93b1fb..46efc9003f1 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -661,7 +661,7 @@ JSON_SEARCH('{"foo":"bar"}', 'all' , @str, '%', @path) "$.foo" SELECT JSON_VALUE('[{"foo": 1},"bar"]', '$[*][0]'); JSON_VALUE('[{"foo": 1},"bar"]', '$[*][0]') -bar +NULL CREATE TABLE t1 (f INT NOT NULL); INSERT INTO t1 VALUES (0); SELECT JSON_KEYS(f) FROM t1 ORDER BY 1; @@ -1455,7 +1455,7 @@ SET @old_collation_connection= @@COLLATION_CONNECTION; SET COLLATION_CONNECTION= ucs2_unicode_ci; SELECT JSON_VALUE('["foo"]', '$**[0]') AS f; f -foo +NULL SET @@COLLATION_CONNECTION= @old_collation_connection; # # MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation @@ -2383,7 +2383,7 @@ SET @json= '[ ]'; SELECT JSON_VALUE(@json, '$[0][1 to 2].key1'); JSON_VALUE(@json, '$[0][1 to 2].key1') -value1 +NULL SET @json='{ "A": [0, [1, 2, 3], @@ -2400,7 +2400,7 @@ SET @json='{ }'; SELECT JSON_QUERY(@json, '$.A[-2][-3 to -1]'); JSON_QUERY(@json, '$.A[-2][-3 to -1]') -[13, 14] +NULL SET @json= '[ [1, {"key1": "value1"}, 3], [false, 5, 6], @@ -2548,7 +2548,7 @@ SET @json1= '[ ]'; SELECT JSON_VALUE(@json1, '$[2][1 to 2].key1'); JSON_VALUE(@json1, '$[2][1 to 2].key1') -value7 +NULL SET @json= '[ [1.1, {"key1": "value1"}, 3], [false, 5, 6], @@ -2558,10 +2558,10 @@ SET @json= '[ ]'; SELECT JSON_VALUE(@json, '$[*][0]'); JSON_VALUE(@json, '$[*][0]') -1.1 +NULL SELECT JSON_VALUE(@json, '$[2 to 3][0]'); JSON_VALUE(@json, '$[2 to 3][0]') -7 +NULL # # MDEV-28072: JSON_EXTRACT has inconsistent behavior with '0' value in # json path (when range is used) @@ -2763,4 +2763,11 @@ SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]' COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; NAME S1A1 +# +# MDEV-25148: Unexpected success and result set upon erroneous +# JSON_VALUE call +# +SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); +JSON_VALUE('{"a":[1,2]}', '$.a[*]') +NULL # End of 10.11 Test diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 28c8e923207..b826f66ed85 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -2025,4 +2025,11 @@ COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]' COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; +--echo # +--echo # MDEV-25148: Unexpected success and result set upon erroneous +--echo # JSON_VALUE call +--echo # + +SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); + --echo # End of 10.11 Test diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 61ee2bd2493..43d54601196 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -738,8 +738,8 @@ bool Json_path_extractor::extract(String *str, Item *item_js, Item *item_jp, { String *s_p= item_jp->val_str(&tmp_path); if (s_p && - json_path_setup(&p, s_p->charset(), (const uchar *) s_p->ptr(), - (const uchar *) s_p->ptr() + s_p->length())) + path_setup_nwc(&p, s_p->charset(), (const uchar *) s_p->ptr(), + (const uchar *) s_p->ptr() + s_p->length())) return true; parsed= constant; } From 42c260bc0f768ccd449d7f59d9a8a85d3e54b844 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 19 Jan 2026 16:13:34 +0100 Subject: [PATCH 068/152] MDEV-37997 vcpkg's FIND_PACKAGE throws error for zlib dependent packages Build with vcpkg and WITH_ZLIB=bundled throws error "Broken installation of vcpkg port zlib" in FIND_PACKAGE(CURL) Set CMAKE_DISABLE_FIND_PACKAGE_ZLIB to workaround. Previously, this workaround was hashicorp specific, now we need this also for videx. Thus setting CMAKE_DISABLE_FIND_PACKAGE_ZLIB was moved to correct place, inside MYSQL_USE_BUNDLED_ZLIB macro. --- cmake/zlib.cmake | 5 +++++ plugin/hashicorp_key_management/CMakeLists.txt | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake index a933194cd33..2a7043b3254 100644 --- a/cmake/zlib.cmake +++ b/cmake/zlib.cmake @@ -21,6 +21,11 @@ MACRO (MYSQL_USE_BUNDLED_ZLIB) SET(ZLIB_LIBRARY ${ZLIB_LIBRARIES}) SET(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIRS}) SET(ZLIB_FOUND TRUE) + IF(VCPKG_INSTALLED_DIR) + # Avoid errors in vcpkg's FIND_PACKAGE + # for packages dependend on zlib + SET(CMAKE_DISABLE_FIND_PACKAGE_ZLIB 1) + ENDIF() SET(WITH_ZLIB "bundled" CACHE STRING "Use bundled zlib") ADD_SUBDIRECTORY(zlib) ENDMACRO() diff --git a/plugin/hashicorp_key_management/CMakeLists.txt b/plugin/hashicorp_key_management/CMakeLists.txt index 0705760fc29..809b480f6ac 100644 --- a/plugin/hashicorp_key_management/CMakeLists.txt +++ b/plugin/hashicorp_key_management/CMakeLists.txt @@ -1,6 +1,3 @@ -IF(VCPKG_INSTALLED_DIR AND (WITH_ZLIB STREQUAL "bundled")) - SET(CMAKE_DISABLE_FIND_PACKAGE_ZLIB 1) -ENDIF() FIND_PACKAGE(CURL) IF(NOT CURL_FOUND) # Can't build plugin From f2cb54849f9fea763c4f5c06caec9cda87fe35c9 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 19 Jan 2026 16:29:34 +0100 Subject: [PATCH 069/152] MDEV-38203 fix build error on Windows --- .../hashicorp_key_management/hashicorp_key_management_plugin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc index b51bac9e7d5..592c96713fd 100644 --- a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc +++ b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc @@ -161,7 +161,7 @@ static clock_t cache_max_ver_time; Convert milliseconds to timer ticks with rounding to nearest integer: */ -static clock_t ms_to_ticks (long ms) +static clock_t ms_to_ticks (long long ms) { long long ticks_1000 = ms * (long long) CLOCKS_PER_SEC; clock_t ticks = (clock_t) (ticks_1000 / 1000); From f92337ac173cbb2fce955ae83f982853167c1c71 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 19 Jan 2026 17:09:05 +0100 Subject: [PATCH 070/152] Fix MSVC warning innodb_rbt-t.cc(9,1): warning C4722: 'ib::fatal_or_error::~fatal_or_error': destructor never returns, potential memory leak --- storage/innobase/unittest/innodb_rbt-t.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/unittest/innodb_rbt-t.cc b/storage/innobase/unittest/innodb_rbt-t.cc index 38b980da7d9..3dc4b017a3c 100644 --- a/storage/innobase/unittest/innodb_rbt-t.cc +++ b/storage/innobase/unittest/innodb_rbt-t.cc @@ -6,7 +6,7 @@ const size_t alloc_max_retries= 0; void os_thread_sleep(ulint) { abort(); } void ut_dbg_assertion_failed(const char *, const char *, unsigned) { abort(); } -namespace ib { fatal_or_error::~fatal_or_error() { abort(); } } +namespace ib { fatal_or_error::~fatal_or_error() { IF_WIN(__debugbreak(),abort()); } } #ifdef UNIV_PFS_MEMORY PSI_memory_key mem_key_other, mem_key_std; PSI_memory_key ut_new_get_key_by_file(uint32_t) { return mem_key_std; } From f18ad925b8309a4934f0a3e29bef19dad9fac882 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 19 Jan 2026 20:52:59 +0100 Subject: [PATCH 071/152] Wolfssl v5.8.4-stable --- extra/wolfssl/wolfssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl index b077c81eb63..59f4fa56861 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit b077c81eb635392e694ccedbab8b644297ec0285 +Subproject commit 59f4fa568615396fbf381b073b220d1e8d61e4c2 From 08c57c5ebf3434419de14ef059a564c570a550ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 20 Jan 2026 08:55:59 +0200 Subject: [PATCH 072/152] MDEV-37600 fixup: clang 21 -Wunterminated-string-initialization --- plugin/auth_mysql_sha2/sha256crypt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin/auth_mysql_sha2/sha256crypt.c b/plugin/auth_mysql_sha2/sha256crypt.c index aa75632452f..672a0afb9d6 100644 --- a/plugin/auth_mysql_sha2/sha256crypt.c +++ b/plugin/auth_mysql_sha2/sha256crypt.c @@ -32,6 +32,9 @@ void sha256_crypt_r(const unsigned char *key, size_t key_len, static const char b64t[64] #if defined __GNUC__ && __GNUC__ > 7 __attribute__((nonstring)) +#endif +#if defined __clang_major__ && __clang_major__ > 20 + __attribute__((nonstring)) #endif = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; void *ctx = alloca(my_sha256_context_size()); From b241f97daa2eab47f990db9c82489b1a67ea45ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 20 Jan 2026 08:57:39 +0200 Subject: [PATCH 073/152] MDEV-32744 fixup: clang -Winstantiation-after-specialization --- storage/innobase/sync/srw_lock.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index 74c09b8d0a3..7a8376432c8 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -624,7 +624,6 @@ void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line) noexcept lock.u_wr_upgrade(); } #else /* UNIV_PFS_RWLOCK */ -template void ssux_lock_impl::rd_lock() noexcept; template void ssux_lock_impl::rd_unlock() noexcept; template void ssux_lock_impl::u_unlock() noexcept; template void ssux_lock_impl::wr_unlock() noexcept; From e40277d29b7c531e1ed6b3bed7ecfc8cfeff4c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 18 Dec 2025 09:58:38 +0200 Subject: [PATCH 074/152] MDEV-38218 : Galera test failure on galera_bf_abort_flush_for_export Problem was in wsrep_handle_mdl_conflict function was comparing thd->lex->sql_command variable for granted MDL-lock. There is two possible schedules: (1) FLUSH TABLES ... FOR EXPORT that will take MDL-lock (granted_thd). INSERT from other node is conflicting operation (request_thd) and sees MDL-conflict. Because granted_thd has not executed anything else thd->lex->sql_command == SQLCOM_FLUSH and this case was correctly handled in wsrep_handle_mdl_conflict i.e. INSERT needs to wait. (2) FLUSH TABLES ... FOR EXPORT that will take MDL-lock (granted_thd). SET SESSION wsrep_sync_wait=0; (granted_thd) INSERT from other node is conflicting operation (request_thd) However, thd->lex->sql_command is not stored to taken MDL-lock. Now as granted_thd is executing SET thd->lex->sql_command != SQLCOM_FLUSH and INSERT that is BF will abort it and that means also FTFE is killed and MDL-lock relesed. This is incorrect as FTFE has written file on filesystem and it can't be really killed. In this fix wsrep_handle_mdl_conflict is refactored not to use thd->lex->sql_command as a variable used for decisions. Instead connection state can be determined also via THD members. E.g.: * wsrep_thd_is_toi() || wsrep_thd_is_applying - ongoing TOI or applier * wsrep_thd_is_BF - thread is brute force * wsrep_thd_is_SR - thread is streaming replication thread * thd->current_backup_stage != BACKUP_FINISHED - there's ongoing BACKUP * thd->global_read_lock.is_acquired() - ongoing FTWRL * thd->locked_tables_mode == LTM_LOCK_TABLES - ongoing FTFE or LOCK TABLES --- mysql-test/suite/galera/r/MDEV-22232.result | 4 +- mysql-test/suite/galera/r/MDEV-32938.result | 7 +- .../galera/r/galera_as_slave_ctas.result | 3 + .../suite/galera/r/galera_bf_abort.result | 3 + .../r/galera_create_table_as_select.result | 2 +- mysql-test/suite/galera/suite.pm | 1 + mysql-test/suite/galera/t/MDEV-22232.test | 4 +- mysql-test/suite/galera/t/MDEV-32938.test | 18 +- .../suite/galera/t/galera_as_slave_ctas.test | 3 + .../suite/galera/t/galera_bf_abort.test | 2 + .../t/galera_create_table_as_select.test | 2 +- sql/service_wsrep.cc | 5 + sql/sql_class.cc | 8 + sql/wsrep_mysqld.cc | 159 ++++++++++-------- sql/wsrep_mysqld.h | 4 +- sql/wsrep_thd.cc | 2 +- sql/wsrep_thd.h | 15 +- 17 files changed, 151 insertions(+), 91 deletions(-) diff --git a/mysql-test/suite/galera/r/MDEV-22232.result b/mysql-test/suite/galera/r/MDEV-22232.result index 79db271bc50..6ba9cd7b55b 100644 --- a/mysql-test/suite/galera/r/MDEV-22232.result +++ b/mysql-test/suite/galera/r/MDEV-22232.result @@ -9,7 +9,7 @@ connection node_1; SET DEBUG_SYNC = 'now WAIT_FOR may_run'; TRUNCATE TABLE t1; connection con1; -ERROR 70100: Query execution was interrupted +Got one of the listed errors SET DEBUG_SYNC = 'RESET'; --- CTAS with non-empty result set --- INSERT INTO t1 VALUES (10), (20), (30); @@ -19,7 +19,7 @@ connection node_1; SET DEBUG_SYNC = 'now WAIT_FOR may_run'; TRUNCATE TABLE t1; connection con1; -ERROR 70100: Query execution was interrupted +Got one of the listed errors SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; disconnect con1; diff --git a/mysql-test/suite/galera/r/MDEV-32938.result b/mysql-test/suite/galera/r/MDEV-32938.result index 5e310eb7843..492434d06ca 100644 --- a/mysql-test/suite/galera/r/MDEV-32938.result +++ b/mysql-test/suite/galera/r/MDEV-32938.result @@ -3,16 +3,15 @@ connection node_1; connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; -SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter WAIT_FOR bf_abort'; +SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter'; ALTER TABLE t1 DROP COLUMN c2; connection node_1; SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; ALTER TABLE t1 ADD COLUMN c3 INT; connection con1; -ERROR 70100: Query execution was interrupted -INSERT INTO t1 (c1, c2, c3) VALUES (1, 0, 0); +INSERT INTO t1 (c1, c3) VALUES (1, 0); connection node_2; -INSERT INTO t1 (c1, c2, c3) VALUES (2, 0, 0); +INSERT INTO t1 (c1, c3) VALUES (2, 0); connection node_1; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_as_slave_ctas.result b/mysql-test/suite/galera/r/galera_as_slave_ctas.result index a3d28ce42aa..7e057aab176 100644 --- a/mysql-test/suite/galera/r/galera_as_slave_ctas.result +++ b/mysql-test/suite/galera/r/galera_as_slave_ctas.result @@ -24,8 +24,11 @@ connection node_3; DROP TABLE source; DROP TABLE target; connection node_2; +call mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on"); +call mtr.add_suppression("WSREP: Failed to apply write set: gtid:"); connection node_1; STOP SLAVE; RESET SLAVE ALL; +call mtr.add_suppression("WSREP: unexpected async replication event: 0"); connection node_3; RESET MASTER; diff --git a/mysql-test/suite/galera/r/galera_bf_abort.result b/mysql-test/suite/galera/r/galera_bf_abort.result index cb4a27c82fd..82160eca700 100644 --- a/mysql-test/suite/galera/r/galera_bf_abort.result +++ b/mysql-test/suite/galera/r/galera_bf_abort.result @@ -12,6 +12,9 @@ connection node_2a; connection node_2; INSERT INTO t1 VALUES (2, 'node_2'); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; wsrep_local_aborts_increment 1 DROP TABLE t1; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/r/galera_create_table_as_select.result b/mysql-test/suite/galera/r/galera_create_table_as_select.result index 4ee313fd683..cac68d11cc5 100644 --- a/mysql-test/suite/galera/r/galera_create_table_as_select.result +++ b/mysql-test/suite/galera/r/galera_create_table_as_select.result @@ -88,7 +88,7 @@ COUNT(*) = 5 1 CREATE TABLE t1 AS SELECT * FROM t2; connection node_1; -ERROR 70100: Query execution was interrupted +Got one of the listed errors SET GLOBAL DEBUG_DBUG = ''; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm index 55cdde373c5..3c174d90552 100644 --- a/mysql-test/suite/galera/suite.pm +++ b/mysql-test/suite/galera/suite.pm @@ -68,6 +68,7 @@ push @::global_suppressions, qr|WSREP: Trying to continue unpaused monitor|, qr|WSREP: Wait for gtid returned error 3 while waiting for prior transactions to commit before setting position|, qr|WSREP: Failed to report last committed|, + qr|bytes freed by|, ); sub which($) { return `sh -c "command -v $_[0]"` } diff --git a/mysql-test/suite/galera/t/MDEV-22232.test b/mysql-test/suite/galera/t/MDEV-22232.test index 087d6417b01..473766c6188 100644 --- a/mysql-test/suite/galera/t/MDEV-22232.test +++ b/mysql-test/suite/galera/t/MDEV-22232.test @@ -31,7 +31,7 @@ TRUNCATE TABLE t1; --connection con1 # CTAS gets BF aborted. ---error ER_QUERY_INTERRUPTED +--error ER_QUERY_INTERRUPTED, ER_LOCK_DEADLOCK --reap # Cleanup @@ -56,7 +56,7 @@ TRUNCATE TABLE t1; --connection con1 # CTAS gets BF aborted. ---error ER_QUERY_INTERRUPTED +--error ER_QUERY_INTERRUPTED, ER_LOCK_DEADLOCK --reap # Cleanup diff --git a/mysql-test/suite/galera/t/MDEV-32938.test b/mysql-test/suite/galera/t/MDEV-32938.test index cb41f21a58a..4d22f984abc 100644 --- a/mysql-test/suite/galera/t/MDEV-32938.test +++ b/mysql-test/suite/galera/t/MDEV-32938.test @@ -14,7 +14,9 @@ # - after entering TOI mode, it would later find it'd been killed, and complete with an error # - at the same time, the command would successfully apply on every other node except the initiator. # -# Fixed by checking killed state on THD before entering TOI. +# +# NOTE : After MDL-lock conflict resolution rework this test behaviour has +# changed. # --source include/galera_cluster.inc @@ -28,26 +30,24 @@ call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; # Run ALTER DROP COLUMN and hang before closing tables on adding FK keys and before entering TOI. -# Wait until it gets BF-aborted. -SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter WAIT_FOR bf_abort'; +SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter'; --send ALTER TABLE t1 DROP COLUMN c2; --connection node_1 -# Run ALTER ADD COLUMN and BF-abort the previous ALTER DROP COLUMN. +# Run ALTER ADD COLUMN SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; ALTER TABLE t1 ADD COLUMN c3 INT; --connection con1 -# ALTER DROP COLUMN gets BF aborted. ---error ER_QUERY_INTERRUPTED +# ALTER DROP COLUMN waits --reap -INSERT INTO t1 (c1, c2, c3) VALUES (1, 0, 0); +INSERT INTO t1 (c1, c3) VALUES (1, 0); --connection node_2 -# ALTER DROP COLUMN must not be replicated. -INSERT INTO t1 (c1, c2, c3) VALUES (2, 0, 0); +# ALTER DROP COLUMN must be replicated. +INSERT INTO t1 (c1, c3) VALUES (2, 0); # Cleanup. --connection node_1 diff --git a/mysql-test/suite/galera/t/galera_as_slave_ctas.test b/mysql-test/suite/galera/t/galera_as_slave_ctas.test index 36d7f00ae87..1ea80458979 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_ctas.test +++ b/mysql-test/suite/galera/t/galera_as_slave_ctas.test @@ -66,10 +66,13 @@ DROP TABLE target; --connection node_2 --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target'; --source include/wait_condition.inc +call mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on"); +call mtr.add_suppression("WSREP: Failed to apply write set: gtid:"); --connection node_1 STOP SLAVE; RESET SLAVE ALL; +call mtr.add_suppression("WSREP: unexpected async replication event: 0"); --connection node_3 RESET MASTER; diff --git a/mysql-test/suite/galera/t/galera_bf_abort.test b/mysql-test/suite/galera/t/galera_bf_abort.test index f3476fba490..d5020c172d7 100644 --- a/mysql-test/suite/galera/t/galera_bf_abort.test +++ b/mysql-test/suite/galera/t/galera_bf_abort.test @@ -24,6 +24,7 @@ INSERT INTO t1 VALUES (1,'node_1'); --connection node_2 --error ER_LOCK_DEADLOCK INSERT INTO t1 VALUES (2, 'node_2'); +COMMIT; --let $wsrep_local_bf_aborts_after = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` @@ -32,3 +33,4 @@ INSERT INTO t1 VALUES (2, 'node_2'); --enable_query_log DROP TABLE t1; +--source include/galera_end.inc diff --git a/mysql-test/suite/galera/t/galera_create_table_as_select.test b/mysql-test/suite/galera/t/galera_create_table_as_select.test index 63af9b552e0..1511f3a7f63 100644 --- a/mysql-test/suite/galera/t/galera_create_table_as_select.test +++ b/mysql-test/suite/galera/t/galera_create_table_as_select.test @@ -121,7 +121,7 @@ SELECT COUNT(*) = 5 FROM t2; CREATE TABLE t1 AS SELECT * FROM t2; --connection node_1 ---error ER_QUERY_INTERRUPTED +--error ER_QUERY_INTERRUPTED,ER_LOCK_DEADLOCK --reap SET GLOBAL DEBUG_DBUG = ''; diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 9d04849aadb..f34245ad377 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -226,6 +226,11 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, */ if ((ret || !wsrep_on(victim_thd)) && signal) { + WSREP_DEBUG("wsrep_thd_bf_abort thread %ld sending " + "KILL_QUERY_HARD to %ld ret=%d signal %d", + bf_thd->thread_id, + victim_thd->thread_id, + ret, signal); victim_thd->wsrep_aborter= bf_thd->thread_id; victim_thd->awake_no_mutex(KILL_QUERY_HARD); } else { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1cfca806f36..a5155b9955d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2182,6 +2182,10 @@ int THD::killed_errno() DBUG_RETURN(ER_CONNECTION_KILLED); case KILL_QUERY: case KILL_QUERY_HARD: +#ifdef WITH_WSREP + if (WSREP(this)) + wsrep_report_query_interrupted(this, __FILE__, __LINE__); +#endif /* WITH_WSREP */ DBUG_RETURN(ER_QUERY_INTERRUPTED); case KILL_TIMEOUT: case KILL_TIMEOUT_HARD: @@ -8352,6 +8356,10 @@ wait_for_commit::wait_for_prior_commit2(THD *thd, bool allow_kill) wakeup_error= ER_QUERY_INTERRUPTED; my_message(wakeup_error, ER_THD(thd, wakeup_error), MYF(0)); thd->EXIT_COND(&old_stage); +#ifdef WITH_WSREP + if (WSREP(thd)) + wsrep_report_query_interrupted(thd, __FILE__, __LINE__); +#endif /* WITH_WSREP */ /* Must do the DEBUG_SYNC() _after_ exit_cond(), as DEBUG_SYNC is not safe to use within enter_cond/exit_cond. diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a5840875ff7..f08dec7fc84 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -3227,18 +3227,21 @@ void wsrep_to_isolation_end(THD *thd) if (wsrep_emulate_bin_log) wsrep_thd_binlog_trx_reset(thd); } -#define WSREP_MDL_LOG(severity, msg, schema, schema_len, req, gra) \ - WSREP_##severity( \ - "%s\n" \ - "schema: %.*s\n" \ - "request: (%llu \tseqno %lld \twsrep (%s, %s, %s) cmd %d %d \t%s)\n" \ - "granted: (%llu \tseqno %lld \twsrep (%s, %s, %s) cmd %d %d \t%s)", \ - msg, schema_len, schema, \ - req->thread_id, (long long)wsrep_thd_trx_seqno(req), \ - wsrep_thd_client_mode_str(req), wsrep_thd_client_state_str(req), wsrep_thd_transaction_state_str(req), \ - req->get_command(), req->lex->sql_command, req->query(), \ - gra->thread_id, (long long)wsrep_thd_trx_seqno(gra), \ - wsrep_thd_client_mode_str(gra), wsrep_thd_client_state_str(gra), wsrep_thd_transaction_state_str(gra), \ +#define WSREP_MDL_LOG(severity, msg, schema, schema_len, name, name_len, req, gra) \ + WSREP_##severity( \ + "%s\n" \ + "schema.name: %.*s.%.*s\n" \ + "request: (%llu \tseqno %lld \twsrep (%s, %s, %s, BF%d) cmd %d %d \t%s)\n" \ + "granted: (%llu \tseqno %lld \twsrep (%s, %s, %s, BF%d) cmd %d %d \t%s)", \ + msg, schema_len, schema, \ + name_len, name, \ + req->thread_id, wsrep_thd_trx_seqno(req), \ + wsrep_thd_client_mode_str(req), wsrep_thd_client_state_str(req), \ + wsrep_thd_transaction_state_str(req), wsrep_thd_is_BF(req, false), \ + req->get_command(), req->lex->sql_command, req->query(), \ + gra->thread_id, wsrep_thd_trx_seqno(gra), \ + wsrep_thd_client_mode_str(gra), wsrep_thd_client_state_str(gra), \ + wsrep_thd_transaction_state_str(gra), wsrep_thd_is_BF(gra, false), \ gra->get_command(), gra->lex->sql_command, gra->query()); /** @@ -3260,6 +3263,8 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, mysql_mutex_lock(&request_thd->LOCK_thd_data); + // If requestor is not BF it has to wait for + // release of MDL-lock. if (wsrep_thd_is_toi(request_thd) || wsrep_thd_is_applying(request_thd)) { @@ -3267,13 +3272,13 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, const char* schema= key->db_name(); int schema_len= key->db_name_length(); + const char* name= key->name(); + int name_len= key->name_length(); - WSREP_DEBUG("wsrep_handle_mdl_conflict request TOI/APPLY for %s", - wsrep_thd_query(request_thd)); THD_STAGE_INFO(request_thd, stage_waiting_isolation); mysql_mutex_unlock(&request_thd->LOCK_thd_data); WSREP_MDL_LOG(DEBUG, "MDL conflict ", schema, schema_len, - request_thd, granted_thd); + name, name_len, request_thd, granted_thd); ticket->wsrep_report(wsrep_debug); DEBUG_SYNC(request_thd, "before_wsrep_thd_abort"); @@ -3293,109 +3298,103 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, if (granted_thd->wsrep_aborter != 0) { + // Granted thread has being already selected as a victim for + // BF kill, we can wait until it releases MDL-lock DBUG_ASSERT(granted_thd->wsrep_aborter == request_thd->thread_id); WSREP_DEBUG("BF thread waiting for a victim to release locks"); } else if (wsrep_thd_is_toi(granted_thd) || wsrep_thd_is_applying(granted_thd)) { + // Here both request thread and granted thread are either TOI + // or applying. if (wsrep_thd_is_aborting(granted_thd)) { - WSREP_DEBUG("BF thread waiting for SR in aborting state for %s", - wsrep_thd_query(request_thd)); - THD_STAGE_INFO(request_thd, stage_waiting_isolation); + // Granted thread is aborting, we wait it to release MDL-locs + WSREP_DEBUG("BF thread for %s waiting for thread in aborting state for %s", + wsrep_thd_query(request_thd), + wsrep_thd_query(granted_thd)); ticket->wsrep_report(wsrep_debug); } else if (wsrep_thd_is_SR(granted_thd) && !wsrep_thd_is_SR(request_thd)) { + // Granted thread is executing streaming replication and request is DDL, + // abort granted WSREP_MDL_LOG(INFO, "MDL conflict, DDL vs SR", - schema, schema_len, request_thd, granted_thd); - WSREP_DEBUG("wsrep_handle_mdl_conflict DDL vs SR for %s", - wsrep_thd_query(request_thd)); - THD_STAGE_INFO(request_thd, stage_waiting_isolation); + schema, schema_len, name, name_len, + request_thd, granted_thd); wsrep_abort_thd(request_thd, granted_thd, 1); } else { + DBUG_ASSERT(0); + // In this case request thread waits WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", schema, schema_len, - request_thd, granted_thd); + name, name_len, request_thd, granted_thd); ticket->wsrep_report(true); - mysql_mutex_unlock(&granted_thd->LOCK_thd_data); - mysql_mutex_unlock(&granted_thd->LOCK_thd_kill); - unireg_abort(1); } } - else if (granted_thd->lex->sql_command == SQLCOM_FLUSH || - /* System transactions with explicit locks are BACKUP. */ - (granted_thd->system_thread != NON_SYSTEM_THREAD && - granted_thd->mdl_context.has_explicit_locks())) + /* If granted thread has + ongoing BACKUP OR + ongoing FLUSH TABLES WITH READ LOCK OR + ongoing FLUSH TABLES FOR EXPORT OR LOCK TABLES + */ + else if (granted_thd->current_backup_stage != BACKUP_FINISHED || + granted_thd->global_read_lock.is_acquired() || + granted_thd->locked_tables_mode == LTM_LOCK_TABLES) { WSREP_DEBUG("BF thread waiting for %s", - granted_thd->lex->sql_command == SQLCOM_FLUSH ? "FLUSH" : "BACKUP"); + (granted_thd->current_backup_stage != BACKUP_FINISHED ? "BACKUP" : + (granted_thd->global_read_lock.is_acquired() ? "FTWRL" : "LOCK TABLES"))); ticket->wsrep_report(wsrep_debug); if (granted_thd->current_backup_stage != BACKUP_FINISHED && - wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP)) + wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP)) { - wsrep_abort_thd(request_thd, granted_thd, 1); + // User has allowed killing mariabackup + wsrep_abort_thd(request_thd, granted_thd, 1); } } - else if (granted_thd->lex->sql_command == SQLCOM_LOCK_TABLES) - { - WSREP_DEBUG("BF thread waiting for LOCK TABLES"); - ticket->wsrep_report(wsrep_debug); - } - else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE) - { - WSREP_DEBUG("DROP caused BF abort, conf %s for %s", - wsrep_thd_transaction_state_str(granted_thd), - wsrep_thd_query(request_thd)); - THD_STAGE_INFO(request_thd, stage_waiting_isolation); - ticket->wsrep_report(wsrep_debug); - wsrep_abort_thd(request_thd, granted_thd, 1); - } else { WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", schema, schema_len, - request_thd, granted_thd); + name, name_len, request_thd, granted_thd); WSREP_DEBUG("wsrep_handle_mdl_conflict -> BF abort for %s", - wsrep_thd_query(request_thd)); - THD_STAGE_INFO(request_thd, stage_waiting_isolation); + wsrep_thd_query(granted_thd)); ticket->wsrep_report(wsrep_debug); if (granted_thd->wsrep_trx().active()) { + // Granted thread has active wsrep transaction wsrep_abort_thd(request_thd, granted_thd, 1); } + else if (!WSREP(granted_thd) || + wsrep_thd_is_BF(granted_thd, false)) + { + // Granted thread is not wsrep transaction or it is not BF kill it + WSREP_MDL_LOG(DEBUG, "MDL conflict-> kill", schema, schema_len, + name, name_len, request_thd, granted_thd); + granted_thd->awake_no_mutex(KILL_QUERY_HARD); + ha_abort_transaction(request_thd, granted_thd, TRUE); + } else { - /* - Granted_thd is likely executing with wsrep_on=0. If the requesting - thd is BF, BF abort and wait. - */ - if (wsrep_thd_is_BF(request_thd, FALSE)) - { - granted_thd->awake_no_mutex(KILL_QUERY_HARD); - ha_abort_transaction(request_thd, granted_thd, TRUE); - } - else - { - WSREP_MDL_LOG(INFO, "MDL unknown BF-BF conflict", - schema, schema_len, - request_thd, granted_thd); - ticket->wsrep_report(true); - mysql_mutex_unlock(&granted_thd->LOCK_thd_data); - mysql_mutex_unlock(&granted_thd->LOCK_thd_kill); - unireg_abort(1); - } + WSREP_DEBUG("MDL conflig-> wait request BF:%ld:%s granted %s:%ld query %s", + request_thd->thread_id, + wsrep_thd_query(request_thd), + (wsrep_thd_is_BF(granted_thd, FALSE) ? "LOCAL" : "BF"), + granted_thd->thread_id, + wsrep_thd_query(granted_thd)); } } + mysql_mutex_unlock(&granted_thd->LOCK_thd_data); mysql_mutex_unlock(&granted_thd->LOCK_thd_kill); DEBUG_SYNC(request_thd, "after_wsrep_thd_abort"); } else { + // Request thread is normal local transaction it has to wait mysql_mutex_unlock(&request_thd->LOCK_thd_data); } } @@ -4154,3 +4153,25 @@ bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk) return false; } + +void wsrep_report_query_interrupted(const THD *thd, const char *file, const int line) +{ + const wsrep::client_error ce= wsrep_current_error(thd); + const enum wsrep::provider::status status= wsrep_current_error_status(thd); + + WSREP_DEBUG("Query %s interrupted client_error %s provider_status %s in %s:%d", + wsrep_thd_query(thd), + wsrep::to_string(ce).c_str(), + wsrep::provider::to_string(status).c_str(), + file, line); + + if (ce != wsrep::e_success) + { + push_warning_printf((THD *)thd, Sql_condition::WARN_LEVEL_WARN, + ER_QUERY_INTERRUPTED, + "Query interrupted or killed client_error: %s provider_status: %s killed: %d", + wsrep::to_string(ce).c_str(), + wsrep::provider::to_string(status).c_str(), + thd->killed); + } +} diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index e2be203ef27..9a8fcdcf8bf 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2023 Codership Oy +/* Copyright 2008-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -610,6 +610,8 @@ bool wsrep_table_list_has_non_temp_tables(THD *thd, TABLE_LIST *tables); */ bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk); +void wsrep_report_query_interrupted(const THD *thd, const char* file, const int line); + #else /* !WITH_WSREP */ /* These macros are needed to compile MariaDB without WSREP support diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index de91c960222..42f6cdc39be 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2023 Codership Oy +/* Copyright (C) 2013-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index 2fe3e123cea..cf6e089285c 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2023 Codership Oy +/* Copyright (C) 2013-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -198,6 +198,18 @@ void wsrep_store_threadvars(THD *); */ void wsrep_reset_threadvars(THD *); +static inline enum wsrep::client_error wsrep_current_error(const THD* thd) +{ + return thd->wsrep_cs().current_error(); +} + +static inline enum wsrep::provider::status + wsrep_current_error_status(const THD* thd) +{ + return thd->wsrep_cs().current_error_status(); +} + + /** Helper functions to override error status @@ -267,6 +279,7 @@ static inline void wsrep_override_error(THD* thd, } break; case wsrep::e_interrupted_error: + wsrep_report_query_interrupted(thd, __FILE__, __LINE__); wsrep_override_error(thd, ER_QUERY_INTERRUPTED); break; case wsrep::e_size_exceeded_error: From a8471426f473d687c6694d7911e76c1613d05837 Mon Sep 17 00:00:00 2001 From: Raghunandan Bhat Date: Mon, 12 Jan 2026 12:02:14 +0530 Subject: [PATCH 075/152] MDEV-38487: Prevent aggregate function cloning when pushing HAVING into WHERE Problem: When building a pushable condition that can be pushed from HAVING into WHERE, the server tries to clone aggregate functions. This is not necessary because aggregate functions can not be pushed into WHERE anyway. Fix: This fix introduces a check within `Item::build_pushable_cond` to skip cloning aggregate functions. Also fixes assert failure in MDEV-38492, by adding a missing copy method for `Item_aggregate_ref`. --- mysql-test/main/derived_cond_pushdown.result | 79 ++++++++++++++ mysql-test/main/derived_cond_pushdown.test | 22 ++++ mysql-test/main/having_cond_pushdown.result | 103 +++++++++++++++++++ mysql-test/main/having_cond_pushdown.test | 29 ++++++ sql/item.cc | 8 ++ 5 files changed, 241 insertions(+) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index e418f56778f..c9e69b5884e 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -19135,3 +19135,82 @@ where cte1.a >= 1; a drop table t; # End of 10.5 tests +# +# MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +# +CREATE TABLE t (a INT, b INT); +INSERT INTO t VALUES (1, 10), (1, 20), (2, 50), (3, 100); +explain format=JSON SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 4, + "filtered": 100, + "attached_condition": "dt.max_b > 25", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "max_b > 25", + "filesort": { + "sort_key": "t.a", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 4, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +a max_b +2 50 +3 100 +CREATE VIEW v AS SELECT a, MAX(b) as max_b FROM t GROUP BY a; +explain format=JSON SELECT * FROM v where max_b > 25; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 4, + "filtered": 100, + "attached_condition": "v.max_b > 25", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "max_b > 25", + "filesort": { + "sort_key": "t.a", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 4, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * FROM v where max_b > 25; +a max_b +2 50 +3 100 +DROP VIEW v; +DROP TABLE t; +# End of 10.6 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 92d31ded3a1..5f3c0b4f2e6 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -4294,3 +4294,25 @@ where cte1.a >= 1; drop table t; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +--echo # + +CREATE TABLE t (a INT, b INT); +INSERT INTO t VALUES (1, 10), (1, 20), (2, 50), (3, 100); + +# outer where to inner having pushdown +let $q= SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +eval explain format=JSON $q; +eval $q; + +CREATE VIEW v AS SELECT a, MAX(b) as max_b FROM t GROUP BY a; +let $q= SELECT * FROM v where max_b > 25; +eval explain format=JSON $q; +eval $q; + +DROP VIEW v; +DROP TABLE t; + +--echo # End of 10.6 tests diff --git a/mysql-test/main/having_cond_pushdown.result b/mysql-test/main/having_cond_pushdown.result index 2a5fb5b3de8..21695e8f9c4 100644 --- a/mysql-test/main/having_cond_pushdown.result +++ b/mysql-test/main/having_cond_pushdown.result @@ -5194,3 +5194,106 @@ SELECT LOAD_FILE('') AS f, a FROM t1 GROUP BY f, a HAVING f = a; f a DROP TABLE t1; End of 10.5 tests +# +# MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +# +CREATE TABLE t (c INT); +insert into t values (1), (2), (3); +explain format=JSON SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "t.c = t.c or (/*always not null*/ 1 is null) + interval t.c second and t.c like 1", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } +} +SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +c +1 +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "avg(t.c) > 0", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "t.c > 1" + } + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +c +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "avg(t.c) is not null", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "t.c > 0 and t.c < 10" + } + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +c +1 +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "t.c = 1 or avg(t.c) > 2", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +c +1 +3 +DROP TABLE t; +# End of 10.6 tests diff --git a/mysql-test/main/having_cond_pushdown.test b/mysql-test/main/having_cond_pushdown.test index 190fb8a493f..1ebd64f285b 100644 --- a/mysql-test/main/having_cond_pushdown.test +++ b/mysql-test/main/having_cond_pushdown.test @@ -1601,3 +1601,32 @@ SELECT LOAD_FILE('') AS f, a FROM t1 GROUP BY f, a HAVING f = a; DROP TABLE t1; --echo End of 10.5 tests + +--echo # +--echo # MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +--echo # + +CREATE TABLE t (c INT); +insert into t values (1), (2), (3); +--disable_warnings +let $q= SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +eval explain format=JSON $q; +eval $q; +--enable_warnings + +# Tests to verify all possible conditions are pushed except aggregate function +let $q= SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +eval explain format=JSON $q; +eval $q; + +let $q= SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +eval explain format=JSON $q; +eval $q; + +let $q= SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +eval explain format=JSON $q; +eval $q; + +DROP TABLE t; + +--echo # End of 10.6 tests diff --git a/sql/item.cc b/sql/item.cc index eb432a643c9..a651ef452a0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2305,6 +2305,8 @@ public: Item_ident::print(str, query_type); } Ref_Type ref_type() override final { return AGGREGATE_REF; } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -7840,6 +7842,8 @@ void Item::check_pushable_cond(Pushdown_checker checker, uchar *arg) In the case when this item is a multiple equality a checker method is called to find the equal fields to build a new equality that can be pushed down. + In case when this item is an aggregate function, we skip cloning because + they can not be pushed anyway. @note The built condition C is always implied by the condition cond (cond => C). The method tries to build the most restrictive such @@ -7948,7 +7952,11 @@ Item *Item::build_pushable_cond(THD *thd, return new_cond; } else if (get_extraction_flag() != MARKER_NO_EXTRACTION) + { + if (with_sum_func()) + return 0; return build_clone(thd); + } return 0; } From 496767b310aac2f0bcc55261785f69a00eaf289d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 19 Jan 2026 21:01:27 +0100 Subject: [PATCH 076/152] pcre2 10.47 --- cmake/pcre.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 08353e9236a..9ebab4e66fe 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -8,7 +8,6 @@ MACRO(BUNDLE_PCRE2) "Which pcre to use (possible values are 'bundled', 'system', or 'auto')") SET(dir "${CMAKE_BINARY_DIR}/extra/pcre2") - SET(PCRE_INCLUDE_DIRS ${dir}/src/pcre2-build ${dir}/src/pcre2/src) MESSAGE(STATUS "Will download and bundle pcre2") SET(byproducts) FOREACH(lib pcre2-posix pcre2-8) @@ -43,6 +42,8 @@ MACRO(BUNDLE_PCRE2) ENDIF() SET(byproducts ${byproducts} BUILD_BYPRODUCTS ${file} ${file_d}) SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${file}) + MAKE_DIRECTORY(${dir}/src/pcre2-build/interface) + TARGET_INCLUDE_DIRECTORIES(${lib} INTERFACE ${dir}/src/pcre2-build/interface) ENDFOREACH() FOREACH(v "" "_DEBUG" "_RELWITHDEBINFO" "_RELEASE" "_MINSIZEREL") @@ -64,8 +65,8 @@ MACRO(BUNDLE_PCRE2) ExternalProject_Add( pcre2 PREFIX "${dir}" - URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.45/pcre2-10.45.zip" - URL_MD5 873da56c6469ec207ca5c5ae9688b83a + URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.zip" + URL_MD5 7906aec38f872b74f1b925122dde9069 INSTALL_COMMAND "" CMAKE_ARGS "-DCMAKE_WARN_DEPRECATED=FALSE" From e2c63a7062e3acbe44b8f7122c347183b87cbd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 20 Jan 2026 12:41:27 +0200 Subject: [PATCH 077/152] MDEV-38595: Simplify InnoDB doublewrite buffer creation buf_dblwr_t::create(): Create the doublewrite buffer in a single atomic mini-transaction. Do not write any log records for initializing any doublewrite buffer pages, in order to avoid recovery failure with innodb_log_archive=ON starting from the very beginning. The mtr.commit() in buf_dblwr_t::create() was observed to comprise 295 mtr_t::m_memo entries: 1 entry for the fil_system.sys_space and the rest split between page 5 (TRX_SYS) and page 0 (allocation metadata). We are nowhere near the sux_lock::RECURSIVE_MAX limit of 65535 per page descriptor. Reviewed by: Thirunarayanan Balathandayuthapani Tested by: Saahil Alam --- storage/innobase/buf/buf0dblwr.cc | 98 ++++++++++-------------------- storage/innobase/include/mtr0mtr.h | 3 + 2 files changed, 35 insertions(+), 66 deletions(-) diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 3f26fe23cee..e32b68ed52d 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -93,15 +93,17 @@ start_again: mtr.start(); dberr_t err; - buf_block_t *trx_sys_block= buf_dblwr_trx_sys_get(&mtr); + buf_block_t *const trx_sys_block= buf_dblwr_trx_sys_get(&mtr); if (!trx_sys_block) { mtr.commit(); return false; } - if (mach_read_from_4(TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC + - trx_sys_block->page.frame) == + byte *const fseg_header= TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG + + trx_sys_block->page.frame; + + if (mach_read_from_4(fseg_header + FSEG_HEADER_SIZE) == TRX_SYS_DOUBLEWRITE_MAGIC_N) { /* The doublewrite buffer has already been created: just read in @@ -135,21 +137,21 @@ fail: sql_print_information("InnoDB: Doublewrite buffer not found:" " creating new"); - /* FIXME: After this point, the doublewrite buffer creation - is not atomic. The doublewrite buffer should not exist in + /* FIXME: The doublewrite buffer should not exist in the InnoDB system tablespace file in the first place. It could be located in separate optional file(s) in a user-specified location. */ } - byte *fseg_header= TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG + - trx_sys_block->page.frame; + mtr_t init_mtr; + init_mtr.start(); + for (uint32_t prev_page_no= 0, i= 0, extent_size= FSP_EXTENT_SIZE; i < 2 * size + extent_size / 2; i++) { buf_block_t *new_block= fseg_alloc_free_page_general(fseg_header, prev_page_no + 1, FSP_UP, - false, &mtr, &mtr, &err); + false, &mtr, &init_mtr, &err); if (!new_block) { sql_print_error("InnoDB: Cannot create doublewrite buffer: " @@ -164,75 +166,39 @@ fail: return false; } - /* We read the allocated pages to the buffer pool; when they are - written to disk in a flush, the space id and page number fields - are also written to the pages. When we at database startup read - pages from the doublewrite buffer, we know that if the space id - and page number in them are the same as the page position in the - tablespace, then the page has not been written to in - doublewrite. */ - - ut_ad(new_block->page.lock.not_recursive()); const page_id_t id= new_block->page.id(); - /* We only do this in the debug build, to ensure that the check in - buf_flush_init_for_writing() will see a valid page type. The - flushes of new_block are actually unnecessary here. */ - ut_d(mtr.write<2>(*new_block, FIL_PAGE_TYPE + new_block->page.frame, - FIL_PAGE_TYPE_SYS)); + /* Normally, allocated pages will be modified further. However, + the pages of the doublewrite buffer are just dummy storage, not + covered by the write-ahead log. */ + ut_ad(init_mtr.get_savepoint() == 1); + ut_ad(init_mtr.m_memo[0].object == new_block); + ut_ad(init_mtr.m_memo[0].type == MTR_MEMO_PAGE_X_MODIFY); + init_mtr.m_memo[0].type= MTR_MEMO_PAGE_X_FIX; + init_mtr.rollback_to_savepoint(0, 1); + init_mtr.m_log.erase(); if (i == size / 2) - { ut_a(id.page_no() == size); - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_BLOCK1 + - trx_sys_block->page.frame, id.page_no()); - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_REPEAT + - TRX_SYS_DOUBLEWRITE_BLOCK1 + trx_sys_block->page.frame, - id.page_no()); - } else if (i == size / 2 + size) - { ut_a(id.page_no() == 2 * size); - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_BLOCK2 + - trx_sys_block->page.frame, id.page_no()); - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_REPEAT + - TRX_SYS_DOUBLEWRITE_BLOCK2 + trx_sys_block->page.frame, - id.page_no()); - } else if (i > size / 2) ut_a(id.page_no() == prev_page_no + 1); - - if (((i + 1) & 15) == 0) { - /* rw_locks can only be recursively x-locked 2048 times. (on 32 - bit platforms, (lint) 0 - (X_LOCK_DECR * 2049) is no longer a - negative number, and thus lock_word becomes like a shared lock). - For 4k page size this loop will lock the fseg header too many - times. Since this code is not done while any other threads are - active, restart the MTR occasionally. */ - mtr.commit(); - mtr.start(); - trx_sys_block= buf_dblwr_trx_sys_get(&mtr); - fseg_header= TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG + - trx_sys_block->page.frame; - } - prev_page_no= id.page_no(); } - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC + - trx_sys_block->page.frame, TRX_SYS_DOUBLEWRITE_MAGIC_N); - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC + - TRX_SYS_DOUBLEWRITE_REPEAT + trx_sys_block->page.frame, - TRX_SYS_DOUBLEWRITE_MAGIC_N); - - mtr.write<4>(*trx_sys_block, - TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED + - trx_sys_block->page.frame, + ut_ad(init_mtr.is_empty()); + byte *const doublewrite= fseg_header + + (TRX_SYS_DOUBLEWRITE_MAGIC - TRX_SYS_DOUBLEWRITE_FSEG); + mtr.write<4>(*trx_sys_block, doublewrite, TRX_SYS_DOUBLEWRITE_MAGIC_N); + static_assert(TRX_SYS_DOUBLEWRITE_BLOCK1==TRX_SYS_DOUBLEWRITE_MAGIC + 4, ""); + mtr.write<4>(*trx_sys_block, doublewrite + 4, size); + static_assert(TRX_SYS_DOUBLEWRITE_BLOCK2==TRX_SYS_DOUBLEWRITE_MAGIC + 8, ""); + mtr.write<4>(*trx_sys_block, doublewrite + 8, size * 2); + static_assert(TRX_SYS_DOUBLEWRITE_REPEAT == 12, ""); + mtr.memcpy(*trx_sys_block, doublewrite + 12, doublewrite, 12); + static_assert(TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED == + 24 + TRX_SYS_DOUBLEWRITE_MAGIC, ""); + mtr.write<4>(*trx_sys_block, doublewrite + 24, TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N); mtr.commit(); diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 3828a31cdb5..f0395748c8b 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -63,10 +63,13 @@ struct mtr_memo_slot_t void release() const; }; +class buf_dblwr_t; + /** Mini-transaction handle and buffer */ struct mtr_t { mtr_t(); ~mtr_t(); + friend buf_dblwr_t; /** Start a mini-transaction. */ void start(); From 6c4aedae5ee4fb614fe25be784a4c02f1580b8e4 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 20 Jan 2026 11:15:34 +0100 Subject: [PATCH 078/152] new HeidiSQL --- win/packaging/heidisql.cmake | 2 +- win/packaging/heidisql.wxi.in | 36 ++++++++++++++--------------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 33d3e84b875..eb0418f1a0f 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_12.11_64_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_12.14_64_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "https://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) diff --git a/win/packaging/heidisql.wxi.in b/win/packaging/heidisql.wxi.in index e4089be7204..cec4005a477 100644 --- a/win/packaging/heidisql.wxi.in +++ b/win/packaging/heidisql.wxi.in @@ -49,15 +49,17 @@ + + + + + + + + - - - - - - @@ -65,22 +67,15 @@ - - - - - - - - + - - + + @@ -137,19 +132,16 @@ - - - - - - + + + From 540e6daeee3ee9413e6c3cb4305d349bbb3a2dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 19 Jan 2026 09:36:06 +0200 Subject: [PATCH 079/152] MDEV-37984 : Test failure on galera.MDEV-34647 Make sure that both nodes uses intended auto_increment configuration, all tables and rows are replicated and ordered correctly. --- mysql-test/suite/galera/r/MDEV-34647.result | 97 ++++++++++++--------- mysql-test/suite/galera/t/MDEV-34647.cnf | 13 +-- mysql-test/suite/galera/t/MDEV-34647.test | 37 +++++--- 3 files changed, 90 insertions(+), 57 deletions(-) diff --git a/mysql-test/suite/galera/r/MDEV-34647.result b/mysql-test/suite/galera/r/MDEV-34647.result index 0bdab65d963..b535acbe6b9 100644 --- a/mysql-test/suite/galera/r/MDEV-34647.result +++ b/mysql-test/suite/galera/r/MDEV-34647.result @@ -1,51 +1,61 @@ connection node_2; connection node_1; +connection node_1; +set global auto_increment_offset=1; +set global auto_increment_increment=1; +connection node_2; +set global auto_increment_offset=2; +set global auto_increment_increment=1; +connection node_1; +select @@auto_increment_increment,@@auto_increment_offset; +@@auto_increment_increment @@auto_increment_offset +1 1 create table t1(id serial, val varchar(100)) engine=myisam; insert into t1 values(null, 'a'); insert into t1 values(null, 'b'); insert into t1 select null, 'c'; insert into t1 select null, 'd' from t1; -select * from t1; +select * from t1 order by id; id val 1 a -3 b -5 c -7 d -9 d -11 d +2 b +3 c +4 d +5 d +6 d create table t2(id serial, val varchar(100)) engine=aria; insert into t2 values(null, 'a'); insert into t2 values(null, 'b'); insert into t2 select null, 'c'; insert into t2 select null, 'd' from t2; -select * from t2; +select * from t2 order by id; id val 1 a -3 b -5 c -7 d -9 d -11 d +2 b +3 c +4 d +5 d +6 d create table t3(id serial, val varchar(100)) engine=innodb; insert into t3 values(null, 'a'); insert into t3 values(null, 'b'); insert into t3 select null, 'c'; insert into t3 select null, 'd' from t3; -select * from t3; +select * from t3 order by id; id val 1 a -3 b -5 c -7 d -9 d -11 d +2 b +3 c +4 d +5 d +6 d set global wsrep_mode='REPLICATE_MYISAM,REPLICATE_ARIA'; create table t4(id serial, val varchar(100)) engine=myisam; insert into t4 values(null, 'a'); insert into t4 values(null, 'b'); insert into t4 select null, 'c'; insert into t4 select null, 'd' from t4; -select * from t4; +select * from t4 order by id; id val 1 a 2 b @@ -58,28 +68,7 @@ insert into t5 values(null, 'a'); insert into t5 values(null, 'b'); insert into t5 select null, 'c'; insert into t5 select null, 'd' from t5; -select * from t2; -id val -1 a -3 b -5 c -7 d -9 d -11 d -connection node_2; -select * from t1; -id val -select * from t2; -id val -select * from t3; -id val -1 a -3 b -5 c -7 d -9 d -11 d -select * from t4; +select * from t5 order by id; id val 1 a 2 b @@ -87,7 +76,31 @@ id val 4 d 5 d 6 d -select * from t5; +connection node_2; +select @@auto_increment_increment,@@auto_increment_offset; +@@auto_increment_increment @@auto_increment_offset +1 2 +select * from t1 order by id; +id val +select * from t2 order by id; +id val +select * from t3 order by id; +id val +1 a +2 b +3 c +4 d +5 d +6 d +select * from t4 order by id; +id val +1 a +2 b +3 c +4 d +5 d +6 d +select * from t5 order by id; id val 1 a 2 b diff --git a/mysql-test/suite/galera/t/MDEV-34647.cnf b/mysql-test/suite/galera/t/MDEV-34647.cnf index 1b8791ae398..d6475b23f21 100644 --- a/mysql-test/suite/galera/t/MDEV-34647.cnf +++ b/mysql-test/suite/galera/t/MDEV-34647.cnf @@ -1,13 +1,16 @@ !include ../galera_2nodes.cnf [mysqld] +loose-mdev-34647 + +[mysqld.1] +auto-increment-increment=1 +auto-increment-offset=1 log-bin log-slave-updates -[mysqld.1] -auto-increment-increment=2 -auto-increment-offset=1 - [mysqld.2] auto-increment-increment=2 -auto-increment-offset=2 +auto-increment-offset=1 +log-bin +log-slave-updates diff --git a/mysql-test/suite/galera/t/MDEV-34647.test b/mysql-test/suite/galera/t/MDEV-34647.test index 2cf4b627f76..1833c1a2000 100644 --- a/mysql-test/suite/galera/t/MDEV-34647.test +++ b/mysql-test/suite/galera/t/MDEV-34647.test @@ -1,27 +1,38 @@ --source include/galera_cluster.inc --source include/have_innodb.inc --source include/have_aria.inc +--source include/force_restart.inc +--connection node_1 +set global auto_increment_offset=1; +set global auto_increment_increment=1; + +--connection node_2 +set global auto_increment_offset=2; +set global auto_increment_increment=1; + +--connection node_1 +select @@auto_increment_increment,@@auto_increment_offset; create table t1(id serial, val varchar(100)) engine=myisam; insert into t1 values(null, 'a'); insert into t1 values(null, 'b'); insert into t1 select null, 'c'; insert into t1 select null, 'd' from t1; -select * from t1; +select * from t1 order by id; create table t2(id serial, val varchar(100)) engine=aria; insert into t2 values(null, 'a'); insert into t2 values(null, 'b'); insert into t2 select null, 'c'; insert into t2 select null, 'd' from t2; -select * from t2; +select * from t2 order by id; create table t3(id serial, val varchar(100)) engine=innodb; insert into t3 values(null, 'a'); insert into t3 values(null, 'b'); insert into t3 select null, 'c'; insert into t3 select null, 'd' from t3; -select * from t3; +select * from t3 order by id; set global wsrep_mode='REPLICATE_MYISAM,REPLICATE_ARIA'; @@ -30,21 +41,27 @@ insert into t4 values(null, 'a'); insert into t4 values(null, 'b'); insert into t4 select null, 'c'; insert into t4 select null, 'd' from t4; -select * from t4; +select * from t4 order by id; create table t5(id serial, val varchar(100)) engine=myisam; insert into t5 values(null, 'a'); insert into t5 values(null, 'b'); insert into t5 select null, 'c'; insert into t5 select null, 'd' from t5; -select * from t2; +select * from t5 order by id; --connection node_2 -select * from t1; -select * from t2; -select * from t3; -select * from t4; -select * from t5; +select @@auto_increment_increment,@@auto_increment_offset; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't5' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 6 FROM t5 +--source include/wait_condition.inc + +select * from t1 order by id; +select * from t2 order by id; +select * from t3 order by id; +select * from t4 order by id; +select * from t5 order by id; --connection node_1 drop table t1,t2,t3,t4,t5; From 52b1d7eb7f8fd21e851e2ffddb73e22f2ae3789c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 20 Jan 2026 14:19:35 +0100 Subject: [PATCH 080/152] libfmt 12.1 - Suppress warning, MSVC-specific discarding return value of function with [[nodiscard]] attribute for std::isalpha This comes from libfmt templated code --- cmake/libfmt.cmake | 4 ++-- sql/item_strfunc.cc | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cmake/libfmt.cmake b/cmake/libfmt.cmake index 0eda394a4dc..bdd7d8c0be9 100644 --- a/cmake/libfmt.cmake +++ b/cmake/libfmt.cmake @@ -15,8 +15,8 @@ MACRO(BUNDLE_LIBFMT) ExternalProject_Add( libfmt PREFIX "${dir}" - URL "https://github.com/fmtlib/fmt/releases/download/12.0.0/fmt-12.0.0.zip" - URL_MD5 9bd04e6e8c5b1733e4eefb473604219d + URL "https://github.com/fmtlib/fmt/releases/download/12.1.0/fmt-12.1.0.zip" + URL_MD5 028c6979cad96a4260154f091885171a INSTALL_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 441c5a0105e..e401e3ed9e4 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1622,7 +1622,18 @@ String *Item_func_sformat::val_str(String *res) /* Create the string output */ try { +#ifdef _MSC_VER +/* + C4834 : "discarding return value of function with [[nodiscard]] attribute" + in fmt 12.1 template code, for isalpha() +*/ +#pragma warning(push) +#pragma warning(disable : 4834) +#endif auto text = fmt::vformat(fmt_locale, fmt_arg->c_ptr_safe(), arg_store); +#ifdef _MSC_VER +#pragma warning(pop) +#endif res->length(0); res->set_charset(collation.collation); res->append(text.c_str(), text.size(), fmt_arg->charset()); From df50563513a1c7ea9d10a4af9d6e40ee0b337f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 20 Jan 2026 10:27:56 +0200 Subject: [PATCH 081/152] MDEV-38598 : Galera test failure on MW-86-wait8 Test failure is caused by regression introduced by commit 4de773e90 that changed error code when function does not exists. --- mysql-test/suite/galera/t/MW-86-wait8.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/t/MW-86-wait8.test b/mysql-test/suite/galera/t/MW-86-wait8.test index 1b3f355eb25..33036ca7313 100644 --- a/mysql-test/suite/galera/t/MW-86-wait8.test +++ b/mysql-test/suite/galera/t/MW-86-wait8.test @@ -67,7 +67,7 @@ SHOW DATABASES; --error 0 SHOW ENGINE InnoDB STATUS; ---error ER_LOCK_WAIT_TIMEOUT +--error ER_SP_DOES_NOT_EXIST SHOW FUNCTION CODE f1; --error ER_LOCK_WAIT_TIMEOUT @@ -82,7 +82,7 @@ SHOW INDEX FROM t1; --error ER_LOCK_WAIT_TIMEOUT SHOW OPEN TABLES; ---error ER_LOCK_WAIT_TIMEOUT +--error ER_SP_DOES_NOT_EXIST SHOW PROCEDURE CODE p1; --error ER_LOCK_WAIT_TIMEOUT From 8575b07f1183c12eb6a81c42050c114de86b07d8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 30 Oct 2024 15:49:26 +0100 Subject: [PATCH 082/152] MDEV-35288 Assertion `!is_cond()' failed in virtual longlong Item_bool_func::val_int() Boolean function now uses val_bool to get string result (val_str()) --- mysql-test/main/bool_innodb.result | 10 ++++++++++ mysql-test/main/bool_innodb.test | 15 +++++++++++++++ sql/item_cmpfunc.h | 10 ++++++++++ 3 files changed, 35 insertions(+) create mode 100644 mysql-test/main/bool_innodb.result create mode 100644 mysql-test/main/bool_innodb.test diff --git a/mysql-test/main/bool_innodb.result b/mysql-test/main/bool_innodb.result new file mode 100644 index 00000000000..c08bc52a1b7 --- /dev/null +++ b/mysql-test/main/bool_innodb.result @@ -0,0 +1,10 @@ +# +# MDEV-35288: Assertion `!is_cond()' failed in +# virtual longlong Item_bool_func::val_int() +# +CREATE TABLE t (a INT) ENGINE=INNODB; +SELECT SUM(a), ROWNUM() AS r FROM t HAVING r=1; +SUM(a) r +NULL 1 +DROP TABLE t; +# End of 10.5 tests diff --git a/mysql-test/main/bool_innodb.test b/mysql-test/main/bool_innodb.test new file mode 100644 index 00000000000..744311990cf --- /dev/null +++ b/mysql-test/main/bool_innodb.test @@ -0,0 +1,15 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-35288: Assertion `!is_cond()' failed in +--echo # virtual longlong Item_bool_func::val_int() +--echo # + +CREATE TABLE t (a INT) ENGINE=INNODB; +SELECT SUM(a), ROWNUM() AS r FROM t HAVING r=1; + +# Cleanup +DROP TABLE t; + + +--echo # End of 10.5 tests diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 334aafeae5f..bb6f9009daf 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -248,6 +248,16 @@ public: return val_bool(); } bool val_bool() override= 0; + String *val_str(String *str) override final + { + DBUG_ASSERT(fixed()); + bool res= val_bool(); + if (null_value) + return 0; + + str->set_int(res, false, collation.collation); + return str; + } bool fix_length_and_dec() override { decimals=0; max_length=1; return FALSE; } decimal_digits_t decimal_precision() const override { return 1; } bool need_parentheses_in_default() override { return true; } From e583a7724b3b7086da119bbdb4f14105637f3ed9 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 19 Jan 2026 13:27:02 +0530 Subject: [PATCH 083/152] MDEV-37042 innodb_undo_log_truncate=ON leads to out-of-bounds write During undo tablespace truncation, pages with LSNs older than the tablespace creation LSN may still exist in the buffer pool and get submitted to the doublewrite buffer. When mtr_t::commit_shrink() is invoked shortly after doublewrite batch submission, this can lead to out-of-bounds write errors. Fix: === buf_dblwr_t::flush_buffered_writes_completed() : skip doublewrite processing for pages where the page LSN is older than the tablespace creation LSN. Such pages belong to the old tablespace before truncation and should not be written through the doublewrite buffer. --- storage/innobase/buf/buf0dblwr.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e32b68ed52d..65370512056 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -748,6 +748,15 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) static_cast(frame))); ut_ad(lsn); ut_ad(lsn >= bpage->oldest_modification()); + if (lsn < e.request.node->space->get_create_lsn()) + { + /* mtr_t::commit_shrink() must have been invoked between + buf_dblwr_t::flush_buffered_writes() and + buf_dblwr_t::flush_buffered_writes_completed().*/ + ut_ad(srv_is_undo_tablespace(e.request.node->space->id)); + continue; + } + log_write_up_to(lsn, true); e.request.node->space->io(e.request, bpage->physical_offset(), e_size, frame, bpage); From f0ffc5d4325f98d31a53dc9712dad07f78162833 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 6 Jan 2026 14:20:30 +0400 Subject: [PATCH 084/152] MDEV-37862 - innodb.gap_locks test failure: 0 lock structs, 0 row locks Test was affected by incompletely closed preceding connections. Make test agnostic to concurrent connections by querying InnoDB status only for connections that it uses. This is an addition to 3b2169f0d1e, which didn't handle a case when preceding test has active transaction on disconnect. --- mysql-test/suite/innodb/t/gap_locks.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/gap_locks.test b/mysql-test/suite/innodb/t/gap_locks.test index e0af735ef67..6291e3f2b3d 100644 --- a/mysql-test/suite/innodb/t/gap_locks.test +++ b/mysql-test/suite/innodb/t/gap_locks.test @@ -6,6 +6,8 @@ INSERT INTO t1 VALUES (1,'1',1),(2,'2',1); SET @save_locks= @@GLOBAL.innodb_status_output_locks; SET GLOBAL INNODB_STATUS_OUTPUT_LOCKS = 'ON'; +let $default_id= `select connection_id()`; +let $reg= /.*---TRANSACTION \d+, ACTIVE.*?(\d+ lock struct...), heap size \d+(, \d+ row lock...).*?\nMariaDB thread id $default_id,.*/\1\2/; let $isolation= 4; while ($isolation) { @@ -34,7 +36,7 @@ DELETE FROM t1 WHERE b='2' AND c=2; # not of any inactive ones. Note the use of non-greedy match ".*?", so that # we get the values for the ACTIVE transaction, not the last values in the # list. ---replace_regex /.*---TRANSACTION \d+, ACTIVE.*?(\d+ lock struct...), heap size \d+(, \d+ row lock...).*/\1\2/ +--replace_regex $reg SHOW ENGINE INNODB STATUS; ROLLBACK; From 48d08d6e997e602ed6843eb985635dcfbdce63cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 21 Jan 2026 09:14:24 +0200 Subject: [PATCH 085/152] MDEV-38558 : MariaDB does not support writes during MySQL --> MariaDB migration When MariaDB node has joined to MySQL Galera cluster if any writes to existing tables are done cluster requests to use protocol version 7 (max protocol version used by MySQL Galera cluster). MariaDB had support to protocol version up to 4. While writeset keys are prepared allow using protocol version 7, it has no effect on writeset key format i.e. protocol version 4 and 7 are identical on that case. Note that there is no mtr test case because currently there is no way to test both MySQL and MariaDB in mtr. --- sql/wsrep_mysqld.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 2e671b2af54..abb51aead33 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2008, 2025, Codership Oy - Copyright (c) 2020, 2025, MariaDB + Copyright (c) 2020, 2026, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -121,6 +121,10 @@ my_bool wsrep_restart_slave_activated= 0; // Node has dropped, and slave bool wsrep_new_cluster= false; // Bootstrap the cluster? int wsrep_slave_count_change= 0; // No. of appliers to stop/start int wsrep_to_isolation= 0; // No. of active TO isolation threads +// +// NOTE : MySQL Cluster has max_protocol version 7 +// thus protocol versions 5-7 are reserved for compatibility. +// long wsrep_max_protocol_version= 4; // Maximum protocol version to use long int wsrep_protocol_version= wsrep_max_protocol_version; ulong wsrep_trx_fragment_unit= WSREP_FRAG_BYTES; @@ -1973,6 +1977,10 @@ static bool wsrep_prepare_key_for_isolation(const char* db, case 2: case 3: case 4: + // For MySQL Galera Cluster migration + case 5: + case 6: + case 7: { *key_len= 0; if (db) @@ -1990,7 +1998,6 @@ static bool wsrep_prepare_key_for_isolation(const char* db, break; } default: - assert(0); WSREP_ERROR("Unsupported protocol version: %ld", wsrep_protocol_version); unireg_abort(1); return false; @@ -2153,6 +2160,10 @@ bool wsrep_prepare_key(const uchar* cache_key, size_t cache_key_len, case 2: case 3: case 4: + // For MySQL Galera Cluster migration + case 5: + case 6: + case 7: { key[0].ptr= cache_key; key[0].len= strlen( (char*)cache_key ); @@ -2164,6 +2175,7 @@ bool wsrep_prepare_key(const uchar* cache_key, size_t cache_key_len, break; } default: + WSREP_ERROR("Unsupported protocol version : %ld", wsrep_protocol_version); return false; } From 840ebde8b9a8012a216895e182039b6e2fb05944 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 21 Jan 2026 10:08:45 +0100 Subject: [PATCH 086/152] new CC --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 9e2b0370de0..7a5c80e85e3 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 9e2b0370de0076461ebae71a06acfb7a9364395b +Subproject commit 7a5c80e85e36848a161864bad5e8b2d075492838 From 470487c1a6ef29ab5db911739412754acd25e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 21 Jan 2026 14:16:00 +0200 Subject: [PATCH 087/152] MDEV-21816 Suboptimal implementation of my_convert() my_convert(): Correctly identify unaligned access by invoking memcpy(), which will be translated to a single x86 MOV instruction already by GCC 4.8.5. Also, process the data 64 bits at a time when possible. The use of memcpy() prevents GCC from emitting a SIMD instruction that expects aligned memory (MDEV-37148, MDEV-37786, MDEV-38398) and allows us to enable the fast path across all ISA. Reviewed by: Alexander Barkov Reviewed by: Vladislav Vaintroub --- strings/ctype.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/strings/ctype.c b/strings/ctype.c index 2975f3a2fb9..a0bc1612831 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -1240,21 +1240,28 @@ my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, length= length2= MY_MIN(to_length, from_length); -#if defined(__i386__) || defined(__x86_64__) - /* - Special loop for i386, it allows to refer to a - non-aligned memory block as UINT32, which makes - it possible to copy four bytes at once. This - gives about 10% performance improvement comparing - to byte-by-byte loop. - */ - for ( ; length >= 4; length-= 4, from+= 4, to+= 4) +#if SIZEOF_SIZE_T <= 8 + for (size_t f; length >= sizeof f; + length-= sizeof f, from+= sizeof f, to+= sizeof f) { - if ((*(uint32*)from) & 0x80808080) - break; - *((uint32*) to)= *((const uint32*) from); + memcpy(&f, from, sizeof f); + if (f & (size_t) 0x8080808080808080ULL) + goto nonascii; + memcpy(to, from, sizeof f); } -#endif /* __i386__ */ +# if SIZEOF_SIZE_T > 4 + if (length >= 4) + { + uint32 f; + memcpy(&f, from, 4); + if (f & 0x80808080U) + goto nonascii; + memcpy(to, from, 4); + length-= 4, to+= 4, from+= 4; + } +# endif + nonascii: +#endif for (; ; *to++= *from++, length--) { From 5f6109abe5b4abae035f20cba8ef7094c17e2317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 21 Jan 2026 14:33:31 +0200 Subject: [PATCH 088/152] MDEV-38618 Unused variable dict_table_t::fk_max_recusive_level Ever since mysql/mysql-server@377774689bf6a16af74182753fe950d514c2c6dd was applied in commit 2e814d4702d71a04388386a9f591d14a35980bfed the data member dict_table_t::fk_max_recusive_level is never being read, only initialized as 0. Let us follow the lead of mysql/mysql-server@b22ac19f104c3b3654601b387c37ee82af180d7a and remove this useless field. --- storage/innobase/dict/dict0load.cc | 9 +-------- storage/innobase/include/dict0mem.h | 5 ----- storage/innobase/row/row0mysql.cc | 2 -- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 0071e7e8afe..cfdc55932cc 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -2506,10 +2506,6 @@ corrupted: } } - /* Initialize table foreign_child value. Its value could be - changed when dict_load_foreigns() is called below */ - table->fk_max_recusive_level = 0; - /* We will load the foreign key information only if all indexes were loaded. */ if (!table->is_readable()) { @@ -2528,7 +2524,6 @@ corrupted: goto evict; } else { dict_mem_table_fill_foreign_vcol_set(table); - table->fk_max_recusive_level = 0; } } @@ -3222,9 +3217,7 @@ load_next_index: mtr.commit(); if ((sec_index = dict_table_get_next_index(sec_index))) { - /* Switch to scan index on REF_NAME, fk_max_recusive_level - already been updated when scanning FOR_NAME index, no need to - update again */ + /* Switch to scan index on REF_NAME */ check_recursive = false; goto start_load; } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 3b1ae66d861..0ab4e4d1fda 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2320,11 +2320,6 @@ public: /** Node of the LRU list of tables. */ UT_LIST_NODE_T(dict_table_t) table_LRU; - /** Maximum recursive level we support when loading tables chained - together with FK constraints. If exceeds this level, we will stop - loading child table into memory along with its parent table. */ - byte fk_max_recusive_level; - /** DDL transaction that last touched the table definition, or 0 if no history is available. This includes possible changes in ha_innobase::prepare_inplace_alter_table() and diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 1db5ec04ff1..8302fcf5827 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1560,8 +1560,6 @@ init_fts_doc_id_for_ref( dict_table_t* table, /*!< in: table */ ulint* depth) /*!< in: recusive call depth */ { - table->fk_max_recusive_level = 0; - /* Limit on tables involved in cascading delete/update */ if (++*depth > FK_MAX_CASCADE_DEL) { return; From b17a182d7e17bac559cb5cc0caff3718112ba1fc Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 21 Jan 2026 10:15:41 +0100 Subject: [PATCH 089/152] New CC 3.4 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 46880b00365..47171e34c7a 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 46880b003653a000e9588bd73c8b1dd65088c686 +Subproject commit 47171e34c7acec6d7ccf92c44bdcf06483a7c2b2 From 7ae02de3a55ed8f0455b253ab17bc978ada050d3 Mon Sep 17 00:00:00 2001 From: KhaledR57 Date: Fri, 13 Jun 2025 17:39:40 +0300 Subject: [PATCH 090/152] MDEV-36107 MDEV-36108 Enhance mysqltest language with expression evaluation and variable substitutions mysqltest had limited scripting capabilities, requiring complex workarounds for mathematical calculations and string manipulations in test cases. This commit solves these limitations by adding a new `$(...)` syntax that enables direct evaluation of mathematical, logical, and string expressions within test scripts. Expression Evaluation (MDEV-36107): - Recursive descent parser supporting arithmetic, logical, comparison, and bitwise operators with proper precedence - Support for integers (decimal, hex, binary), booleans, strings, and NULL values - Variable substitution within expressions - Integration with existing mysqltest control flow String Functions (MDEV-36108): - Base conversion functions supporting bases 2-62 - String manipulation and processing functions - Regular expression functions - Conditional and numeric utility functions The implementation enhances mysqltest's scripting capabilities while maintaining full backward compatibility. --- client/mysqltest.cc | 2825 +++++++++++++++++ .../mysqltest_expression_evaluation.result | 508 +++ .../main/mysqltest_expression_evaluation.test | 897 ++++++ .../main/mysqltest_string_functions.result | 1095 +++++++ .../main/mysqltest_string_functions.test | 2056 ++++++++++++ 5 files changed, 7381 insertions(+) create mode 100644 mysql-test/main/mysqltest_expression_evaluation.result create mode 100644 mysql-test/main/mysqltest_expression_evaluation.test create mode 100644 mysql-test/main/mysqltest_string_functions.result create mode 100644 mysql-test/main/mysqltest_string_functions.test diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 110f7167ac8..ba9ed6ec9b2 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -688,6 +688,320 @@ void display_optimizer_trace(struct st_connection *con, DYNAMIC_STRING *ds); + +/* + ======================================================================== + EXPRESSION PARSER AND EVALUATOR FOR MYSQLTEST + ======================================================================== + + DESCRIPTION + This module implements a complete recursive descent parser for mathematical + and logical expressions used in mysqltest scripts. The parser supports: + + OPERATOR PRECEDENCE (from highest to lowest): + - Primary expressions (parentheses, literals, functions) + - Unary operators (!, -, ~) + - Bitwise XOR (^) + - Multiplication/Division (*, /, %) + - Arithmetic (+, -) + - Bitwise Shift (<<, >>) + - Bitwise AND (&) + - Bitwise OR (|) + - Comparison (<, <=, >, >=) + - Equality (==, !=) + - Logical AND (&&) + - Logical OR (||) + + SUPPORTED DATA TYPES: + - Integers (decimal, hexadecimal (0x), binary (0b)) + - Booleans + - Strings + - NULL values + + BUILT-IN FUNCTIONS: + String functions: substr/substring, locate, length, hex, oct, bin, + ltrim, rtrim, trim, upper/ucase, lower/lcase, + reverse, replace, concat, concat_ws, repeat, + insert, instr, lpad, rpad, substring_index + Regex functions: regexp_instr, regexp_replace, regexp_substr + Numeric functions: abs, conv + Comparison functions: greatest, least + Conditional: ifnull, nullif, coalesce + + SYNTAX: + Expressions are enclosed in $() and can contain: + - Variables: $var_name + - Literals: numbers, strings, booleans, null + - Operators: all standard mathematical and logical operators + - Functions: built-in function calls with arguments + - Parentheses for grouping + + EXAMPLES: + $(1 + 2 * 3) # Arithmetic + $($var1 > $var2) # Comparison + $(substr("hello", 1, 3)) # Function call + $($flag && ($count > 0)) # Logical operations + $(1 << 2 | 3) # Bitwise operations + + let $x = $(10 + 2); + echo $(1 + 2); + if ($($x > 10)) + { + echo "x is greater than 10"; + } + while ($($x < 20)) + { + echo $($x); + let $x = $($x + 1); + } + + ENTRY POINT: + Main parsing starts with expr() function which is called from do_eval(). + + ERROR HANDLING: + Parser dies with descriptive error messages on syntax errors or + type mismatches. All errors are fatal to ensure test reliability. +*/ + +typedef String My_string; + +enum Expression_value_type +{ + EXPR_INT, + EXPR_STRING, + EXPR_NULL +}; + + +/* + Expression value container for mysqltest expression parser + This structure holds the result of parsed expressions and provides + type conversion methods. It supports multiple data types with + the ability to convert between them. +*/ + +struct Expression_value +{ + Expression_value_type type; + unsigned long long int_val; + bool is_numeric; + bool is_unsigned; + My_string str_val; + + + Expression_value() + { + type= EXPR_NULL; + is_numeric= false; + is_unsigned= false; + } + + + void set_int(long long value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= false; + int_val= value; + } + + + void set_uint(unsigned long long value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= true; + int_val= value; + } + + + void set_string(const char *value, size_t len) + { + type= EXPR_STRING; + is_numeric= false; + str_val.copy(value, len, charset_info); + } + + + void set_bool(bool value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= false; + int_val= value ? 1 : 0; + } + + + long long to_int() const + { + if (is_numeric) + return (long long)int_val; + errno= 0; + long long val= strtoll(str_val.ptr(), NULL, 10); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)str_val.length(), str_val.ptr()); + return val; + } + + + unsigned long long to_uint() const + { + if (is_numeric) + return int_val; + errno= 0; + unsigned long long val= strtoull(str_val.ptr(), NULL, 10); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)str_val.length(), str_val.ptr()); + return val; + } + + + bool to_bool() const + { + return (bool)to_int(); + } + + + My_string to_string() const + { + My_string buffer; + + if (type == EXPR_NULL) + { + buffer.set("", 0, charset_info); + return buffer; + } + + if (is_numeric) + { + buffer.set_int(int_val, is_unsigned, charset_info); + return buffer; + } + + if (type == EXPR_STRING) + { + buffer.copy(str_val); + return buffer; + } + + buffer.set("", 0, charset_info); + return buffer; + } + + + Expression_value& operator=(const Expression_value& other) + { + if (this != &other) + { + type= other.type; + int_val= other.int_val; + is_numeric= other.is_numeric; + is_unsigned= other.is_unsigned; + if (other.type == EXPR_STRING) + { + str_val.copy(other.str_val); + } + } + return *this; + } + + + void reset() + { + // My_string memory is kept allocated for reuse + type= EXPR_NULL; + is_numeric= false; + is_unsigned= false; + } + + +/** + Parses a token string and initializes the Expression_value with the + appropriate type and value. + + Type selection logic: + - Hex/binary numbers, or values > LLONG_MAX → unsigned integer + - Decimal numbers ≤ LLONG_MAX → signed integer + - Boolean literals → boolean type + - "null" → null type + - Everything else → string type +*/ + + void init(const char* token_start, size_t token_len) + { + char *endptr; + unsigned long long parsed_int; + int base= 10; + + // Check for boolean literals (case insensitive) + if (token_len == 4 && strncasecmp(token_start, "true", 4) == 0) + { + set_bool(true); + return; + } + + if (token_len == 5 && strncasecmp(token_start, "false", 5) == 0) + { + set_bool(false); + return; + } + + if(token_len == 4 && strncasecmp(token_start, "null", 4) == 0) + { + reset(); + return; + } + + // Check for special prefixes (0x, 0b) + if (token_len >= 3 && token_start[0] == '0') + { + if (token_start[1] == 'x') + { + base= 16; + } + else if (token_start[1] == 'b') + { + base= 2; + token_start+= 2; // Skip "0b" prefix for strtol + token_len-= 2; + } + } + + errno= 0; + parsed_int= strtoull(token_start, &endptr, base); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)token_len, token_start); + + // If the entire token was parsed as an integer, set the type to integer + if (endptr == token_start + token_len) + { + if (base == 16 || base == 2 || parsed_int > LLONG_MAX) + set_uint(parsed_int); + else + set_int((long long)parsed_int); + return; + } + + set_string(token_start, token_len); + } +}; + + +/* Core expression parsing functions */ +static void expr(Expression_value *result, const char **s); +static void logical_or(Expression_value *result, const char **s); +static void logical_and(Expression_value *result, const char **s); +static void equality(Expression_value *result, const char **s); +static void comparison(Expression_value *result, const char **s); +static void term(Expression_value *result, const char **s); +static void factor(Expression_value *result, const char **s); +static void unary(Expression_value *result, const char **s); +static void primary(Expression_value *result, const char **s); + + class LogFile { FILE* m_file; char m_file_name[FN_REFLEN]; @@ -1163,6 +1477,60 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, escaped= 0; dynstr_append_mem(query_eval, p, 1); } + else if (p < query_end && *(p + 1) == '(') + { + const char* expr_start= p + 2; + int paren_level= 1; + const char* expr_end= expr_start; + char in_quote= 0; + bool escaped= false; + + // Find the matching closing parenthesis + while (*expr_end && paren_level > 0) + { + if (!in_quote) + { + // Not inside quotes - handle parentheses normally + if (*expr_end == '(') paren_level++; + else if (*expr_end == ')') paren_level--; + else if (*expr_end == '\'' || *expr_end == '"') + in_quote= *expr_end; // Start of quoted string + } + else + { + // Inside quotes - only look for closing quote + if (!escaped && *expr_end == in_quote) + in_quote= 0; // End of quoted string + } + escaped= (!escaped && *expr_end == '\\'); + expr_end++; + } + + if (paren_level != 0) + die("Unmatched parenthesis in expression starting at '%.*s'", 10, p); + expr_end--; // Go back to the ')' + + // Recursively evaluate the content of the expression + DYNAMIC_STRING sub_expr_eval; + init_dynamic_string(&sub_expr_eval, "", 256, 1024); + do_eval(&sub_expr_eval, expr_start, expr_end, FALSE); + + const char* eval_ptr= sub_expr_eval.str; + Expression_value result_val; + expr(&result_val, &eval_ptr); + + while(*eval_ptr && my_isspace(charset_info, *eval_ptr)) + eval_ptr++; + + if (*eval_ptr != '\0') + die("Syntax error in sub-expression '%.*s'", (int)sub_expr_eval.length, sub_expr_eval.str); + + My_string result_buf= result_val.to_string(); + dynstr_append_mem(query_eval, result_buf.c_ptr(), result_buf.length()); + + dynstr_free(&sub_expr_eval); + p= expr_end; + } else { if (!(v= var_get(p, &p, 0, 0))) @@ -4921,6 +5289,2385 @@ int do_save_master_pos() } +/* Built-in functions available in expressions */ +enum func_type +{ + // Numeric functions + FUNC_ABS, + FUNC_BIN, + FUNC_CONV, + FUNC_HEX, + FUNC_OCT, + // String functions + FUNC_CONCAT, + FUNC_CONCAT_WS, + FUNC_GREATEST, + FUNC_INSERT, + FUNC_INSTR, + FUNC_LPAD, + FUNC_LEAST, + FUNC_LENGTH, + FUNC_LOCATE, + FUNC_LOWER, + FUNC_LTRIM, + FUNC_REPEAT, + FUNC_REPLACE, + FUNC_REVERSE, + FUNC_RPAD, + FUNC_RTRIM, + FUNC_SUBSTR, + FUNC_SUBSTR_IDX, + FUNC_TRIM, + FUNC_UPPER, + // Regexp functions + FUNC_REGEXP_INSTR, + FUNC_REGEXP_REPLACE, + FUNC_REGEXP_SUBSTR, + // Null functions + FUNC_COALESCE, + FUNC_IFNULL, + FUNC_NULLIF, + + FUNC_UNKNOWN +}; + + +enum func_type get_expr_function_type(const char *name, size_t len); +void handle_expr_function_call(enum func_type func_type, + Expression_value *result, const char **s); + + +static int match(const char **s, const char *op) +{ + while (my_isspace(charset_info, **s)) (*s)++; + size_t len= strlen(op); + if (strncmp(*s, op, len) == 0) + { + // check for ambiguous operators (e.g., distinguish | from ||) + if (len == 1 && strchr("&|", **s)) + { + char next_char= *(*s + 1); + if (next_char == op[0]) + return 0; // don't match single & or | when && or || follows + } + *s += len; + return 1; + } + return 0; +} + + +/** + @brief Check if character is an operator + @param[in] c Character to check + + @details + Used to separate tokens during parsing of unquoted string literals. + Operator characters: ! * % / + - < > = & | ^ ~ ( ) , + + @return + TRUE if character is an operator + FALSE otherwise +*/ + +static bool is_operator_char(char c) +{ + return strchr("!*%/+-<>=&|^~(),", c) != NULL; +} + + +/** + @brief Compare two Expression_value operands numerically + @param[in] left Left operand + @param[in] right Right operand + + @details + Compares two numeric Expression_value objects handling signed vs unsigned + comparison correctly. Handles the edge cases where comparing signed negative + values with unsigned values. + + @return + -1 left < right + 0 left == right + 1 left > right + -2 left or right is null +*/ + +static int cmp_numeric(const Expression_value &left, const Expression_value &right) +{ + // Handle null values first + if (left.type == EXPR_NULL || right.type == EXPR_NULL) + return -2; + + if (!left.is_numeric || !right.is_numeric) + die("Evaluation error: cmp_numeric called with non-numeric operands"); + + // Both unsigned + if (left.is_unsigned && right.is_unsigned) + return (left.to_uint() > right.to_uint()) - (left.to_uint() < right.to_uint()); + + // Both signed + if (!left.is_unsigned && !right.is_unsigned) + return (left.to_int() > right.to_int()) - (left.to_int() < right.to_int()); + + // Mixed signed/unsigned + if (left.is_unsigned) + { + // left is unsigned, right is signed + long long right_val= right.to_int(); + if (right_val < 0) + return 1; // unsigned > negative + else + { + unsigned long long left_val= left.to_uint(); + unsigned long long right_unsigned= (unsigned long long)right_val; + return (left_val > right_unsigned) - (left_val < right_unsigned); + } + } + else + { + // left is signed, right is unsigned + long long left_val= left.to_int(); + if (left_val < 0) + return -1; // negative < unsigned + else + { + unsigned long long left_unsigned= (unsigned long long)left_val; + unsigned long long right_val= right.to_uint(); + return (left_unsigned > right_val) - (left_unsigned < right_val); + } + } +} + + +/** + @brief Parse primary expressions (literals, functions) + @param[out] result Expression_value to store result + @param[in] s Pointer to string pointer containing the expression to parse + + @details + Handles the lowest level of expression parsing: + - String literals: 'text' or "text" + - Function calls: func_name(args...) + - Numeric literals: integers in decimal/hex/binary format + - Boolean literals: true/false (case-insensitive) + - Null literal: null (case-insensitive) + - Unquoted string tokens (treated as strings) as long as they are not operators, + literals, or function calls. + + For function calls, validates function name against function_table[] + and delegates to handle_expr_function_call(). + + @note Dies on syntax errors or unknown functions +*/ + +static void primary(Expression_value *result, const char **s) +{ + while (my_isspace(charset_info, **s)) (*s)++; + + if (match(s, "(")) + { + expr(result, s); + if (!match(s, ")")) + die("Syntax error: Expected ')' in expression"); + return; + } + + const char *start= *s; + const char *end= start; + char quote_char= 0; + + // check if this is a quoted string literal + if (*start == '\'' || *start == '"') + { + quote_char= *start; + start++; + end= start; + while (*end) + { + if (*end == '\\' && *(end + 1)) + end++; + else if (*end == quote_char) + break; + end++; + } + + if (*end != quote_char) + die("Syntax error: Unmatched quote in expression"); + + result->set_string(start, end - start); + *s= end + 1; + return; + } + + /* + function name is a sequence of alphanumeric characters or underscores + followed by a '(' + */ + while (*end && (my_isalnum(charset_info, *end) || *end == '_')) + end++; + + if (*end == '(') + { + enum func_type func_type= get_expr_function_type(start, + end - start); + if (func_type == FUNC_UNKNOWN) + die("Syntax error: Unknown function"); + + *s= end + 1; // skip '(' + handle_expr_function_call(func_type, result, s); + } + else + { + // treat unquoted string literals as strings + end= start; + while (*end && !is_operator_char(*end)) + end++; + + while (start < end && my_isspace(charset_info, *(end - 1))) + end--; + + if (end == start) + die("Syntax error: invalid expression"); + + result->init(start, end - start); + *s= end; + } +} + + +static void unary(Expression_value *result, const char **s) +{ + if (match(s, "!")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: logical NOT requires an integer operand"); + result->set_bool(!result->to_int()); + return; + } + if (match(s, "-")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: unary minus requires an integer operand"); + result->set_int(-result->to_int()); + return; + } + if (match(s, "~")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: bitwise NOT requires an integer operand"); + result->set_uint(~result->to_uint()); + return; + } + primary(result, s); +} + + +static void bitwise_xor(Expression_value *result, const char **s) +{ + Expression_value rhs; + + unary(result, s); + while (true) + { + if (match(s, "^")) + { + rhs.reset(); + unary(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '^' requires integer operands"); + result->set_uint(result->to_uint() ^ rhs.to_uint()); + } + else + break; + } +} + + +static void factor(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_xor(result, s); + while (true) + { + if (match(s, "*")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '*' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() * rhs.to_uint()); + else + result->set_int(result->to_int() * rhs.to_int()); + } + else if (match(s, "/")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '/' requires integer operands"); + if (rhs.to_int() == 0) + die("Evaluation error: Division by zero"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() / rhs.to_uint()); + else + { + long long nominator= result->to_int(); + long long denominator= rhs.to_int(); + // Prevent fatal integer overflow from LLONG_MIN / -1, which causes a crash + if (nominator == LLONG_MIN && denominator == -1) + result->set_int(nominator); + else + result->set_int(nominator / denominator); + } + } + else if (match(s, "%")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '%%' requires integer operands"); + if (rhs.to_int() == 0) + die("Evaluation error: Modulo by zero"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() % rhs.to_uint()); + else + { + long long nominator= result->to_int(); + long long denominator= rhs.to_int(); + // Prevent fatal integer overflow from LLONG_MIN % -1, which causes a crash + if (nominator == LLONG_MIN && denominator == -1) + result->set_int(0); + else + result->set_int(nominator % denominator); + } + } + else + break; + } +} + + +static void term(Expression_value *result, const char **s) +{ + Expression_value rhs; + + factor(result, s); + while (true) + { + if (match(s, "+")) + { + rhs.reset(); + factor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '+' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() + rhs.to_uint()); + else + result->set_int(result->to_int() + rhs.to_int()); + } + else if (match(s, "-")) + { + rhs.reset(); + factor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '-' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() - rhs.to_uint()); + else + result->set_int(result->to_int() - rhs.to_int()); + } + else + break; + } +} + + +static void bitwise_shift(Expression_value *result, const char **s) +{ + Expression_value rhs; + + term(result, s); + while (true) + { + if (match(s, "<<")) + { + rhs.reset(); + term(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<<' requires integer operands"); + if (rhs.to_int() < 0 || rhs.to_int() >= 64) + die("Evaluation error: Invalid shift amount"); + result->set_uint(result->to_uint() << rhs.to_int()); + } + else if (match(s, ">>")) + { + rhs.reset(); + term(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>>' requires integer operands"); + if (rhs.to_int() < 0 || rhs.to_int() >= 64) + die("Evaluation error: Invalid shift amount"); + result->set_uint(result->to_uint() >> rhs.to_int()); + } + else + break; + } +} + + +static void bitwise_and(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_shift(result, s); + while (true) + { + if (match(s, "&") && !match(s, "&&")) + { + rhs.reset(); + bitwise_shift(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '&' requires integer operands"); + result->set_uint(result->to_uint() & rhs.to_uint()); + } + else + break; + } +} + + +static void bitwise_or(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_and(result, s); + while (true) + { + if (match(s, "|") && !match(s, "||")) + { + rhs.reset(); + bitwise_and(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '|' requires integer operands"); + result->set_uint(result->to_uint() | rhs.to_uint()); + } + else + break; + } +} + + +static void comparison(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_or(result, s); + while (true) + { + if (match(s, "<=")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<=' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) <= 0); + } + else if (match(s, ">=")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>=' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) >= 0); + } + else if (match(s, "<")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) < 0); + } + else if (match(s, ">")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) > 0); + } + else + break; + } +} + + +static void equality(Expression_value *result, const char **s) +{ + Expression_value rhs; + + comparison(result, s); + while (true) + { + if (match(s, "==")) + { + rhs.reset(); + comparison(&rhs, s); + + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + { + result->reset(); + } + else if (result->is_numeric && rhs.is_numeric) + { + result->set_bool(cmp_numeric(*result, rhs) == 0); + } + else if (result->type == EXPR_STRING && rhs.type == EXPR_STRING) + { + result->set_bool(!strcmp(result->str_val.c_ptr(), rhs.str_val.c_ptr())); + } + else + { + result->set_bool(false); // different types are not equal + } + } + else if (match(s, "!=")) + { + rhs.reset(); + comparison(&rhs, s); + + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + { + result->reset(); + } + else if (result->is_numeric && rhs.is_numeric) + { + result->set_bool(cmp_numeric(*result, rhs) != 0); + } + else if (result->type == EXPR_STRING && rhs.type == EXPR_STRING) + { + result->set_bool(strcmp(result->str_val.c_ptr(), rhs.str_val.c_ptr()) != 0); + } + else + { + result->set_bool(true); // different types are not equal + } + } + else + break; + } +} + + +static void logical_and(Expression_value *result, const char **s) +{ + Expression_value rhs; + + equality(result, s); + while (match(s, "&&")) + { + rhs.reset(); + equality(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '&&' requires integer operands"); + result->set_bool(result->to_int() && rhs.to_int()); + } +} + + +static void logical_or(Expression_value *result, const char **s) +{ + Expression_value rhs; + + logical_and(result, s); + while (match(s, "||")) + { + rhs.reset(); + logical_and(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '||' requires integer operands"); + result->set_bool(result->to_int() || rhs.to_int()); + } +} + + +/** + @brief Parse and evaluate a mathematical/logical expression + @param[out] result Pointer to Expression_value structure to store the result + @param[in] s Pointer to string pointer containing the expression to parse + + @details + This is the main entry point for the recursive descent expression parser. + It parses expressions with the following grammar hierarchy (by precedence): + + expr -> logical_or + logical_or -> logical_and (||) + logical_and -> equality (&&) + equality -> comparison (==, !=) + comparison -> bitwise_or (<, >, <=, >=) + bitwise_or -> bitwise_and (|) + bitwise_and -> bitwise_shift (&) + bitwise_shift -> term (<<, >>) + term -> factor (+, -) + factor -> bitwise_xor (*, /, %) + bitwise_xor -> unary (^) + unary -> primary (!, -, ~) + primary -> literals, functions, parentheses + + Supported data types: + - INTEGERS: signed/unsigned integers (decimal, hex 0x, binary 0b) + - BOOLEAN: boolean values (true, false) + - STRINGS: quoted or unquoted string literals + - NULL: null values + + The parser advances the string pointer *s as it consumes tokens. + + @note + The parser does not handle overflow/underflow of large numbers after + the initial parsing. It is the responsibility of the caller to ensure that + the result of the operations is within the range of the data type (2^64-1). + + @note Dies with error message if syntax error or type mismatch detected +*/ + +static void expr(Expression_value *result, const char **s) +{ + logical_or(result, s); +} + + +/* Expression function handling */ +#define MAX_FUNC_ARGS 100 + +static struct { + const char *name; + enum func_type type; +} function_table[]= { + // Numeric functions + {"abs", FUNC_ABS}, + {"bin", FUNC_BIN}, + {"conv", FUNC_CONV}, + {"hex", FUNC_HEX}, + {"oct", FUNC_OCT}, + // String functions + {"concat", FUNC_CONCAT}, + {"concat_ws", FUNC_CONCAT_WS}, + {"greatest", FUNC_GREATEST}, + {"insert", FUNC_INSERT}, + {"instr", FUNC_INSTR}, + {"lcase", FUNC_LOWER}, + {"least", FUNC_LEAST}, + {"length", FUNC_LENGTH}, + {"locate", FUNC_LOCATE}, + {"lower", FUNC_LOWER}, + {"lpad", FUNC_LPAD}, + {"ltrim", FUNC_LTRIM}, + {"repeat", FUNC_REPEAT}, + {"replace", FUNC_REPLACE}, + {"reverse", FUNC_REVERSE}, + {"rpad", FUNC_RPAD}, + {"rtrim", FUNC_RTRIM}, + {"substr", FUNC_SUBSTR}, + {"substring", FUNC_SUBSTR}, + {"substring_index", FUNC_SUBSTR_IDX}, + {"trim", FUNC_TRIM}, + {"ucase", FUNC_UPPER}, + {"upper", FUNC_UPPER}, + // Regexp functions + {"regexp_instr", FUNC_REGEXP_INSTR}, + {"regexp_replace", FUNC_REGEXP_REPLACE}, + {"regexp_substr", FUNC_REGEXP_SUBSTR}, + // Null functions + {"coalesce", FUNC_COALESCE}, + {"ifnull", FUNC_IFNULL}, + {"nullif", FUNC_NULLIF}, + {NULL, FUNC_UNKNOWN} +}; + + +static void convert_base_helper(const My_string &str, int from_base, int to_base, + Expression_value *value) +{ + char temp_buffer[66]; // should be enough for any base + long long result; + char *endptr; + int err; + size_t str_len= str.length(); + + if (from_base < 0) // Negative base = treat input as SIGNED + result= my_strntoll_8bit(charset_info, str.ptr(), str_len, -from_base, + &endptr, &err); + else // Positive base = treat input as UNSIGNED + result= (long long) my_strntoull_8bit(charset_info, str.ptr(), str_len, + from_base, &endptr, &err); + + if (err == ERANGE) + die("Range error: value out of range for Integer type"); + + if (err != 0 || endptr != str.ptr() + str_len) + die("invalid number '%.*s' for base %d", (int)str_len, str.ptr(), from_base); + + endptr= longlong2str(result, temp_buffer, to_base); + if (!endptr) + die("could not convert number '%.*s' for base %d", + (int)str_len, str.ptr(), to_base); + + value->set_string(temp_buffer, endptr - temp_buffer); +} + + +/** + @brief Compare two decimal strings numerically + @param[in] a First decimal string + @param[in] b Second decimal string + + @details + Compares two decimal number strings treating them as numeric values. + Handles leading/trailing whitespace, signs, and leading zeros properly. + + @return + -1 a < b + 0 a == b + 1 a > b +*/ + +static int cmp_decimal(const My_string &a, const My_string &b) +{ + const char *a_ptr= a.ptr(); + const char *b_ptr= b.ptr(); + size_t a_len= a.length(); + size_t b_len= b.length(); + + // Skip leading whitespace + while (a_len > 0 && isspace(*a_ptr)) + a_ptr++, a_len--; + while (b_len > 0 && isspace(*b_ptr)) + b_ptr++, b_len--; + + // Handle empty strings (treat as 0) + if (a_len == 0 && b_len == 0) return 0; + if (a_len == 0) return b_ptr[0] == '-' ? 1 : -1; + if (b_len == 0) return a_ptr[0] == '-' ? -1 : 1; + + // Extract signs + bool a_negative= false, b_negative= false; + if (*a_ptr == '-') a_negative= true, a_ptr++, a_len--; + else if (*a_ptr == '+') a_ptr++, a_len--; + + if (*b_ptr == '-') b_negative= true, b_ptr++, b_len--; + else if (*b_ptr == '+') b_ptr++, b_len--; + + // Skip leading zeros + while (a_len > 0 && *a_ptr == '0') a_ptr++, a_len--; + while (b_len > 0 && *b_ptr == '0') b_ptr++, b_len--; + + // Find actual numeric length (digits only) + size_t a_digits= 0, b_digits= 0; + for (size_t i= 0; i < a_len && isdigit(a_ptr[i]); i++) a_digits++; + for (size_t i= 0; i < b_len && isdigit(b_ptr[i]); i++) b_digits++; + + // Handle zero cases after removing leading zeros + bool a_is_zero= (a_digits == 0); + bool b_is_zero= (b_digits == 0); + + if (a_is_zero && b_is_zero) return 0; + if (a_is_zero) return b_negative ? 1 : -1; + if (b_is_zero) return a_negative ? -1 : 1; + + // Different signs: negative < positive + if (a_negative && !b_negative) return -1; + if (!a_negative && b_negative) return 1; + + // Same sign: compare absolute values + int abs_cmp= 0; + + // First compare by number of digits + if (a_digits != b_digits) + { + abs_cmp= (a_digits > b_digits) ? 1 : -1; + } + else + { + // Same number of digits: compare digit by digit + for (size_t i= 0; i < a_digits; i++) + { + if (a_ptr[i] != b_ptr[i]) + { + abs_cmp= (a_ptr[i] > b_ptr[i]) ? 1 : -1; + break; + } + } + } + + // If both negative, reverse the comparison result + return a_negative ? -abs_cmp : abs_cmp; +} + + +/* Expression Built-in Function Implementations */ + + +/** + @brief Absolute value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + ABS(X) returns the absolute (positive) value of X. + + @note Dies if argument count != 1 or argument is not numeric +*/ + +void func_abs(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("abs() expects 1 argument, got %d", count); + + if (!args[0].is_numeric) + die("abs() requires numeric argument"); + + result->set_int(abs(args[0].to_int())); +} + + +/** + @brief Base conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts numbers between different bases. + CONV(N, from_base, to_base) converts number N from base from_base to base to_base. + Bases can be from 2 to 62. Negative bases treat input as signed. + + @note Dies if argument count != 3, bases not numeric, or bases out of range +*/ + +void func_conv(Expression_value args[], int count, Expression_value *result) +{ + int from_base; + int to_base; + + if (count != 3) + die("conv() expects 3 arguments (N, from_base, to_base), got %d", count); + + from_base= (int)args[1].to_int(); + to_base= (int)args[2].to_int(); + + if (!args[1].is_numeric || !args[2].is_numeric) + die("conv() bases must be numeric"); + + if (abs(from_base) < 2 || abs(from_base) > 62) + die("conv() from_base must be between 2 and 62, got %d", from_base); + if (abs(to_base) < 2 || abs(to_base) > 62) + die("conv() to_base must be between 2 and 62, got %d", to_base); + + convert_base_helper(args[0].to_string(), from_base, to_base, result); +} + + +/** + @brief Binary conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to binary representation. + BIN(N) returns a string representation of the binary value of N. + This is equivalent to CONV(N, 10, 2). + + @note Dies if argument count != 1 +*/ + +void func_bin(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("bin() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 2, result); +} + + +/** + @brief Octal conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to octal representation. + OCT(N) returns a string representation of the octal value of N. + This is equivalent to CONV(N, 10, 8). + + @note Dies if argument count != 1 +*/ + +void func_oct(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("oct() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 8, result); +} + + +/** + @brief Hexadecimal conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to hexadecimal representation. + HEX(N) returns a string representation of the hexadecimal value of N. + This is equivalent to CONV(N, 10, 16). + + @note Dies if argument count != 1 +*/ + +void func_hex(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("hex() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 16, result); +} + + +/** + @brief String search function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + INSTR(str, substr) returns position of first occurrence of substr in str. + Returns 0 if not found. Positions start at 1. Performs a case-insensitive + search. + + @note Dies if less than 2 arguments +*/ + +void func_instr(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("instr() expects 2 arguments (str, substr), got %d", count); + + my_match_t match; + My_string str= args[0].to_string(); + My_string substr= args[1].to_string(); + + if (charset_info->coll->instr(charset_info, str.ptr(), str.length(), + substr.ptr(), substr.length(), &match, 1)) + result->set_int(match.mb_len + 1); + else + result->set_int(0); +} + + +/** + @brief Locate substring function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LOCATE(substr, str [, start]) returns position of substr in str starting from + start (default 1). Returns 0 if substr is not in str. Positions start at 1. + Performs a case-insensitive search. + + @note Dies if wrong argument count or non-numeric start position +*/ + +void func_locate(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2 || count > 3) + die("locate() expects 2 or 3 arguments (substr, str [, start]), got %d", count); + + if (count == 3 && !args[2].is_numeric) + die("locate() start position must be numeric"); + + My_string substr= args[0].to_string(); + My_string str= args[1].to_string(); + + long long start= 0; + long long start0= 0; + my_match_t match; + + if (count == 3) + { + start0= start= args[2].to_int() - 1; + + if (start < 0 || start > (longlong)str.length()) + { + result->set_int(0); + return; + } + + start= str.charpos((int) start); + + // Substring is longer than str at start position. + if (start + substr.length() > str.length()) + { + result->set_int(0); + return; + } + } + + if (!substr.length()) + { + result->set_int(start + 1); + return; + } + + if (charset_info->coll->instr(charset_info, str.ptr() + start, + (uint)(str.length() - start), + substr.ptr(), substr.length(), &match, 1)) + result->set_int((longlong)match.mb_len + start0 + 1); + else + result->set_int(0); +} + + +/** + @brief String replacement function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REPLACE(str, from_str, to_str) replaces all occurrences of from_str with + to_str. Performs a case-sensitive match when searching for from_str. + + @note Dies if argument count != 3 or arguments are numeric +*/ + +void func_replace(Expression_value args[], int count, Expression_value *result) +{ + if (count != 3) + die("replace() expects 3 arguments (str, from, to), got %d", count); + + if (args[0].is_numeric || args[1].is_numeric || args[2].is_numeric) + die("replace() arguments must be strings"); + + My_string str= args[0].to_string(); + My_string from_str= args[1].to_string(); + My_string to_str= args[2].to_string(); + + if (from_str.length() == 0) + { + result->set_string(str.ptr(), str.length()); + return; + } + + My_string result_str; + result_str.copy(str); + + int pos= 0; + while ((pos= result_str.strstr(from_str, pos)) >= 0) + { + result_str.replace(pos, from_str.length(), to_str.ptr(), to_str.length()); + pos += to_str.length(); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Substring extraction function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + SUBSTR(str, pos [, len]) returns substring starting at position pos. + Positions start at 1. Negative positions count from end. + + @note Dies if wrong argument count or non-numeric position/length +*/ + +void func_substr(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2 || count > 3) + die("substr() expects 2 or 3 arguments (str, start [, length]), got %d", count); + + if (args[0].is_numeric) + die("substr() first argument must be a string"); + + if (!args[1].is_numeric) + die("substr() start position must be numeric"); + + if (count == 3 && !args[2].is_numeric) + die("substr() length must be numeric"); + + My_string str= args[0].to_string(); + int start= (int)args[1].to_int(); + int length= count == 3 ? (int)args[2].to_int() : str.length(); + + if (start == 0 || start > (int)str.length() || length <= 0) + { + result->set_string("", 0); + return; + } + + if (start < 0) + start= str.length() + start; + else + start--; + + int end= str.length(); + if (count == 3) + { + end= start + length; + if (end > (int)str.length()) + end= str.length(); + } + + if (start >= end || start >= (int)str.length() || start < 0) + { + result->set_string("", 0); + return; + } + + result->set_string(str.ptr() + start, end - start); +} + + +/** + @brief String concatenation function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + CONCAT(str1, str2, ...) returns the string that results from concatenating + arguments. + + @note Dies if no arguments provided +*/ + +void func_concat(Expression_value args[], int count, Expression_value *result) +{ + if (count == 0) + die("concat() expects at least 1 argument"); + + My_string result_str= args[0].to_string(); + + for (int i= 1; i < count; ++i) + { + result_str.append(args[i].to_string()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String concatenation with separator function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + CONCAT_WS(separator, str1, str2, ...) concatenates strings using separator. + If separator is NULL, returns NULL; all other NULL values are skipped. + + @note Dies if less than 2 arguments provided +*/ + +void func_concat_ws(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("concat_ws() expects at least 2 arguments"); + + if (args[0].type == EXPR_NULL) + { + result->reset(); + return; + } + + My_string separator= args[0].to_string(); + My_string result_str= args[1].to_string(); + + for (int i= 2; i < count; ++i) + { + if (args[i].type == EXPR_NULL) + continue; + result_str.append(separator); + result_str.append(args[i].to_string()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String case conversion to lowercase + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LOWER(str) returns string str with all characters converted to lowercase. + LCASE(str) is an alias for LOWER(str). + + @note Dies if argument count != 1 +*/ + +void func_lower(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("lower() expects 1 argument, got %d", count); + + My_string result_str; + result_str.copy_casedn(charset_info, args[0].to_string().to_lex_cstring()); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String case conversion to uppercase + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + UPPER(str) returns string str with all characters converted to uppercase. + UCASE(str) is an alias for UPPER(str). + + @note Dies if argument count != 1 +*/ + +void func_upper(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("upper() expects 1 argument, got %d", count); + + My_string result_str; + result_str.copy_caseup(charset_info, args[0].to_string().to_lex_cstring()); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String reversal function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REVERSE(str) returns the string str with the order of the characters reversed. + + @note Dies if argument count != 1 +*/ + +void func_reverse(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("reverse() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + size_t len= str.length(); + for (size_t i= 0; i < len / 2; ++i) + { + char temp= str.c_ptr()[i]; + str.c_ptr()[i]= str.c_ptr()[len - 1 - i]; + str.c_ptr()[len - 1 - i]= temp; + } + + result->set_string(str.ptr(), str.length()); +} + + +/** + @brief String trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + TRIM(str) returns string str with leading and trailing space removed. + + @note Dies if argument count != 1 +*/ + +void func_trim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("trim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int start= 0; + while (start < (int)str.length() && my_isspace(charset_info, str.ptr()[start])) + start++; + + int end= (int)str.length(); + while (end > start && my_isspace(charset_info, str.ptr()[end - 1])) + end--; + + result->set_string(str.ptr() + start, end - start); +} + + +/** + @brief Left string trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LTRIM(str) returns string str with leading space removed. + + @note Dies if argument count != 1 +*/ + +void func_ltrim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("ltrim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int start= 0; + while (start < (int)str.length() && my_isspace(charset_info, str.ptr()[start])) + start++; + + result->set_string(str.ptr() + start, (int)str.length() - start); +} + + +/** + @brief Right string trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + RTRIM(str) returns string str with trailing space removed. + + @note Dies if argument count != 1 +*/ + +void func_rtrim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("rtrim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int end= (int)str.length(); + while (end > 0 && my_isspace(charset_info, str.ptr()[end - 1])) + end--; + + result->set_string(str.ptr(), end); +} + + +/** + @brief Left padding function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LPAD(str, len [, padstr]) returns the string str, left-padded with the + string padstr to a length of len characters. If str is longer than len, + the return value is shortened to len characters. If padstr is omitted, + the LPAD function pads spaces. + + @note Dies if wrong argument count, non-numeric length, or negative length +*/ + +void func_lpad(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2 && count != 3) + die("lpad() expects 2 or 3 arguments (str, length [, padstr]), got %d", count); + + if (!args[1].is_numeric) + die("lpad() length must be numeric"); + + My_string str= args[0].to_string(); + int length= (int)args[1].to_int(); + My_string padstr= count == 3 ? args[2].to_string() : My_string(); + My_string result_str; + + if (length < 0) + die("lpad() length cannot be negative"); + + if (count == 3 && padstr.is_empty()) + { + result->set_string("", 0); + return; + } + + if (length <= (int) str.length()) + { + result->set_string(str.ptr(), length); + return; + } + + int padding_needed= length - (int)str.length(); + if (count == 2) + { + for (int i= 0; i < padding_needed; ++i) + result_str.append(" ", 1); + } + else + { + for (int i= 0; i < padding_needed; ++i) + result_str.append(&padstr.ptr()[i % padstr.length()], 1); + } + + result_str.append(str.ptr(), str.length()); + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Right padding function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + RPAD(str, len [, padstr]) returns the string str, right-padded with the + string padstr to a length of len characters. If str is longer than len, + the return value is shortened to len characters. If padstr is omitted, + the RPAD function pads spaces. + + @note Dies if wrong argument count, non-numeric length, or negative length +*/ + +void func_rpad(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2 && count != 3) + die("rpad() expects 2 or 3 arguments (str, length [, padstr]), got %d", count); + + if (!args[1].is_numeric) + die("rpad() length must be numeric"); + + My_string str= args[0].to_string(); + int length= (int)args[1].to_int(); + My_string padstr= count == 3 ? args[2].to_string() : My_string(); + + if (length < 0) + die("rpad() length cannot be negative"); + + if (count == 3 && padstr.is_empty()) + { + result->set_string("", 0); + return; + } + + if (length <= (int)str.length()) + { + result->set_string(str.ptr(), length); + return; + } + + int padding_needed= length - (int)str.length(); + + if (count == 2) + { + for (int i= 0; i < padding_needed; ++i) + str.append(" ", 1); + } + else + { + for (int i= 0; i < padding_needed; ++i) + str.append(&padstr.ptr()[i % padstr.length()], 1); + } + + result->set_string(str.ptr(), str.length()); +} + + +/** + @brief String length function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LENGTH(str) returns the length of the string str. + + @note Dies if argument count != 1 +*/ + +void func_length(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("length() expects 1 argument, got %d", count); + + result->set_int((long long) args[0].to_string().length()); +} + + +/** + @brief Substring index function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + SUBSTRING_INDEX(str, delim, count) returns substring before count occurrences + of delim (counting from the left). If count is negative, returns substring + after count occurrences from end (counting from the right). Performs a + case-sensitive match when searching for delim. + + @note Dies if argument count != 3 or count is not numeric +*/ + +void func_substring_index(Expression_value args[], int count, + Expression_value *result) +{ + if (count != 3) + die("substring_index() expects 3 arguments (str, delimiter, count), got %d", count); + + if (!args[2].is_numeric) + die("substring_index() count must be numeric"); + + My_string str= args[0].to_string(); + My_string delimiter= args[1].to_string(); + int count_val= (int)args[2].to_int(); + + if (str.is_empty() || delimiter.is_empty() || !count_val) + { + result->set_string("", 0); + return; + } + + const char *str_ptr= str.ptr(); + const char *str_end= str.end(); + const char *delim_ptr= delimiter.ptr(); + int delim_len= (int)delimiter.length(); + + if (count_val > 0) + { + const char *current_pos= str_ptr; + int found_count= 0; + + while (current_pos < str_end && found_count < count_val) + { + const char *found= strstr(current_pos, delim_ptr); + if (!found) + break; + + found_count++; + if (found_count < count_val) + current_pos= found + delim_len; + else + current_pos= found; + } + + if (found_count < count_val) + result->set_string(str.ptr(), str.length()); + else + result->set_string(str.ptr(), current_pos - str_ptr); + } + else + { + count_val= -count_val; + const char *current_pos= str_end; + int found_count= 0; + + while (current_pos > str_ptr && found_count < count_val) + { + const char *found= NULL; + const char *search_pos= str_ptr; + + while (search_pos < current_pos) + { + const char *temp_found= strstr(search_pos, delim_ptr); + if (!temp_found || temp_found >= current_pos) + break; + found= temp_found; + search_pos= temp_found + delim_len; + } + + if (!found) + break; + + found_count++; + if (found_count < count_val) + current_pos= found; + else + current_pos= found + delim_len; + } + + if (found_count < count_val) + result->set_string(str.ptr(), str.length()); + else + result->set_string(current_pos, str_end - current_pos); + } +} + + +/** + @brief String repetition function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REPEAT(str, count) returns string consisting of str repeated count times. + If count is less than 1, returns an empty string. + + @note Dies if argument count != 2 or count is not numeric +*/ + +void func_repeat(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("repeat() expects 2 arguments (str, count), got %d", count); + + if (!args[1].is_numeric) + die("repeat() count must be numeric"); + + My_string result_str; + My_string str= args[0].to_string(); + int repeat_count= (int)args[1].to_int(); + + if (repeat_count <= 0 || str.is_empty()) + { + result->set_string("", 0); + return; + } + + if ((ulonglong) repeat_count > INT_MAX32) + repeat_count= INT_MAX32; + + for (int i= 0; i < repeat_count; ++i) + { + result_str.append(str.ptr(), str.length()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String insertion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + INSERT(str, pos, len, newstr) replaces len characters starting at pos with + newstr. Returns the original string if pos is not within the length of the string. + Replaces the rest of the string from position pos if len is not + within the length of the rest of the string. + + @note Dies if argument count != 4 or position/length not numeric +*/ + +void func_insert(Expression_value args[], int count, Expression_value *result) +{ + if (count != 4) + die("insert() expects 4 arguments (str, pos, len, newstr), got %d", count); + + if (!args[1].is_numeric) + die("insert() position must be numeric"); + + if (!args[2].is_numeric) + die("insert() length must be numeric"); + + My_string str= args[0].to_string(); + int pos= (int)args[1].to_int(); + int len= (int)args[2].to_int(); + My_string newstr= args[3].to_string(); + My_string result_str; + + + if (pos <= 0 || pos > (int)str.length()) + { + result->set_string(str.ptr(), str.length()); + return; + } + + pos--; + + int end_pos; + if (len < 0) + { + end_pos= str.length(); + } + else + { + end_pos= pos + len; + if (end_pos > (int)str.length()) + end_pos= str.length(); + } + + if (pos > 0) + result_str.append(str.ptr(), pos); + + result_str.append(newstr.ptr(), newstr.length()); + + if (end_pos < (int)str.length()) + result_str.append(str.ptr() + end_pos, str.length() - end_pos); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Regular expression position function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_INSTR(subject, pattern) returns position of first match of pattern in + subject. Uses POSIX extended regular expressions with case-insensitive + matching. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_instr('ABCC','C\$')) -> 4 + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_instr('ABC\$DE','\\\$')) -> 4 + @endcode + + @note Dies if argument count != 2 or regex compilation fails +*/ + +void func_regexp_instr(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("regexp_instr() expects 2 arguments (subject, pattern), got %d", count); + + regex_t regex; + regmatch_t match; + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + + if (pattern.is_empty()) + { + result->set_int(1); + return; + } + + if (subject.is_empty()) + { + result->set_int(0); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + err_code= regexec(®ex, subject.ptr(), 1, &match, 0); + regfree(®ex); + + result->set_int(err_code ? 0 : (int)(match.rm_so + 1)); +} + + +/** + @brief Regular expression substring extraction function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_SUBSTR(subject, pattern) returns substring that matches pattern. + Uses POSIX extended regular expressions with case-insensitive matching. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_substr('ABCC','C\$')) -> C + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_substr('ABC\$','\\\$')) -> $ + @endcode + + @note Dies if argument count != 2 or regex compilation fails +*/ + +void func_regexp_substr(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("regexp_substr() expects 2 arguments (subject, pattern), got %d", count); + + regex_t regex; + regmatch_t matches[1]; + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + + if (subject.is_empty()) + { + result->set_string("", 0); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + err_code= regexec(®ex, subject.ptr(), 1, matches, 0); + regfree(®ex); + + if (err_code) + { + result->set_string("", 0); + } + else + { + regoff_t start= matches[0].rm_so; + regoff_t end= matches[0].rm_eo; + result->set_string(subject.ptr() + start, end - start); + } +} + + +/** + @brief Regular expression replacement function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_REPLACE(subject, pattern, replace) replaces all matches of pattern + with replace. Supports backreferences \0-\9 in replace string. Uses + POSIX extended regex. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_replace('ABCC','C\$','D')) -> ABCD + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_replace('ABC\$','\\\$','D')) -> ABCD + @endcode + + @note Dies if argument count != 3 or regex compilation fails +*/ + +void func_regexp_replace(Expression_value args[], int count, + Expression_value *result) +{ + if (count != 3) + die("regexp_replace() expects 3 arguments (subject, pattern, replace), got %d", count); + + regex_t regex; + regmatch_t matches[10]; // Array to store up to 10 matches (0=full match, 1-9=capture groups) + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string result_str; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + My_string replace= args[2].to_string(); + const char *current_pos= subject.ptr(); + const char *end_pos= subject.end(); + const char *replace_ptr; + const char *replace_end; + + if (pattern.is_empty()) + { + result->set_string(subject.ptr(), subject.length()); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + while (current_pos < end_pos) + { + err_code= regexec(®ex, current_pos, 10, matches, 0); + if (err_code) + { + result_str.append(current_pos, end_pos - current_pos); + break; + } + + // Append the text before the match + if (matches[0].rm_so > 0) + result_str.append(current_pos, matches[0].rm_so); + + // Process replacement string with backreferences + replace_ptr= replace.ptr(); + replace_end= replace.end(); + + while (replace_ptr < replace_end) + { + if (*replace_ptr == '\\' && replace_ptr + 1 < replace_end) + { + int back_ref_num= (int) (*(replace_ptr + 1) - '0'); + regoff_t start_off, end_off; + if (back_ref_num >= 0 && back_ref_num <= 9 && + (start_off=matches[back_ref_num].rm_so) > -1 && + (end_off=matches[back_ref_num].rm_eo) > -1) + { + result_str.append(current_pos + start_off, end_off - start_off); + } + else + { + result_str.append(replace_ptr, 2); + } + replace_ptr+= 2; + continue; + } + result_str.append(replace_ptr, 1); + replace_ptr++; + } + + current_pos+= matches[0].rm_eo; + + if (matches[0].rm_so == matches[0].rm_eo) + current_pos++; + } + + regfree(®ex); + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief NULL-aware conditional function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + IFNULL(expr1, expr2) returns expr1 if it is not NULL, otherwise returns expr2. + Returns first non-NULL value. + + @note Dies if argument count != 2 +*/ + +void func_ifnull(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("ifnull() expects 2 arguments, got %d", count); + + if (args[0].type == EXPR_NULL) + { + *result= args[1]; + return; + } + *result= args[0]; +} + + +/** + @brief NULL-if-equal function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + NULLIF(expr1, expr2) returns NULL if expr1 = expr2, otherwise returns expr1. + This is the same as `CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END`. + + @note Dies if argument count != 2 +*/ + +void func_nullif(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("nullif() expects 2 arguments, got %d", count); + + /* If first is NULL, result is NULL (returns expr1) */ + if (args[0].type == EXPR_NULL) + { + result->reset(); + return; + } + + bool equal= false; + if (args[0].is_numeric && args[1].is_numeric) + { + if (args[0].is_unsigned || args[1].is_unsigned) + equal= (args[0].to_uint() == args[1].to_uint()); + else + equal= (args[0].to_int() == args[1].to_int()); + } + else + { + equal= !(strcmp(args[0].to_string().c_ptr(), args[1].to_string().c_ptr())); + } + + if (equal) + result->reset(); + else + *result= args[0]; +} + + +/** + @brief First non-NULL value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + COALESCE(value1, value2, ...) returns first non-NULL value in list. + Returns NULL if all values are NULL. + + @note Dies if no arguments provided +*/ + +void func_coalesce(Expression_value args[], int count, Expression_value *result) +{ + if (count < 1) + die("coalesce() expects at least 1 argument"); + + for (int i= 0; i < count; ++i) + { + if (args[i].type != EXPR_NULL) + { + *result= args[i]; + return; + } + } + result->reset(); +} + + +/** + @brief Least value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LEAST(value1, value2, ...) returns the minimum value among arguments. + For numeric values, performs numeric comparison. For strings, performs + string comparison. + + @note + If mixed numeric and string values are provided, the string values are + converted to numbers and the numeric comparison is performed. Be careful + with this, as a string could contain a number that is larger than 2^64-1. + + @note Dies if less than 2 arguments provided. +*/ + +void func_least(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("least() expects at least 2 arguments"); + + // Numeric mode if any arg is numeric + bool any_numeric= false; + for (int i= 0; i < count; ++i) + if (args[i].is_numeric) { any_numeric= true; break; } + + if (any_numeric) + { + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + if (cmp_decimal(args[i].to_string(), args[best_idx].to_string()) < 0) + best_idx= i; + } + if(args[best_idx].is_unsigned) + result->set_uint(args[best_idx].to_uint()); + else + result->set_int(args[best_idx].to_int()); + return; + } + + // String mode: collation-aware + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + My_string cur= args[i].to_string(); + My_string best= args[best_idx].to_string(); + if (sortcmp(&best, &cur, charset_info) > 0) + best_idx= i; + } + *result= args[best_idx]; +} + + +/** + @brief Greatest value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + GREATEST(value1, value2, ...) returns the maximum value among arguments. + For numeric values, performs numeric comparison. For strings, performs + string comparison. + + @note + If mixed numeric and string values are provided, the string values are + converted to numbers and the numeric comparison is performed. Be careful + with this, as a string could contain a number that is larger than 2^64-1. + + @note Dies if less than 2 arguments provided. +*/ + +void func_greatest(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("greatest() expects at least 2 arguments"); + + bool any_numeric= false; + for (int i= 0; i < count; ++i) + if (args[i].is_numeric) { any_numeric= true; break; } + + if (any_numeric) + { + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + if (cmp_decimal(args[i].to_string(), args[best_idx].to_string()) > 0) + best_idx= i; + } + if(args[best_idx].is_unsigned) + result->set_uint(args[best_idx].to_uint()); + else + result->set_int(args[best_idx].to_int()); + return; + } + + // String mode: collation-aware + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + My_string best= args[best_idx].to_string(); + My_string cur= args[i].to_string(); + if (sortcmp(&best, &cur, charset_info) < 0) + best_idx= i; + } + *result= args[best_idx]; +} + + +enum func_type get_expr_function_type(const char *name, size_t len) +{ + for (int i= 0; function_table[i].name; ++i) + { + if (!strncasecmp(function_table[i].name, name, len)) + return function_table[i].type; + } + return FUNC_UNKNOWN; +} + + +/** + @brief Execute built-in function call during expression parsing + @param[in] func_type Type of function to execute (from func_type enum) + @param[out] result Expression_value to store function result + @param[in] s Pointer to string pointer containing expression + + @details + Parses function arguments and executes the specified built-in function. + Each argument is recursively evaluated as a full expression. + Then delegates to the appropriate func_* implementation based on func_type. + + @note Dies on syntax errors or argument count mismatches +*/ + +void handle_expr_function_call(enum func_type func_type, + Expression_value *result, const char **s) +{ + Expression_value args[MAX_FUNC_ARGS]; + int arg_count= 0; + + while (!match(s, ")")) + { + if (arg_count >= MAX_FUNC_ARGS) + die("Too many function arguments (max %d)", MAX_FUNC_ARGS); + + expr(&args[arg_count], s); + arg_count++; + + /* if the next character is a comma, skip it */ + if (match(s, ",")) + continue; + + if (match(s, ")")) + break; + + die("Syntax error: Expected ',' or ')' in function call"); + } + + /* generic NULL propagation, except for IFNULL/NULLIF/COALESCE/CONCAT_WS */ + if (func_type != FUNC_IFNULL && func_type != FUNC_NULLIF && + func_type != FUNC_COALESCE && func_type != FUNC_CONCAT_WS) + { + for (int i= 0; i < arg_count; i++) + { + if (args[i].type == EXPR_NULL) + { + result->reset(); + return; + } + } + } + + switch (func_type) { + case FUNC_ABS: + func_abs(args, arg_count, result); + break; + case FUNC_CONV: + func_conv(args, arg_count, result); + break; + case FUNC_BIN: + func_bin(args, arg_count, result); + break; + case FUNC_OCT: + func_oct(args, arg_count, result); + break; + case FUNC_HEX: + func_hex(args, arg_count, result); + break; + case FUNC_INSTR: + func_instr(args, arg_count, result); + break; + case FUNC_LOCATE: + func_locate(args, arg_count, result); + break; + case FUNC_REPLACE: + func_replace(args, arg_count, result); + break; + case FUNC_SUBSTR: + func_substr(args, arg_count, result); + break; + case FUNC_CONCAT: + func_concat(args, arg_count, result); + break; + case FUNC_CONCAT_WS: + func_concat_ws(args, arg_count, result); + break; + case FUNC_LOWER: + func_lower(args, arg_count, result); + break; + case FUNC_UPPER: + func_upper(args, arg_count, result); + break; + case FUNC_REVERSE: + func_reverse(args, arg_count, result); + break; + case FUNC_TRIM: + func_trim(args, arg_count, result); + break; + case FUNC_LTRIM: + func_ltrim(args, arg_count, result); + break; + case FUNC_RTRIM: + func_rtrim(args, arg_count, result); + break; + case FUNC_LPAD: + func_lpad(args, arg_count, result); + break; + case FUNC_RPAD: + func_rpad(args, arg_count, result); + break; + case FUNC_LENGTH: + func_length(args, arg_count, result); + break; + case FUNC_SUBSTR_IDX: + func_substring_index(args, arg_count, result); + break; + case FUNC_REPEAT: + func_repeat(args, arg_count, result); + break; + case FUNC_INSERT: + func_insert(args, arg_count, result); + break; + case FUNC_LEAST: + func_least(args, arg_count, result); + break; + case FUNC_GREATEST: + func_greatest(args, arg_count, result); + break; + case FUNC_REGEXP_INSTR: + func_regexp_instr(args, arg_count, result); + break; + case FUNC_REGEXP_SUBSTR: + func_regexp_substr(args, arg_count, result); + break; + case FUNC_REGEXP_REPLACE: + func_regexp_replace(args, arg_count, result); + break; + case FUNC_IFNULL: + func_ifnull(args, arg_count, result); + break; + case FUNC_NULLIF: + func_nullif(args, arg_count, result); + break; + case FUNC_COALESCE: + func_coalesce(args, arg_count, result); + break; + case FUNC_UNKNOWN: + default: + die("Unknown function"); + break; + } +} + + /* Assign the variable with @@ -6422,6 +9169,84 @@ void do_block(enum block_cmd cmd, struct st_command* command) if (*p && *p != '{') die("Missing '{' after %s. Found \"%s\"", cmd_name, p); + if (*expr_start == '$' && *(expr_start + 1) == '(') + { + const char *scanner= expr_start + 2; + int paren_level= 1; + char in_quote= 0; // Track quote state + bool escaped= false; // Track if the current character is escaped + + while (*scanner && paren_level > 0) + { + if (!in_quote) + { + // Not inside quotes - handle parentheses normally + if (*scanner == '(') paren_level++; + else if (*scanner == ')') paren_level--; + else if (*scanner == '\'' || *scanner == '"') + in_quote= *scanner; // Start of quoted string + } + else + { + // Inside quotes - only look for closing quote + if (!escaped && *scanner == in_quote) + in_quote= 0; // End of quoted string + } + escaped= (!escaped && *scanner == '\\'); + scanner++; + } + + const char *end_ptr= expr_end; + while(end_ptr > expr_start && my_isspace(charset_info, *(end_ptr - 1))) + end_ptr--; + + // if the $(...) is the entire condition, evaluate it + if (scanner == end_ptr) + { + DYNAMIC_STRING evaluated_expr; + init_dynamic_string(&evaluated_expr, "", 64, 256); + + do_eval(&evaluated_expr, expr_start, expr_end, FALSE); + + char* result_str= evaluated_expr.str; + while (*result_str && my_isspace(charset_info, *result_str)) + result_str++; + + /* + Setup the next block on the stack + This logic is borrowed from the end of this function + Any non-empty string which does not begin with 0 is TRUE + */ + cur_block++; + cur_block->cmd= cmd; + cur_block->ok= (*result_str && *result_str != '0'); + + if (not_expr) + cur_block->ok= !cur_block->ok; + + if (cur_block->ok) + { + cur_block->delim[0]= '\0'; + } + else + { + /* Remember "old" delimiter if entering a false if block */ + if (safe_strcpy_truncated(cur_block->delim, sizeof cur_block->delim, + delimiter)) + die("Delimiter too long, truncated"); + } + + DBUG_PRINT("info", ("OK: %d", cur_block->ok)); + + dynstr_free(&evaluated_expr); + DBUG_VOID_RETURN; + } + else + { + die("Expression evaluator $(...) must be the entire condition"); + } + } + var_init(&v,0,0,0,0); /* If expression starts with a variable, it may be a compare condition */ diff --git a/mysql-test/main/mysqltest_expression_evaluation.result b/mysql-test/main/mysqltest_expression_evaluation.result new file mode 100644 index 00000000000..d9fa0ccb3b8 --- /dev/null +++ b/mysql-test/main/mysqltest_expression_evaluation.result @@ -0,0 +1,508 @@ +# ---------------------------------------------------------------------------- +# Test for MDEV-36107: Add expression evaluation support to mysqltest +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# Test backward compatibility (expressions are not evaluated without $()) +# ---------------------------------------------------------------------------- +# Backward compatibility - no evaluation +5 + 2 (no evaluation) -> 5 + 2 +# ---------------------------------------------------------------------------- +# Basic arithmetic operations +# ---------------------------------------------------------------------------- +# Basic arithmetic operations +10 + 5 -> 15 +10 - 4 -> 6 +3 * 7 -> 21 +20 / 4 -> 5 +21 % 5 -> 1 +# ---------------------------------------------------------------------------- +# Negative numbers and unary minus +# ---------------------------------------------------------------------------- +# Negative numbers and unary minus +-5 -> -5 +-1 + 3 -> 2 +-(2 + 3) -> -5 +-1 * -2 -> 2 +-10 / 2 -> -5 +-7 % 3 -> -1 +# Negative numbers in complex expressions +5 + -3 -> 2 +10 - -5 -> 15 +-2 * 3 + 1 -> -5 +# ---------------------------------------------------------------------------- +# Operator precedence +# ---------------------------------------------------------------------------- +# Operator precedence +2 + 3 * 4 - 1 -> 13 +20 / 2 - 3 -> 7 +10 - 4 + 2 -> 8 +# ---------------------------------------------------------------------------- +# Parentheses override precedence +# ---------------------------------------------------------------------------- +# Parentheses override precedence +(2 + 3) * 4 -> 20 +20 / (5 - 3) -> 10 +((2 + 3) * (4 + 1)) -> 25 +(10 / (3 + 2)) + 1 -> 3 +# ---------------------------------------------------------------------------- +# Test variables in expressions +# ---------------------------------------------------------------------------- +# Variables in expressions +100 / 25 + 1 = 5 +Variable substitution: 10 + 20 == 30 is 1 +# Test multiple variable references +Multiple variables: 10 * 20 / 10 = 20 +# ---------------------------------------------------------------------------- +# Overflow edge cases +# ---------------------------------------------------------------------------- +-9223372036854775808 / -1 -> -9223372036854775808 +-9223372036854775808 % -1 -> 0 +-(-9223372036854775808) -> -9223372036854775808 +-4611686018427387904 * 2 -> -9223372036854775808 +-4611686018427387904 * 2 / -1 -> -9223372036854775808 +-4611686018427387904 * -2 / -1 -> -9223372036854775808 +18446744073709551615 / 2 / -1 -> 0 +# ---------------------------------------------------------------------------- +# Comparison operators +# ---------------------------------------------------------------------------- +# Comparison operators +10 > 5 -> 1 +10 < 5 -> 0 +5 == 5 -> 1 +5 != 5 -> 0 +10 >= 10 -> 1 +10 <= 9 -> 0 +5 <= 5 -> 1 +5 >= 5 -> 1 +5 != 6 -> 1 +18446744073709551615 == -1 -> 0 +18446744073709551615 != -1 -> 1 +18446744073709551615 > -1 -> 1 +18446744073709551615 < -1 -> 0 +18446744073709551615 >= -1 -> 1 +18446744073709551615 <= -1 -> 0 +# NULL comparisons +NULL > 5 -> +NULL < 5 -> +NULL == 5 -> +NULL != 5 -> +NULL >= 5 -> +NULL <= 5 -> +NULL > 5 -> +NULL < 5 -> +NULL == NULL -> +NULL != NULL -> +# ---------------------------------------------------------------------------- +# Logical operators +# ---------------------------------------------------------------------------- +# Logical operators and combinations +1 && 1 -> 1 +1 && 0 -> 0 +0 && 1 -> 0 +0 && 0 -> 0 +2 && 3 -> 1 +2 && 0 -> 0 +-1 && -2 -> 1 +-2 && 2 -> 1 +1 || 1 -> 1 +1 || 0 -> 1 +0 || 1 -> 1 +0 || 0 -> 0 +2 || 3 -> 1 +2 || 0 -> 1 +-1 || -2 -> 1 +-2 || 2 -> 1 +!0 -> 1 +!1 -> 0 +!-3 -> 0 +!10 -> 0 +!-0 -> 1 +1 && 1 && 1 -> 1 +1 && 1 && 0 -> 0 +0 || 0 || 1 -> 1 +0 || 0 || 0 -> 0 +!(5 > 10) -> 1; +!(2 + 3 == 6) -> 1 +# ---------------------------------------------------------------------------- +# Expressions with spaces and formatting +# ---------------------------------------------------------------------------- +# Expressions with varying spaces +10 + 5 (with spaces) -> 15 +10+5 (no spaces) -> 15 +10+ 5 (mixed spaces) -> 15 +# Test spacing in comparisons +Spaced comparison works +No space comparison works +Mixed spacing works +# ---------------------------------------------------------------------------- +# Hex and Binary Literal Tests +# ---------------------------------------------------------------------------- +# Basic hex and binary parsing +0x10 -> 16 +0xFF -> 255 +0x0 -> 0 +0b1010 -> 10 +0b1111 -> 15 +0b0 -> 0 +# ---------------------------------------------------------------------------- +# Hex and Binary Arithmetic +# ---------------------------------------------------------------------------- +# Hex arithmetic operations +0x10 + 0x20 -> 48 +0xFF - 0x0F -> 240 +0x10 * 0x2 -> 32 +0x20 / 0x4 -> 8 +0x17 % 0x5 -> 3 +# Binary arithmetic operations +0b1010 + 0b0101 -> 15 +0b1111 - 0b0011 -> 12 +0b110 * 0b10 -> 12 +0b1000 / 0b10 -> 4 +0b1011 % 0b11 -> 2 +# ---------------------------------------------------------------------------- +# Mixed Base Arithmetic +# ---------------------------------------------------------------------------- +# Mixed base arithmetic (hex + binary + decimal) +0x10 + 0b1000 + 8 -> 32 +0xFF - 0b11111111 -> 0 +0x20 * 0b10 + 5 -> 74 +(0x64 + 0b1100) / 4 -> 28 +# ---------------------------------------------------------------------------- +# Hex and Binary Comparisons +# ---------------------------------------------------------------------------- +# Hex vs decimal comparisons +0x10 == 16 -> 1 +0xFF > 200 -> 1 +0x20 <= 32 -> 1 +0xA != 11 -> 1 +# Binary vs decimal comparisons +0b1010 == 10 -> 1 +0b1111 > 14 -> 1 +0b1000 <= 8 -> 1 +0b101 != 6 -> 1 +# Hex vs binary comparisons +0xFF == 0b11111111 -> 1 +0x10 > 0b1111 -> 1 +0xA <= 0b1010 -> 1 +0x5 != 0b101 -> 0 +# ---------------------------------------------------------------------------- +# Boolean Literal Tests +# ---------------------------------------------------------------------------- +# Boolean literals +true -> 1 +false -> 0 +TRUE -> 1 +FALSE -> 0 +# Boolean operations +true && false -> 0 +true || false -> 1 +true && true -> 1 +true || true -> 1 +!true -> 0 +!false -> 1 +# Boolean comparisons +true == 1 -> 1 +false == 0 -> 1 +true == 10 -> 0 +false == 10 -> 0 +true == 1 -> 1 +false == 1 -> 0 +true == 0 -> 0 +false == 0 -> 1 +true == true -> 1 +true == false -> 0 +true != true -> 0 +true != false -> 1 +true > true -> 0 +true > false -> 1 +true < true -> 0 +true < false -> 0 +true >= true -> 1 +true >= false -> 1 +true <= true -> 1 +true <= false -> 0 +# ---------------------------------------------------------------------------- +# Complex Mixed-Base Expressions +# ---------------------------------------------------------------------------- +# Complex expressions with multiple bases +0x10 + 0b1000 == 0x18 -> 1 +0x20 / 0b100 + 0b11 == 11 -> 1 +# ---------------------------------------------------------------------------- +# Test string comparisons with spaces +# ---------------------------------------------------------------------------- +# String comparisons with spaces +"hello' world" == hello world = 0 +hello world != goodbye world = 1 +# Basic equality: quoted vs quoted +"hello" == "hello" -> 1 +'hello' == 'hello' -> 1 +"hello" == 'hello' -> 1 +"" == "" -> 1 +'' == '' -> 1 +"" == '' -> 1 +# Basic in-equality: quoted vs quoted +"hello" == "world" -> 0 +"hello" == "Hello" -> 0 +"hello" == "hello " -> 0 +"" == "a" -> 0 +# Unquoted vs quoted strings +hello == "hello" -> 1 +hello == 'hello' -> 1 +hello == "hello" -> 1 +hello == " hello " -> 0 +hello world == "hello world" -> 1 +hello world == "hello world" -> 1 +hello world == "hello world" -> 1 +hello world == "hello world" -> 0 +hello world == "hello world" -> 0 +# Unquoted vs unquoted strings +hello == hello -> 1 +hello == hello -> 1 +hello world == hello world -> 1 +hello world == hello world -> 0 +# Strings with special characters (inside quotes) +"'hello'" == "'hello'" -> 1 +'"hello"' == '"hello"' -> 1 +"a+b=c" == "a+b=c" -> 1 +"a*b" == "a*b" -> 1 +"a()b" == "a()b" -> 1 +"a\b" == "a\b" -> 1 +# Complex expressions with string equality +"a" == "a" && 1 == 1 -> 1 +"a" == "b" || "c" == "c" -> 1 +!("a" == "b") -> 1 +(1+2) == 3 && "x" == "x" -> 1 +"x" == "y" || (5 > 3) -> 1 +# Using variables +"test string" == 'test string' -> 1 +"test string" == "another string" -> 0 +"test string" != "another string" -> 1 +"test string" == test string -> 1 +# Using results from SQL +CREATE TABLE t1 (s VARCHAR(20)); +INSERT INTO t1 VALUES ('data'); +data == "data" -> 1 +data == data -> 1 +data == 'data' -> 1 +DROP TABLE t1; +# Edge cases +" " == " " -> 0 +" " == "" -> 0 +"" == "" -> 1 +'\))(' == "\))(" -> 1 +# Numeric strings +"123" == 123 -> 0 +123 == "123" -> 0 +"0" == 0 -> 0 +1 == "1.0" -> 0 +# Mixed quotes in variables +'This is a "quoted" string' == 'This is a "quoted" string' -> 1 +"This is a 'quoted' string" == "This is a 'quoted' string" -> 1 +# Mixed type comparisons +0 != "string" -> 1 +123 == "123" -> 0 +"abc" == 123 -> 0 +NULL == "string" -> +# ---------------------------------------------------------------------------- +# SQL Integration +# ---------------------------------------------------------------------------- +# Expression in SQL query +SQL with expression (7 * 8) -> 56 +# Basic SQL result usage in expressions +Expression with SQL: SQL(15) + 5 -> 20 +# Complex SQL queries in expressions +SQL count matches expression -> 3 +# ---------------------------------------------------------------------------- +# Control Flow Statements (if/while) +# ---------------------------------------------------------------------------- +# Basic if statement conditions +if (1) evaluates to true +Non-zero number is true +Non-empty string is true +Non-empty string with spaces is true +# Variable comparisons in if statements +Arithmetic in comparison: (5 * 2) == 10 is true +# String comparisons in if statements +if (hello != world) evaluates to true +if (hello world == hello world) evaluates to true +# While loop with expression condition +While loop iteration: 3 +While loop iteration: 2 +While loop iteration: 1 +0x10 is greater than 0b1111 +Boolean and hex comparison works +Counter: 0 +Counter: 1 +Counter: 2 +# ---------------------------------------------------------------------------- +# Bitwise operators +# ---------------------------------------------------------------------------- +# Basic bitwise AND (&) +12 & 10 -> 8 +15 & 7 -> 7 +255 & 128 -> 128 +0 & 15 -> 0 +# Basic bitwise OR (|) +12 | 10 -> 14 +8 | 4 -> 12 +1 | 2 -> 3 +0 | 15 -> 15 +# Basic bitwise XOR (^) +12 ^ 10 -> 6 +15 ^ 15 -> 0 +5 ^ 3 -> 6 +255 ^ 128 -> 127 +# Basic bitwise NOT (~) +~0 -> 18446744073709551615 +~1 -> 18446744073709551614 +~255 -> 18446744073709551360 +~(-1) -> 0 +# Basic left shift (<<) +1 << 3 -> 8 +5 << 2 -> 20 +8 << 1 -> 16 +0 << 5 -> 0 +# Basic right shift (>>) +8 >> 3 -> 1 +20 >> 2 -> 5 +16 >> 1 -> 8 +7 >> 3 -> 0 +# ---------------------------------------------------------------------------- +# Bitwise operations with hex and binary literals +# ---------------------------------------------------------------------------- +# Bitwise operations with hex literals +0xFF & 0x0F -> 15 +0xF0 | 0x0F -> 255 +0xFF ^ 0xAA -> 85 +~0xFF -> 18446744073709551360 +0x10 << 2 -> 64 +0x80 >> 4 -> 8 +# Bitwise operations with binary literals +0b1100 & 0b1010 -> 8 +0b1000 | 0b0100 -> 12 +0b1111 ^ 0b1010 -> 5 +~0b1111 -> 18446744073709551600 +0b101 << 2 -> 20 +0b10000 >> 2 -> 4 +# ---------------------------------------------------------------------------- +# Mixed base bitwise operations +# ---------------------------------------------------------------------------- +# Mixed base bitwise operations +0xFF & 0b11110000 -> 240 +0x0F | 0b11110000 -> 255 +255 ^ 0xAA -> 85 +0b1000 << 0x2 -> 32 +0x40 >> 0b10 -> 16 +# ---------------------------------------------------------------------------- +# Bitwise operator precedence +# ---------------------------------------------------------------------------- +# Bitwise operator precedence +12 | 8 ^ 4 -> 12 +12 ^ 8 | 4 -> 4 +12 & 8 ^ 4 -> 12 +12 ^ 8 & 4 -> 4 +12 | 8 & 4 -> 12 +# Parentheses override bitwise precedence +(12 | 8) ^ 4 -> 8 +12 | (8 ^ 4) -> 12 +(12 & 8) | 4 -> 12 +12 & (8 | 4) -> 12 +# ---------------------------------------------------------------------------- +# Shift precedence with arithmetic operators +# ---------------------------------------------------------------------------- +# Shift operators vs arithmetic +2 + 3 << 1 -> 10 +8 >> 1 + 1 -> 2 +4 * 2 << 2 -> 32 +16 >> 2 * 1 -> 4 +# ---------------------------------------------------------------------------- +# Bitwise operations with negative numbers +# ---------------------------------------------------------------------------- +# Bitwise operations with negative numbers (unsigned interpretation) +-1 & 15 -> 15 +-16 | 7 -> 18446744073709551607 +-1 ^ 255 -> 18446744073709551360 +-10 << 3 -> 18446744073709551536 +-10 >> 3 -> 2305843009213693950 +# ---------------------------------------------------------------------------- +# Complex bitwise expressions +# ---------------------------------------------------------------------------- +# Complex bitwise expressions +(0xFF & 0xF0) | (0x0F & 0x05) -> 245 +~(~0xFF | 0x0F) -> 240 +(1 << 4) | (1 << 2) | (1 << 0) -> 21 +(255 >> 2) & (63 << 1) -> 62 +# ---------------------------------------------------------------------------- +# Bitwise operations in conditional expressions +# ---------------------------------------------------------------------------- +# Bitwise operations in conditions +15 & 8 is true (result is 8, non-zero) +!(12 ^ 12) is true +1 << 5 equals 32 +# ---------------------------------------------------------------------------- +# Bitwise operations with variables +# ---------------------------------------------------------------------------- +# Bitwise operations with variables +0xAB & 0xFF -> 171 +0xAB << 4 -> 2736 +0xAB >> 4 -> 10 +~0xAB -> 18446744073709551444 +# ---------------------------------------------------------------------------- +# Bitwise error cases +# ---------------------------------------------------------------------------- +# Testing bitwise error cases +# Shift by negative amount +mysqltest: At line 1: Evaluation error: Invalid shift amount +# Shift by too large amount (>= 64) +mysqltest: At line 1: Evaluation error: Invalid shift amount +mysqltest: At line 1: Evaluation error: Invalid shift amount +# ---------------------------------------------------------------------------- +# Edge cases for shift operations +# ---------------------------------------------------------------------------- +# Edge cases for shift operations +1 << 0 -> 1 +1 << 63 -> 9223372036854775808 +8 >> 0 -> 8 +1 >> 63 -> 0 +# ---------------------------------------------------------------------------- +# Bitwise operations with large numbers +# ---------------------------------------------------------------------------- +# Bitwise operations with large numbers +0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE -> 9223372036854775806 +0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE -> 9223372036854775807 +0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE -> 1 +# ---------------------------------------------------------------------------- +# Complex expressions with multiple operators +# ---------------------------------------------------------------------------- +# Complex expressions +2 + 3 * 4 > 10 -> 1 +(5 + 5) == (2 * 5) -> 1 +1 + 2 + 3 + 4 == 10 -> 1 +3 + 2 > 4 && 5 > 2 -> 1 +2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2 -> 1 +1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4 -> 1 +4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2 -> 1 +5 * 3 + 7 << 1 ^ 12 >> 2 -> 45056 +8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2 -> 0 +(!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) -> 17 +# ---------------------------------------------------------------------------- +# Error Handling (Syntax and Runtime) +# ---------------------------------------------------------------------------- +# Test case: Empty unquoted string (illegal) +mysqltest: At line 1: Syntax error: invalid expression +# Test case: Empty unquoted string with only spaces (illegal) +mysqltest: At line 1: Syntax error: invalid expression +# Test case: Unmatched parenthesis +mysqltest: At line 1: Unmatched parenthesis in expression starting at '$((1 + 2)' +mysqltest: At line 1: Unmatched parenthesis in expression starting at '$(((((((((' +# Test case: Expression evaluator not the entire condition +mysqltest: At line 1: Expression evaluator $(...) must be the entire condition +mysqltest: At line 1: Empty variable +# Test case: Division by zero +mysqltest: At line 1: Evaluation error: Division by zero +# Test case: Modulo by zero +mysqltest: At line 1: Evaluation error: Modulo by zero +# Test case: Overflow +mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type +mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type +# Expression evaluation tests completed successfully diff --git a/mysql-test/main/mysqltest_expression_evaluation.test b/mysql-test/main/mysqltest_expression_evaluation.test new file mode 100644 index 00000000000..7a108f2fe17 --- /dev/null +++ b/mysql-test/main/mysqltest_expression_evaluation.test @@ -0,0 +1,897 @@ +--echo # ---------------------------------------------------------------------------- +--echo # Test for MDEV-36107: Add expression evaluation support to mysqltest +--echo # ---------------------------------------------------------------------------- + +--source include/not_embedded.inc + +--echo # ---------------------------------------------------------------------------- +--echo # Test backward compatibility (expressions are not evaluated without \$()) +--echo # ---------------------------------------------------------------------------- + +let $old_math = 5 + 2; + +--echo # Backward compatibility - no evaluation +--echo 5 + 2 (no evaluation) -> $old_math + +--echo # ---------------------------------------------------------------------------- +--echo # Basic arithmetic operations +--echo # ---------------------------------------------------------------------------- + +let $a = $(10 + 5); +let $b = $(10 - 4); +let $c = $(3 * 7); +let $d = $(20 / 4); +let $e = $(21 % 5); + +--echo # Basic arithmetic operations +--echo 10 + 5 -> $a +--echo 10 - 4 -> $b +--echo 3 * 7 -> $c +--echo 20 / 4 -> $d +--echo 21 % 5 -> $e + +--echo # ---------------------------------------------------------------------------- +--echo # Negative numbers and unary minus +--echo # ---------------------------------------------------------------------------- + +let $neg1 = $(-5); +let $neg2 = $(-1 + 3); +let $neg3 = $(-(2 + 3)); +let $neg4 = $(-1 * -2); +let $neg5 = $(-10 / 2); +let $neg6 = $(-7 % 3); + +--echo # Negative numbers and unary minus +--echo -5 -> $neg1 +--echo -1 + 3 -> $neg2 +--echo -(2 + 3) -> $neg3 +--echo -1 * -2 -> $neg4 +--echo -10 / 2 -> $neg5 +--echo -7 % 3 -> $neg6 + +let $neg_complex1 = $(5 + -3); +let $neg_complex2 = $(10 - -5); +let $neg_complex3 = $(-2 * 3 + 1); + +--echo # Negative numbers in complex expressions +--echo 5 + -3 -> $neg_complex1 +--echo 10 - -5 -> $neg_complex2 +--echo -2 * 3 + 1 -> $neg_complex3 + +--echo # ---------------------------------------------------------------------------- +--echo # Operator precedence +--echo # ---------------------------------------------------------------------------- + +let $p1 = $(2 + 3 * 4 - 1); +let $p2 = $(20 / 2 - 3); +let $p3 = $(10 - 4 + 2); + +--echo # Operator precedence +--echo 2 + 3 * 4 - 1 -> $p1 +--echo 20 / 2 - 3 -> $p2 +--echo 10 - 4 + 2 -> $p3 + +--echo # ---------------------------------------------------------------------------- +--echo # Parentheses override precedence +--echo # ---------------------------------------------------------------------------- + +let $p4 = $((2 + 3) * 4); +let $p5 = $(20 / (5 - 3)); +let $p6 = $(((2 + 3) * (4 + 1))); +let $p7 = $((10 / (3 + 2)) + 1); + +--echo # Parentheses override precedence +--echo (2 + 3) * 4 -> $p4 +--echo 20 / (5 - 3) -> $p5 +--echo ((2 + 3) * (4 + 1)) -> $p6 +--echo (10 / (3 + 2)) + 1 -> $p7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test variables in expressions +--echo # ---------------------------------------------------------------------------- + +let $v1 = 100; +let $v2 = 25; +let $v_res = $($v1 / $v2 + 1); + +--echo # Variables in expressions +--echo 100 / 25 + 1 = $v_res + + +let $var_a = 10; +let $var_b = 20; +let $var_expr = $($var_a + $var_b == 30); + +--echo Variable substitution: 10 + 20 == 30 is $var_expr + +--echo # Test multiple variable references +let $multi_var = $($var_a * $var_b / $var_a); +--echo Multiple variables: 10 * 20 / 10 = $multi_var + +--echo # ---------------------------------------------------------------------------- +--echo # Overflow edge cases +--echo # ---------------------------------------------------------------------------- + +--echo -9223372036854775808 / -1 -> $(-9223372036854775808 / -1) +--echo -9223372036854775808 % -1 -> $(-9223372036854775808 % -1) +--echo -(-9223372036854775808) -> $(-(-9223372036854775808)) +--echo -4611686018427387904 * 2 -> $(-4611686018427387904 * 2) +--echo -4611686018427387904 * 2 / -1 -> $(-4611686018427387904 * 2 / -1) +--echo -4611686018427387904 * -2 / -1 -> $(-4611686018427387904 * -2 / -1) +--echo 18446744073709551615 / 2 / -1 -> $(18446744073709551615 / 2 / -1) + +--echo # ---------------------------------------------------------------------------- +--echo # Comparison operators +--echo # ---------------------------------------------------------------------------- + +--echo # Comparison operators +--echo 10 > 5 -> $(10 > 5) +--echo 10 < 5 -> $(10 < 5) +--echo 5 == 5 -> $(5 == 5) +--echo 5 != 5 -> $(5 != 5) +--echo 10 >= 10 -> $(10 >= 10) +--echo 10 <= 9 -> $(10 <= 9) +--echo 5 <= 5 -> $(5 <= 5) +--echo 5 >= 5 -> $(5 >= 5) +--echo 5 != 6 -> $(5 != 6) + +--echo 18446744073709551615 == -1 -> $(18446744073709551615 == -1) +--echo 18446744073709551615 != -1 -> $(18446744073709551615 != -1) +--echo 18446744073709551615 > -1 -> $(18446744073709551615 > -1) +--echo 18446744073709551615 < -1 -> $(18446744073709551615 < -1) +--echo 18446744073709551615 >= -1 -> $(18446744073709551615 >= -1) +--echo 18446744073709551615 <= -1 -> $(18446744073709551615 <= -1) + +--echo # NULL comparisons +--echo NULL > 5 -> $(NULL > 5) +--echo NULL < 5 -> $(NULL < 5) +--echo NULL == 5 -> $(NULL == 5) +--echo NULL != 5 -> $(NULL != 5) +--echo NULL >= 5 -> $(NULL >= 5) +--echo NULL <= 5 -> $(NULL <= 5) +--echo NULL > 5 -> $(NULL > 5) +--echo NULL < 5 -> $(NULL < 5) +--echo NULL == NULL -> $(NULL == NULL) +--echo NULL != NULL -> $(NULL != NULL) + +--echo # ---------------------------------------------------------------------------- +--echo # Logical operators +--echo # ---------------------------------------------------------------------------- + +--echo # Logical operators and combinations +--echo 1 && 1 -> $(1 && 1) +--echo 1 && 0 -> $(1 && 0) +--echo 0 && 1 -> $(0 && 1) +--echo 0 && 0 -> $(0 && 0) +--echo 2 && 3 -> $(2 && 3) +--echo 2 && 0 -> $(2 && 0) +--echo -1 && -2 -> $(-1 && -2) +--echo -2 && 2 -> $(-2 && 2) + +--echo 1 || 1 -> $(1 || 1) +--echo 1 || 0 -> $(1 || 0) +--echo 0 || 1 -> $(0 || 1) +--echo 0 || 0 -> $(0 || 0) +--echo 2 || 3 -> $(2 || 3) +--echo 2 || 0 -> $(2 || 0) +--echo -1 || -2 -> $(-1 || -2) +--echo -2 || 2 -> $(-2 || 2) + +--echo !0 -> $(!0) +--echo !1 -> $(!1) +--echo !-3 -> $(!-3) +--echo !10 -> $(!10) +--echo !-0 -> $(!-0) +--echo 1 && 1 && 1 -> $(1 && 1 && 1) +--echo 1 && 1 && 0 -> $(1 && 1 && 0) +--echo 0 || 0 || 1 -> $(0 || 0 || 1) +--echo 0 || 0 || 0 -> $(0 || 0 || 0) +--echo !(5 > 10) -> $(!(5 > 10)); +--echo !(2 + 3 == 6) -> $(!(2 + 3 == 6)) + +--echo # ---------------------------------------------------------------------------- +--echo # Expressions with spaces and formatting +--echo # ---------------------------------------------------------------------------- + +let $spaced = $( 10 + 5 ); +let $no_space = $(10+5); +let $mixed_space = $( 10+ 5 ); + +--echo # Expressions with varying spaces +--echo 10 + 5 (with spaces) -> $spaced +--echo 10+5 (no spaces) -> $no_space +--echo 10+ 5 (mixed spaces) -> $mixed_space + +--echo # Test spacing in comparisons +if ($( 5 == 5 )) +{ + --echo Spaced comparison works +} + +if ($(5< 7)) +{ + --echo No space comparison works +} + +if ($( 5 >= 5 )) +{ + --echo Mixed spacing works +} + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Literal Tests +--echo # ---------------------------------------------------------------------------- + +--echo # Basic hex and binary parsing +let $hex1 = $(0x10); +let $hex2 = $(0xFF); +let $hex3 = $(0x0); +let $bin1 = $(0b1010); +let $bin2 = $(0b1111); +let $bin3 = $(0b0); + +--echo 0x10 -> $hex1 +--echo 0xFF -> $hex2 +--echo 0x0 -> $hex3 +--echo 0b1010 -> $bin1 +--echo 0b1111 -> $bin2 +--echo 0b0 -> $bin3 + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Arithmetic +--echo # ---------------------------------------------------------------------------- + +--echo # Hex arithmetic operations +let $hex_add = $(0x10 + 0x20); +let $hex_sub = $(0xFF - 0x0F); +let $hex_mul = $(0x10 * 0x2); +let $hex_div = $(0x20 / 0x4); +let $hex_mod = $(0x17 % 0x5); + +--echo 0x10 + 0x20 -> $hex_add +--echo 0xFF - 0x0F -> $hex_sub +--echo 0x10 * 0x2 -> $hex_mul +--echo 0x20 / 0x4 -> $hex_div +--echo 0x17 % 0x5 -> $hex_mod + +--echo # Binary arithmetic operations +let $bin_add = $(0b1010 + 0b0101); +let $bin_sub = $(0b1111 - 0b0011); +let $bin_mul = $(0b110 * 0b10); +let $bin_div = $(0b1000 / 0b10); +let $bin_mod = $(0b1011 % 0b11); + +--echo 0b1010 + 0b0101 -> $bin_add +--echo 0b1111 - 0b0011 -> $bin_sub +--echo 0b110 * 0b10 -> $bin_mul +--echo 0b1000 / 0b10 -> $bin_div +--echo 0b1011 % 0b11 -> $bin_mod + +--echo # ---------------------------------------------------------------------------- +--echo # Mixed Base Arithmetic +--echo # ---------------------------------------------------------------------------- + +--echo # Mixed base arithmetic (hex + binary + decimal) +let $mixed1 = $(0x10 + 0b1000 + 8); # 16 + 8 + 8 = 32 +let $mixed2 = $(0xFF - 0b11111111); # 255 - 255 = 0 +let $mixed3 = $(0x20 * 0b10 + 10); # 32 * 2 + 10 = 74 +let $mixed4 = $((0x64 + 0b1100) / 4); # (100 + 12) / 4 = 28 + +--echo 0x10 + 0b1000 + 8 -> $mixed1 +--echo 0xFF - 0b11111111 -> $mixed2 +--echo 0x20 * 0b10 + 5 -> $mixed3 +--echo (0x64 + 0b1100) / 4 -> $mixed4 + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Comparisons +--echo # ---------------------------------------------------------------------------- + +--echo # Hex vs decimal comparisons +--echo 0x10 == 16 -> $(0x10 == 16) +--echo 0xFF > 200 -> $(0xFF > 200) +--echo 0x20 <= 32 -> $(0x20 <= 32) +--echo 0xA != 11 -> $(0xA != 11) + +--echo # Binary vs decimal comparisons +--echo 0b1010 == 10 -> $(0b1010 == 10) +--echo 0b1111 > 14 -> $(0b1111 > 14) +--echo 0b1000 <= 8 -> $(0b1000 <= 8) +--echo 0b101 != 6 -> $(0b101 != 6) + +--echo # Hex vs binary comparisons +--echo 0xFF == 0b11111111 -> $(0xFF == 0b11111111) +--echo 0x10 > 0b1111 -> $(0x10 > 0b1111) +--echo 0xA <= 0b1010 -> $(0xA <= 0b1010) +--echo 0x5 != 0b101 -> $(0x5 != 0b101) + +--echo # ---------------------------------------------------------------------------- +--echo # Boolean Literal Tests +--echo # ---------------------------------------------------------------------------- + +--echo # Boolean literals +let $bool1 = $(true); +let $bool2 = $(false); +let $bool3 = $(TRUE); +let $bool4 = $(FALSE); + +--echo true -> $bool1 +--echo false -> $bool2 +--echo TRUE -> $bool3 +--echo FALSE -> $bool4 + +--echo # Boolean operations +--echo true && false -> $(true && false) +--echo true || false -> $(true || false) +--echo true && true -> $(true && true) +--echo true || true -> $(true || true) +--echo !true -> $(!true) +--echo !false -> $(!false) + +--echo # Boolean comparisons +--echo true == 1 -> $(true == 1) +--echo false == 0 -> $(false == 0) +--echo true == 10 -> $(true == 10) +--echo false == 10 -> $(false == 10) +--echo true == 1 -> $(true == 1) +--echo false == 1 -> $(false == 1) +--echo true == 0 -> $(true == 0) +--echo false == 0 -> $(false == 0) +--echo true == true -> $(true == true) +--echo true == false -> $(true == false) +--echo true != true -> $(true != true) +--echo true != false -> $(true != false) +--echo true > true -> $(true > true) +--echo true > false -> $(true > false) +--echo true < true -> $(true < true) +--echo true < false -> $(true < false) +--echo true >= true -> $(true >= true) +--echo true >= false -> $(true >= false) +--echo true <= true -> $(true <= true) +--echo true <= false -> $(true <= false) + +--echo # ---------------------------------------------------------------------------- +--echo # Complex Mixed-Base Expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex expressions with multiple bases +let $complex1 = $(0x10 + 0b1000 == 0x18); # 16 + 8 == 24 +let $complex3 = $(0x20 / 0b100 + 0b11 == 11); # 32/4 + 3 == 11 + +--echo 0x10 + 0b1000 == 0x18 -> $complex1 +--echo 0x20 / 0b100 + 0b11 == 11 -> $complex3 + +--echo # ---------------------------------------------------------------------------- +--echo # Test string comparisons with spaces +--echo # ---------------------------------------------------------------------------- + +--echo # String comparisons with spaces +--echo "hello' world" == hello world = $("hello' world" == hello world) +--echo hello world != goodbye world = $(hello world != goodbye world) + +--echo # Basic equality: quoted vs quoted +--echo "hello" == "hello" -> $("hello" == "hello") +--echo 'hello' == 'hello' -> $('hello' == 'hello') +--echo "hello" == 'hello' -> $("hello" == 'hello') +--echo "" == "" -> $("" == "") +--echo '' == '' -> $('' == '') +--echo "" == '' -> $("" == '') + +--echo # Basic in-equality: quoted vs quoted +--echo "hello" == "world" -> $("hello" == "world") +--echo "hello" == "Hello" -> $("hello" == "Hello") +--echo "hello" == "hello " -> $("hello" == "hello ") +--echo "" == "a" -> $("" == "a") + +--echo # Unquoted vs quoted strings +--echo hello == "hello" -> $(hello == "hello") +--echo hello == 'hello' -> $(hello == 'hello') +--echo hello == "hello" -> $( hello == "hello") +--echo hello == " hello " -> $(hello == " hello ") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $( hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") + +--echo # Unquoted vs unquoted strings +--echo hello == hello -> $(hello == hello) +--echo hello == hello -> $( hello == hello ) +--echo hello world == hello world -> $(hello world == hello world) +--echo hello world == hello world -> $( hello world == hello world ) + +--echo # Strings with special characters (inside quotes) +--echo "'hello'" == "'hello'" -> $("'hello'" == "'hello'") +--echo '"hello"' == '"hello"' -> $('"hello"' == '"hello"') +--echo "a+b=c" == "a+b=c" -> $("a+b=c" == "a+b=c") +--echo "a*b" == "a*b" -> $("a*b" == "a*b") +--echo "a()b" == "a()b" -> $("a()b" == "a()b") +--echo "a\\b" == "a\\b" -> $("a\\b" == "a\\b") + + +--echo # Complex expressions with string equality +--echo "a" == "a" && 1 == 1 -> $("a" == "a" && 1 == 1) +--echo "a" == "b" || "c" == "c" -> $("a" == "b" || "c" == "c") +--echo !("a" == "b") -> $(!("a" == "b")) +--echo (1+2) == 3 && "x" == "x" -> $((1+2) == 3 && "x" == "x") +--echo "x" == "y" || (5 > 3) -> $("x" == "y" || (5 > 3)) + +--echo # Using variables +let $s1 = "test string"; +let $s2 = 'test string'; +let $s3 = "another string"; +--echo $s1 == $s2 -> $($s1 == $s2) +--echo $s1 == $s3 -> $($s1 == $s3) +--echo $s1 != $s3 -> $($s1 != $s3) +let $s_unquoted = test string; +--echo $s1 == $s_unquoted -> $($s1 == $s_unquoted) + +--echo # Using results from SQL +CREATE TABLE t1 (s VARCHAR(20)); +INSERT INTO t1 VALUES ('data'); +let $sql_res = `SELECT s FROM t1`; +--echo $sql_res == "data" -> $($sql_res == "data") +--echo $sql_res == data -> $($sql_res == data) +--echo $sql_res == 'data' -> $($sql_res == 'data') +DROP TABLE t1; + +--echo # Edge cases +--echo " " == " " -> $(" " == " ") +--echo " " == "" -> $(" " == "") +--echo "" == "" -> $("" == "") +--echo '\))(' == "\))(" -> $('\))(' == "\))(") + +--echo # Numeric strings +--echo "123" == 123 -> $("123" == 123) +--echo 123 == "123" -> $(123 == "123") +--echo "0" == 0 -> $("0" == 0) +--echo 1 == "1.0" -> $(1 == "1.0") + +--echo # Mixed quotes in variables +let $a = 'This is a "quoted" string'; +let $b = "This is a 'quoted' string"; +--echo $a == 'This is a "quoted" string' -> $($a == 'This is a "quoted" string') +--echo $b == "This is a 'quoted' string" -> $($b == "This is a 'quoted' string") + +--echo # Mixed type comparisons +--echo 0 != "string" -> $(0 != string) +--echo 123 == "123" -> $(123 == "123") +--echo "abc" == 123 -> $(abc == 123) +--echo NULL == "string" -> $(NULL == "string") + +--echo # ---------------------------------------------------------------------------- +--echo # SQL Integration +--echo # ---------------------------------------------------------------------------- + +let $val1 = 7; +let $val2 = 8; +let $query_result = `SELECT $($val1 * $val2) as product`; + +--echo # Expression in SQL query +--echo SQL with expression (7 * 8) -> $query_result + +--echo # Basic SQL result usage in expressions +let $sql_val = `SELECT 15`; +let $expr_with_sql = $($sql_val + 5); +--echo Expression with SQL: SQL(15) + 5 -> $expr_with_sql + +--echo # Complex SQL queries in expressions +let $count_result = `SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3) t`; +if ($($count_result == 1 + 2)) +{ + --echo SQL count matches expression -> $count_result +} + +--echo # ---------------------------------------------------------------------------- +--echo # Control Flow Statements (if/while) +--echo # ---------------------------------------------------------------------------- + +--echo # Basic if statement conditions +if ($(1)) { + --echo if (1) evaluates to true +} + +if ($(0)) { + --echo This should not print - if (0) is false +} + +if ($(-42)) +{ + --echo Non-zero number is true +} + +if ($(some_string)) +{ + --echo Non-empty string is true +} + +if ($(some string with spaces)) +{ + --echo Non-empty string with spaces is true +} + +--echo # Variable comparisons in if statements +let $x = 5; +if ($(($x * 2) == 10)) { + --echo Arithmetic in comparison: (5 * 2) == 10 is true +} + +--echo # String comparisons in if statements +if ($(hello == world)) { + --echo This should not print - strings don't match +} + +if ($(hello != world)) { + --echo if (hello != world) evaluates to true +} + +if ($(hello world == hello world)) { + --echo if (hello world == hello world) evaluates to true +} + +--echo # While loop with expression condition +let $i = 3; +while ($($i > 0)) { + --echo While loop iteration: $i + --dec $i +} + +if ($(0x10 > 0b1111)) +{ + --echo 0x10 is greater than 0b1111 +} + +if ($(true && (0xFF == 255))) +{ + --echo Boolean and hex comparison works +} + +let $counter = $(0x0); +while ($($counter < 0b11)) +{ + --echo Counter: $counter + --inc $counter +} + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operators +--echo # ---------------------------------------------------------------------------- + +--echo # Basic bitwise AND (&) +let $and1 = $(12 & 10); +let $and2 = $(15 & 7); +let $and3 = $(255 & 128); +let $and4 = $(0 & 15); + +--echo 12 & 10 -> $and1 +--echo 15 & 7 -> $and2 +--echo 255 & 128 -> $and3 +--echo 0 & 15 -> $and4 + +--echo # Basic bitwise OR (|) +let $or1 = $(12 | 10); +let $or2 = $(8 | 4); +let $or3 = $(1 | 2); +let $or4 = $(0 | 15); + +--echo 12 | 10 -> $or1 +--echo 8 | 4 -> $or2 +--echo 1 | 2 -> $or3 +--echo 0 | 15 -> $or4 + +--echo # Basic bitwise XOR (^) +let $xor1 = $(12 ^ 10); +let $xor2 = $(15 ^ 15); +let $xor3 = $(5 ^ 3); +let $xor4 = $(255 ^ 128); + +--echo 12 ^ 10 -> $xor1 +--echo 15 ^ 15 -> $xor2 +--echo 5 ^ 3 -> $xor3 +--echo 255 ^ 128 -> $xor4 + +--echo # Basic bitwise NOT (~) +let $not1 = $(~0); +let $not2 = $(~1); +let $not3 = $(~255); +let $not4 = $(~(-1)); + +--echo ~0 -> $not1 +--echo ~1 -> $not2 +--echo ~255 -> $not3 +--echo ~(-1) -> $not4 + +--echo # Basic left shift (<<) +let $lshift1 = $(1 << 3); +let $lshift2 = $(5 << 2); +let $lshift3 = $(8 << 1); +let $lshift4 = $(0 << 5); + +--echo 1 << 3 -> $lshift1 +--echo 5 << 2 -> $lshift2 +--echo 8 << 1 -> $lshift3 +--echo 0 << 5 -> $lshift4 + +--echo # Basic right shift (>>) +let $rshift1 = $(8 >> 3); +let $rshift2 = $(20 >> 2); +let $rshift3 = $(16 >> 1); +let $rshift4 = $(7 >> 3); + +--echo 8 >> 3 -> $rshift1 +--echo 20 >> 2 -> $rshift2 +--echo 16 >> 1 -> $rshift3 +--echo 7 >> 3 -> $rshift4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with hex and binary literals +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with hex literals +let $hex_and = $(0xFF & 0x0F); +let $hex_or = $(0xF0 | 0x0F); +let $hex_xor = $(0xFF ^ 0xAA); +let $hex_not = $(~0xFF); +let $hex_lshift = $(0x10 << 2); +let $hex_rshift = $(0x80 >> 4); + +--echo 0xFF & 0x0F -> $hex_and +--echo 0xF0 | 0x0F -> $hex_or +--echo 0xFF ^ 0xAA -> $hex_xor +--echo ~0xFF -> $hex_not +--echo 0x10 << 2 -> $hex_lshift +--echo 0x80 >> 4 -> $hex_rshift + +--echo # Bitwise operations with binary literals +let $bin_and = $(0b1100 & 0b1010); +let $bin_or = $(0b1000 | 0b0100); +let $bin_xor = $(0b1111 ^ 0b1010); +let $bin_not = $(~0b1111); +let $bin_lshift = $(0b101 << 2); +let $bin_rshift = $(0b10000 >> 2); + +--echo 0b1100 & 0b1010 -> $bin_and +--echo 0b1000 | 0b0100 -> $bin_or +--echo 0b1111 ^ 0b1010 -> $bin_xor +--echo ~0b1111 -> $bin_not +--echo 0b101 << 2 -> $bin_lshift +--echo 0b10000 >> 2 -> $bin_rshift + +--echo # ---------------------------------------------------------------------------- +--echo # Mixed base bitwise operations +--echo # ---------------------------------------------------------------------------- + +--echo # Mixed base bitwise operations +let $mixed_and = $(0xFF & 0b11110000); +let $mixed_or = $(0x0F | 0b11110000); +let $mixed_xor = $(255 ^ 0xAA); +let $mixed_shift1 = $(0b1000 << 0x2); +let $mixed_shift2 = $(0x40 >> 0b10); + +--echo 0xFF & 0b11110000 -> $mixed_and +--echo 0x0F | 0b11110000 -> $mixed_or +--echo 255 ^ 0xAA -> $mixed_xor +--echo 0b1000 << 0x2 -> $mixed_shift1 +--echo 0x40 >> 0b10 -> $mixed_shift2 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operator precedence +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operator precedence +let $prec1 = $(12 | 8 ^ 4); +let $prec2 = $(12 ^ 8 | 4); +let $prec3 = $(12 & 8 ^ 4); +let $prec4 = $(12 ^ 8 & 4); +let $prec5 = $(12 | 8 & 4); + +--echo 12 | 8 ^ 4 -> $prec1 +--echo 12 ^ 8 | 4 -> $prec2 +--echo 12 & 8 ^ 4 -> $prec3 +--echo 12 ^ 8 & 4 -> $prec4 +--echo 12 | 8 & 4 -> $prec5 + +--echo # Parentheses override bitwise precedence +let $paren1 = $((12 | 8) ^ 4); +let $paren2 = $(12 | (8 ^ 4)); +let $paren3 = $((12 & 8) | 4); +let $paren4 = $(12 & (8 | 4)); + +--echo (12 | 8) ^ 4 -> $paren1 +--echo 12 | (8 ^ 4) -> $paren2 +--echo (12 & 8) | 4 -> $paren3 +--echo 12 & (8 | 4) -> $paren4 + +--echo # ---------------------------------------------------------------------------- +--echo # Shift precedence with arithmetic operators +--echo # ---------------------------------------------------------------------------- + +--echo # Shift operators vs arithmetic +let $shift_arith1 = $(2 + 3 << 1); +let $shift_arith2 = $(8 >> 1 + 1); +let $shift_arith3 = $(4 * 2 << 2); +let $shift_arith4 = $(16 >> 2 * 1); + +--echo 2 + 3 << 1 -> $shift_arith1 +--echo 8 >> 1 + 1 -> $shift_arith2 +--echo 4 * 2 << 2 -> $shift_arith3 +--echo 16 >> 2 * 1 -> $shift_arith4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with negative numbers +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with negative numbers (unsigned interpretation) +let $neg_and = $(-1 & 15); +let $neg_or = $(-16 | 7); +let $neg_xor = $(-1 ^ 255); +let $neg_lshift = $(-10 << 3); +let $neg_rshift = $(-10 >> 3); + +--echo -1 & 15 -> $neg_and +--echo -16 | 7 -> $neg_or +--echo -1 ^ 255 -> $neg_xor +--echo -10 << 3 -> $neg_lshift +--echo -10 >> 3 -> $neg_rshift + +--echo # ---------------------------------------------------------------------------- +--echo # Complex bitwise expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex bitwise expressions +let $complex1 = $((0xFF & 0xF0) | (0x0F & 0x05)); +let $complex2 = $(~(~0xFF | 0x0F)); +let $complex3 = $((1 << 4) | (1 << 2) | (1 << 0)); +let $complex4 = $((255 >> 2) & (63 << 1)); + +--echo (0xFF & 0xF0) | (0x0F & 0x05) -> $complex1 +--echo ~(~0xFF | 0x0F) -> $complex2 +--echo (1 << 4) | (1 << 2) | (1 << 0) -> $complex3 +--echo (255 >> 2) & (63 << 1) -> $complex4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations in conditional expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations in conditions +if ($(15 & 8)) +{ + --echo 15 & 8 is true (result is 8, non-zero) +} + +if ($(12 ^ 12)) +{ + --echo This should not print - 12 ^ 12 is 0 +} + +if ($(!(12 ^ 12))) +{ + --echo !(12 ^ 12) is true +} + +if ($((1 << 5) == 32)) +{ + --echo 1 << 5 equals 32 +} + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with variables +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with variables +let $mask = 0xFF; +let $value = 0xAB; +let $shift_amount = 4; + +let $masked = $($value & $mask); +let $shifted_left = $($value << $shift_amount); +let $shifted_right = $($value >> $shift_amount); +let $inverted = $(~$value); + +--echo $value & $mask -> $masked +--echo $value << $shift_amount -> $shifted_left +--echo $value >> $shift_amount -> $shifted_right +--echo ~$value -> $inverted + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise error cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing bitwise error cases + +--echo # Shift by negative amount +--error 1 +--exec echo "let \$invalid_shift1= \$(5 << -1);" | $MYSQL_TEST 2>&1 + +--echo # Shift by too large amount (>= 64) +--error 1 +--exec echo "let \$invalid_shift2= \$(5 << 64);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$invalid_shift3= \$(100 >> 65);" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Edge cases for shift operations +--echo # ---------------------------------------------------------------------------- + +--echo # Edge cases for shift operations +let $edge_shift1 = $(1 << 0); +let $edge_shift2 = $(1 << 63); +let $edge_shift3 = $(8 >> 0); +let $edge_shift4 = $(1 >> 63); + +--echo 1 << 0 -> $edge_shift1 +--echo 1 << 63 -> $edge_shift2 +--echo 8 >> 0 -> $edge_shift3 +--echo 1 >> 63 -> $edge_shift4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with large numbers +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with large numbers +let $large_and = $(0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE); +let $large_or = $(0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE); +let $large_xor = $(0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE); + +--echo 0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE -> $large_and +--echo 0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE -> $large_or +--echo 0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE -> $large_xor + +--echo # ---------------------------------------------------------------------------- +--echo # Complex expressions with multiple operators +--echo # ---------------------------------------------------------------------------- + +--echo # Complex expressions +--echo 2 + 3 * 4 > 10 -> $(2 + 3 * 4 > 10) +--echo (5 + 5) == (2 * 5) -> $((5 + 5) == (2 * 5)) +--echo 1 + 2 + 3 + 4 == 10 -> $(1 + 2 + 3 + 4 == 10) +--echo 3 + 2 > 4 && 5 > 2 -> $(3 + 2 > 4 && 5 > 2) +--echo 2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2 -> $(2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2) +--echo 1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4 -> $(1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4) +--echo 4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2 -> $(4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2) +--echo 5 * 3 + 7 << 1 ^ 12 >> 2 -> $(5 * 3 + 7 << 1 ^ 12 >> 2) +--echo 8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2 -> $(8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2) +--echo (!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) -> $(!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) + +--echo # ---------------------------------------------------------------------------- +--echo # Error Handling (Syntax and Runtime) +--echo # ---------------------------------------------------------------------------- + +--echo # Test case: Empty unquoted string (illegal) +--error 1 +--exec echo "let \$a = \$();" | $MYSQL_TEST 2>&1 + +--echo # Test case: Empty unquoted string with only spaces (illegal) +--error 1 +--exec echo "let \$a = \$( );" | $MYSQL_TEST 2>&1 + +--echo # Test case: Unmatched parenthesis +--error 1 +--exec echo "let \$a = \$((1 + 2);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(((((((((1+3;" | $MYSQL_TEST 2>&1 + +--echo # Test case: Expression evaluator not the entire condition +--error 1 +--exec echo "if(\$(1 + 2) + 3) { echo 'error'; }" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a=3; if (\$a > \$(1 + 2)) { echo 'error'; }" | $MYSQL_TEST 2>&1 + +--echo # Test case: Division by zero +--error 1 +--exec echo "let \$a = \$(5 / 0);" | $MYSQL_TEST 2>&1 + +--echo # Test case: Modulo by zero +--error 1 +--exec echo "let \$a = \$(5 % 0);" | $MYSQL_TEST 2>&1 + +--echo # Test case: Overflow +--error 1 +--exec echo "let \$a = \$(18446744073709551616);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(-18446744073709551616);" | $MYSQL_TEST 2>&1 + +--echo # Expression evaluation tests completed successfully diff --git a/mysql-test/main/mysqltest_string_functions.result b/mysql-test/main/mysqltest_string_functions.result new file mode 100644 index 00000000000..e89fe942601 --- /dev/null +++ b/mysql-test/main/mysqltest_string_functions.result @@ -0,0 +1,1095 @@ +# ---------------------------------------------------------------------------- +# Test for MDEV-36108: Variable substitutions in mysqltest +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# Test conversion functions (conv, bin, oct, hex) +# ---------------------------------------------------------------------------- +# Basic conv() function tests +conv(10, 10, 2) -> 1010 +conv(255, 10, 16) -> FF +conv(FF, 16, 10) -> 255 +conv(1010, 2, 10) -> 10 +conv(64, 10, 8) -> 100 +conv(77, 8, 10) -> 63 +# ---------------------------------------------------------------------------- +# Test shortcut functions bin(), oct(), hex() +# ---------------------------------------------------------------------------- +# Testing bin() function +bin(10) -> 1010 +bin(255) -> 11111111 +bin(0) -> 0 +# Testing oct() function +oct(64) -> 100 +oct(512) -> 1000 +# Testing hex() function +hex(255) -> FF +hex(4095) -> FFF +# ---------------------------------------------------------------------------- +# Test extended base support (bases 2-62) +# ---------------------------------------------------------------------------- +# Testing extended bases +conv(ZZ, 36, 10) -> 1295 +conv(z, 62, 10) -> 61 +conv(Hello, 62, 10) -> 260914464 +# ---------------------------------------------------------------------------- +# Test signed vs unsigned interpretation +# ---------------------------------------------------------------------------- +# Testing signed vs unsigned interpretation +conv(-1, 10, 16) -> FFFFFFFFFFFFFFFF +conv(-1, 10, -16) -> -1 +conv(-10, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111110110 +conv(-10, 10, -2) -> -1010 +conv(-255, 10, 16) -> FFFFFFFFFFFFFF01 +conv(-255, 10, -16) -> -FF +conv(-1234, -10, 2) -> 1111111111111111111111111111111111111111111111111111101100101110 +conv(-1234, -10, -2) -> -10011010010 +# ---------------------------------------------------------------------------- +# Edge cases and boundary conditions +# ---------------------------------------------------------------------------- +# Testing edge cases and boundaries +conv(0, 10, 2) -> 0 +conv(0, 16, 10) -> 0 +conv(9223372036854775807, 10, 16) -> 7FFFFFFFFFFFFFFF +conv(~0, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111111111 +conv(7FFFFFFFFFFFFFFF, 16, 10) -> 9223372036854775807 +conv(777777777777777777777, 8, 10) -> 9223372036854775807 +conv(1111111111111111111111111111111111111111111111111111111111111111, 2, 10) -> 18446744073709551615 +conv(9223372036854775807, 10, 2) -> 111111111111111111111111111111111111111111111111111111111111111 +conv(18446744073709551615, 10, 16) -> FFFFFFFFFFFFFFFF +conv(18446744073709551615, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111111111 +conv(-~0, 10, 2) -> 1 +conv(0000123, 10, 16) -> 7B +# ---------------------------------------------------------------------------- +# Test case sensitivity in conversion +# ---------------------------------------------------------------------------- +# Testing case sensitivity +conv(AbCd, 16, 10) -> 43981 +conv(abcd, 16, 10) -> 43981 +conv(ABCD, 16, 10) -> 43981 +# ---------------------------------------------------------------------------- +# Test with variables and expressions +# ---------------------------------------------------------------------------- +# Testing with variables and expressions +conv(FF, 16, 10) -> 255 +# ---------------------------------------------------------------------------- +# Error cases - Invalid bases +# ---------------------------------------------------------------------------- +# Testing error cases - Invalid bases +# Base too small (< 2) +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 1 +# Base too large (> 62 for our parser, > 36 for MariaDB) +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 63 +# Zero base +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 0 +# ---------------------------------------------------------------------------- +# Error cases - Invalid characters for base +# ---------------------------------------------------------------------------- +# Testing error cases - Invalid characters +# Character not valid for base 8 +mysqltest: At line 1: invalid number '189' for base 8 +# Character not valid for base 16 +mysqltest: At line 1: invalid number 'XYZ' for base 16 +# Special characters +mysqltest: At line 1: invalid number '@#$' for base 36 +# ---------------------------------------------------------------------------- +# Error cases - Function argument count +# ---------------------------------------------------------------------------- +# Testing error cases - Wrong argument count +# Too few arguments for conv +mysqltest: At line 1: conv() expects 3 arguments (N, from_base, to_base), got 2 +# Too many arguments for conv +mysqltest: At line 1: conv() expects 3 arguments (N, from_base, to_base), got 4 +# Too many arguments for bin +mysqltest: At line 1: bin() expects 1 argument, got 2 +# No arguments for hex +mysqltest: At line 1: hex() expects 1 argument, got 0 +# ---------------------------------------------------------------------------- +# Overflow cases +# ---------------------------------------------------------------------------- +# Testing overflow cases +# Number too large for 64-bit +mysqltest: At line 1: Range error: 99999999999999999999999999999999 value out of range for Integer type +# Very long hex string that would cause overflow +mysqltest: At line 1: Range error: value out of range for Integer type +# ---------------------------------------------------------------------------- +# Test REPLACE function +# ---------------------------------------------------------------------------- +# Basic REPLACE function tests +replace("hello world", "world", "mariadb") -> "hello mariadb" +replace("hello hello hello", "hello", "hi") -> "hi hi hi" +replace("test string", "test", "") -> " string" +replace("no change", "missing", "replacement") -> "no change" +# ---------------------------------------------------------------------------- +# REPLACE with empty strings +# ---------------------------------------------------------------------------- +# REPLACE with empty strings +replace("hello world", "", "test") -> "hello world" +replace("hello world", "hello", "") -> " world" +replace("", "test", "replacement") -> "" +# ---------------------------------------------------------------------------- +# REPLACE with special characters +# ---------------------------------------------------------------------------- +# REPLACE with special characters +replace("a+b=c", "+", "-") -> "a-b=c" +replace("test\nstring", "\n", " ") -> "test string" +replace("quoted 'string'", "'", "") -> "quoted string" +replace('quoted "string"', '"', "") -> "quoted string" +# ---------------------------------------------------------------------------- +# REPLACE with variables +# ---------------------------------------------------------------------------- +# REPLACE with variables +replace("hello world", "world", "mariadb") -> "hello mariadb" +replace("test test test", "test", "mariadb") -> "mariadb mariadb mariadb" +# ---------------------------------------------------------------------------- +# REPLACE edge cases +# ---------------------------------------------------------------------------- +# REPLACE edge cases +replace("aaa", "aa", "b") -> "ba" +replace("aaaa", "aa", "b") -> "bb" +replace("test", "test", "test") -> "test" +replace("", "", "something") -> "" +# ---------------------------------------------------------------------------- +# Test SUBSTR function +# ---------------------------------------------------------------------------- +# SUBSTR function +substr("hello", -7, -7) -> "" +substr("hello", -7, -6) -> "" +substr("hello", -7, -5) -> "" +substr("hello", -7, -4) -> "" +substr("hello", -7, -3) -> "" +substr("hello", -7, -2) -> "" +substr("hello", -7, -1) -> "" +substr("hello", -7, 0) -> "" +substr("hello", -7, 1) -> "" +substr("hello", -7, 2) -> "" +substr("hello", -7, 3) -> "" +substr("hello", -7, 4) -> "" +substr("hello", -7, 5) -> "" +substr("hello", -7, 6) -> "" +substr("hello", -7, 7) -> "" +substr("hello", -6, -7) -> "" +substr("hello", -6, -6) -> "" +substr("hello", -6, -5) -> "" +substr("hello", -6, -4) -> "" +substr("hello", -6, -3) -> "" +substr("hello", -6, -2) -> "" +substr("hello", -6, -1) -> "" +substr("hello", -6, 0) -> "" +substr("hello", -6, 1) -> "" +substr("hello", -6, 2) -> "" +substr("hello", -6, 3) -> "" +substr("hello", -6, 4) -> "" +substr("hello", -6, 5) -> "" +substr("hello", -6, 6) -> "" +substr("hello", -6, 7) -> "" +substr("hello", -5, -7) -> "" +substr("hello", -5, -6) -> "" +substr("hello", -5, -5) -> "" +substr("hello", -5, -4) -> "" +substr("hello", -5, -3) -> "" +substr("hello", -5, -2) -> "" +substr("hello", -5, -1) -> "" +substr("hello", -5, 0) -> "" +substr("hello", -5, 1) -> "h" +substr("hello", -5, 2) -> "he" +substr("hello", -5, 3) -> "hel" +substr("hello", -5, 4) -> "hell" +substr("hello", -5, 5) -> "hello" +substr("hello", -5, 6) -> "hello" +substr("hello", -5, 7) -> "hello" +substr("hello", -4, -7) -> "" +substr("hello", -4, -6) -> "" +substr("hello", -4, -5) -> "" +substr("hello", -4, -4) -> "" +substr("hello", -4, -3) -> "" +substr("hello", -4, -2) -> "" +substr("hello", -4, -1) -> "" +substr("hello", -4, 0) -> "" +substr("hello", -4, 1) -> "e" +substr("hello", -4, 2) -> "el" +substr("hello", -4, 3) -> "ell" +substr("hello", -4, 4) -> "ello" +substr("hello", -4, 5) -> "ello" +substr("hello", -4, 6) -> "ello" +substr("hello", -4, 7) -> "ello" +substr("hello", -3, -7) -> "" +substr("hello", -3, -6) -> "" +substr("hello", -3, -5) -> "" +substr("hello", -3, -4) -> "" +substr("hello", -3, -3) -> "" +substr("hello", -3, -2) -> "" +substr("hello", -3, -1) -> "" +substr("hello", -3, 0) -> "" +substr("hello", -3, 1) -> "l" +substr("hello", -3, 2) -> "ll" +substr("hello", -3, 3) -> "llo" +substr("hello", -3, 4) -> "llo" +substr("hello", -3, 5) -> "llo" +substr("hello", -3, 6) -> "llo" +substr("hello", -3, 7) -> "llo" +substr("hello", -2, -7) -> "" +substr("hello", -2, -6) -> "" +substr("hello", -2, -5) -> "" +substr("hello", -2, -4) -> "" +substr("hello", -2, -3) -> "" +substr("hello", -2, -2) -> "" +substr("hello", -2, -1) -> "" +substr("hello", -2, 0) -> "" +substr("hello", -2, 1) -> "l" +substr("hello", -2, 2) -> "lo" +substr("hello", -2, 3) -> "lo" +substr("hello", -2, 4) -> "lo" +substr("hello", -2, 5) -> "lo" +substr("hello", -2, 6) -> "lo" +substr("hello", -2, 7) -> "lo" +substr("hello", -1, -7) -> "" +substr("hello", -1, -6) -> "" +substr("hello", -1, -5) -> "" +substr("hello", -1, -4) -> "" +substr("hello", -1, -3) -> "" +substr("hello", -1, -2) -> "" +substr("hello", -1, -1) -> "" +substr("hello", -1, 0) -> "" +substr("hello", -1, 1) -> "o" +substr("hello", -1, 2) -> "o" +substr("hello", -1, 3) -> "o" +substr("hello", -1, 4) -> "o" +substr("hello", -1, 5) -> "o" +substr("hello", -1, 6) -> "o" +substr("hello", -1, 7) -> "o" +substr("hello", 0, -7) -> "" +substr("hello", 0, -6) -> "" +substr("hello", 0, -5) -> "" +substr("hello", 0, -4) -> "" +substr("hello", 0, -3) -> "" +substr("hello", 0, -2) -> "" +substr("hello", 0, -1) -> "" +substr("hello", 0, 0) -> "" +substr("hello", 0, 1) -> "" +substr("hello", 0, 2) -> "" +substr("hello", 0, 3) -> "" +substr("hello", 0, 4) -> "" +substr("hello", 0, 5) -> "" +substr("hello", 0, 6) -> "" +substr("hello", 0, 7) -> "" +substr("hello", 1, -7) -> "" +substr("hello", 1, -6) -> "" +substr("hello", 1, -5) -> "" +substr("hello", 1, -4) -> "" +substr("hello", 1, -3) -> "" +substr("hello", 1, -2) -> "" +substr("hello", 1, -1) -> "" +substr("hello", 1, 0) -> "" +substr("hello", 1, 1) -> "h" +substr("hello", 1, 2) -> "he" +substr("hello", 1, 3) -> "hel" +substr("hello", 1, 4) -> "hell" +substr("hello", 1, 5) -> "hello" +substr("hello", 1, 6) -> "hello" +substr("hello", 1, 7) -> "hello" +substr("hello", 2, -7) -> "" +substr("hello", 2, -6) -> "" +substr("hello", 2, -5) -> "" +substr("hello", 2, -4) -> "" +substr("hello", 2, -3) -> "" +substr("hello", 2, -2) -> "" +substr("hello", 2, -1) -> "" +substr("hello", 2, 0) -> "" +substr("hello", 2, 1) -> "e" +substr("hello", 2, 2) -> "el" +substr("hello", 2, 3) -> "ell" +substr("hello", 2, 4) -> "ello" +substr("hello", 2, 5) -> "ello" +substr("hello", 2, 6) -> "ello" +substr("hello", 2, 7) -> "ello" +substr("hello", 3, -7) -> "" +substr("hello", 3, -6) -> "" +substr("hello", 3, -5) -> "" +substr("hello", 3, -4) -> "" +substr("hello", 3, -3) -> "" +substr("hello", 3, -2) -> "" +substr("hello", 3, -1) -> "" +substr("hello", 3, 0) -> "" +substr("hello", 3, 1) -> "l" +substr("hello", 3, 2) -> "ll" +substr("hello", 3, 3) -> "llo" +substr("hello", 3, 4) -> "llo" +substr("hello", 3, 5) -> "llo" +substr("hello", 3, 6) -> "llo" +substr("hello", 3, 7) -> "llo" +substr("hello", 4, -7) -> "" +substr("hello", 4, -6) -> "" +substr("hello", 4, -5) -> "" +substr("hello", 4, -4) -> "" +substr("hello", 4, -3) -> "" +substr("hello", 4, -2) -> "" +substr("hello", 4, -1) -> "" +substr("hello", 4, 0) -> "" +substr("hello", 4, 1) -> "l" +substr("hello", 4, 2) -> "lo" +substr("hello", 4, 3) -> "lo" +substr("hello", 4, 4) -> "lo" +substr("hello", 4, 5) -> "lo" +substr("hello", 4, 6) -> "lo" +substr("hello", 4, 7) -> "lo" +substr("hello", 5, -7) -> "" +substr("hello", 5, -6) -> "" +substr("hello", 5, -5) -> "" +substr("hello", 5, -4) -> "" +substr("hello", 5, -3) -> "" +substr("hello", 5, -2) -> "" +substr("hello", 5, -1) -> "" +substr("hello", 5, 0) -> "" +substr("hello", 5, 1) -> "o" +substr("hello", 5, 2) -> "o" +substr("hello", 5, 3) -> "o" +substr("hello", 5, 4) -> "o" +substr("hello", 5, 5) -> "o" +substr("hello", 5, 6) -> "o" +substr("hello", 5, 7) -> "o" +substr("hello", 6, -7) -> "" +substr("hello", 6, -6) -> "" +substr("hello", 6, -5) -> "" +substr("hello", 6, -4) -> "" +substr("hello", 6, -3) -> "" +substr("hello", 6, -2) -> "" +substr("hello", 6, -1) -> "" +substr("hello", 6, 0) -> "" +substr("hello", 6, 1) -> "" +substr("hello", 6, 2) -> "" +substr("hello", 6, 3) -> "" +substr("hello", 6, 4) -> "" +substr("hello", 6, 5) -> "" +substr("hello", 6, 6) -> "" +substr("hello", 6, 7) -> "" +substr("hello", 7, -7) -> "" +substr("hello", 7, -6) -> "" +substr("hello", 7, -5) -> "" +substr("hello", 7, -4) -> "" +substr("hello", 7, -3) -> "" +substr("hello", 7, -2) -> "" +substr("hello", 7, -1) -> "" +substr("hello", 7, 0) -> "" +substr("hello", 7, 1) -> "" +substr("hello", 7, 2) -> "" +substr("hello", 7, 3) -> "" +substr("hello", 7, 4) -> "" +substr("hello", 7, 5) -> "" +substr("hello", 7, 6) -> "" +substr("hello", 7, 7) -> "" +substr("hello world", 1, 5) -> "hello" +substr("hello world", 7) -> "world" +substr("hello world", 1, 3) -> "hel" +substr("hello world", 7, 5) -> "world" +# ---------------------------------------------------------------------------- +# SUBSTR with negative indices +# ---------------------------------------------------------------------------- +# SUBSTR with negative indices +substr("hello world", -5) -> "world" +substr("hello world", -5, 3) -> "wor" +substr("hello world", -10, 5) -> "ello " +substr("hello world", -20) -> "" +# ---------------------------------------------------------------------------- +# SUBSTR boundary conditions +# ---------------------------------------------------------------------------- +# SUBSTR boundary conditions +substr("hello world", 1, 0) -> "" +substr("hello world", 1, 20) -> "hello world" +substr("hello world", 12) -> "" +substr("hello world", 0) -> "" +substr("hello world", 0, 5) -> "" +# ---------------------------------------------------------------------------- +# SUBSTR with variables +# ---------------------------------------------------------------------------- +# SUBSTR with variables +substr("hello world", 7, 5) -> "world" +substr("hello world", -5) -> "world" +# ---------------------------------------------------------------------------- +# SUBSTR edge cases +# ---------------------------------------------------------------------------- +# SUBSTR edge cases +substr("", 1) -> "" +substr("a", 1, 5) -> "a" +substr("hello", 1, -1) -> "" +substr("hello", 5, 1) -> "o" +# ---------------------------------------------------------------------------- +# Combined function tests +# ---------------------------------------------------------------------------- +# Combined function tests +replace(substr("hello world", 1, 5), "hello", "hi") -> "hi" +substr(replace("hello world", "world", "mariadb"), 7) -> "mariadb" +replace(substr("test test test", 1, 9), "test", "check") -> "check check" +upper(replace("hello world", "world", "mariadb")) -> "HELLO MARIADB" +length(trim(replace(" hello world ", "world", "mariadb"))) -> "13" +instr(lower("HELLO WORLD"), "world") -> 7 +locate(upper("o"), upper("hello world")) -> 5 +reverse(substr(upper("hello world"), 1, 5)) -> "OLLEH" +# ---------------------------------------------------------------------------- +# String functions in while loops +# ---------------------------------------------------------------------------- +# String functions in while loops +Character at position 1: h (upper: H, lower: h) +Character at position 2: e (upper: E, lower: e) +Character at position 3: l (upper: L, lower: l) +Character at position 4: l (upper: L, lower: l) +Character at position 5: o (upper: O, lower: o) +# String processing with multiple functions +Original: "HelloWorld" -> Processed: HeLLoWoRLD +# ---------------------------------------------------------------------------- +# Error cases for REPLACE function +# ---------------------------------------------------------------------------- +# Testing error cases for REPLACE function +# Wrong number of arguments +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 1 +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 2 +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 4 +# Wrong argument types +mysqltest: At line 1: replace() arguments must be strings +mysqltest: At line 1: replace() arguments must be strings +mysqltest: At line 1: replace() arguments must be strings +# ---------------------------------------------------------------------------- +# Error cases for SUBSTR function +# ---------------------------------------------------------------------------- +# Testing error cases for SUBSTR function +# Wrong number of arguments +mysqltest: At line 1: substr() expects 2 or 3 arguments (str, start [, length]), got 1 +mysqltest: At line 1: substr() expects 2 or 3 arguments (str, start [, length]), got 4 +# Wrong argument types +mysqltest: At line 1: substr() first argument must be a string +mysqltest: At line 1: substr() start position must be numeric +mysqltest: At line 1: substr() length must be numeric +# Expression evaluation tests completed successfully +# ---------------------------------------------------------------------------- +# Basic INSTR function tests +# ---------------------------------------------------------------------------- +# Basic INSTR function tests +instr("hello world", "world") -> 7 +instr("hello world", "hello") -> 1 +instr("hello world", "o") -> 5 +instr("hello world", "xyz") -> 0 +instr("hello world", "") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with single characters +# ---------------------------------------------------------------------------- +# INSTR with single characters +instr("hello", "h") -> 1 +instr("hello", "e") -> 2 +instr("hello", "l") -> 3 +instr("hello", "o") -> 5 +instr("hello", "x") -> 0 +# ---------------------------------------------------------------------------- +# INSTR with repeated characters +# ---------------------------------------------------------------------------- +# INSTR with repeated characters +instr("hello", "l") -> 3 +instr("hello hello", "hello") -> 1 +instr("aaa", "aa") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with empty strings +# ---------------------------------------------------------------------------- +# INSTR with empty strings +instr("", "hello") -> 0 +instr("hello", "") -> 1 +instr("", "") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with special characters +# ---------------------------------------------------------------------------- +# INSTR with special characters +instr("a+b=c", "+") -> 2 +instr("test\nstring", "\n") -> 5 +instr("quoted 'string'", "'") -> 8 +instr('quoted "string"', '"') -> 8 +instr("test@example.com", "@") -> 5 +# ---------------------------------------------------------------------------- +# INSTR with variables +# ---------------------------------------------------------------------------- +# INSTR with variables +instr("hello world", "world") -> 7 +instr("hello world", "o") -> 5 +# ---------------------------------------------------------------------------- +# INSTR edge cases +# ---------------------------------------------------------------------------- +# INSTR edge cases +instr("hello", "hello") -> 1 +instr("hello", "hellox") -> 0 +instr("hello", "h") -> 1 +instr("hello", "o") -> 5 +instr("a", "a") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with case sensitivity +# ---------------------------------------------------------------------------- +# INSTR with case sensitivity +instr("Hello World", "hello") -> 1 +instr("Hello World", "HELLO") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with whitespace +# ---------------------------------------------------------------------------- +# INSTR with whitespace +instr("hello world", " ") -> 6 +instr(" hello ", "hello") -> 3 +instr("hello world", " ") -> 6 +instr("hello\tworld", "\t") -> 6 +# ---------------------------------------------------------------------------- +# INSTR with complex expressions +# ---------------------------------------------------------------------------- +# INSTR with complex expressions +instr("hello world", substr("world test", 1, 5)) -> 7 +instr(replace("hello world", "world", "mariadb"), "mariadb") -> 7 +# ---------------------------------------------------------------------------- +# INSTR with arithmetic expressions +# ---------------------------------------------------------------------------- +# INSTR with arithmetic expressions +instr("hello world", "world") + 5 -> 12 +instr("hello world", "hello") * 2 -> 2 +# ---------------------------------------------------------------------------- +# INSTR with logical operators +# ---------------------------------------------------------------------------- +# INSTR with logical operators +instr("hello world", "hello") > 0 && instr("hello world", "world") > 0 -> 1 +instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0 -> 1 +# ---------------------------------------------------------------------------- +# INSTR integration with other functions +# ---------------------------------------------------------------------------- +# INSTR integration with other functions +instr("hello world", substr("world test", 1, 5)) -> 7 +instr(replace("hello world", "world", "mariadb"), "mariadb") -> 7 +# ---------------------------------------------------------------------------- +# INSTR error cases +# ---------------------------------------------------------------------------- +# Testing error cases for INSTR function +# Wrong number of arguments +mysqltest: At line 1: instr() expects 2 arguments (str, substr), got 1 +mysqltest: The test didn't produce any output +# Wrong argument types +mysqltest: The test didn't produce any output +mysqltest: The test didn't produce any output +# ---------------------------------------------------------------------------- +# Test LOCATE function +# ---------------------------------------------------------------------------- +# LOCATE function tests +locate('world', 'hello world') -> 7 +locate('o', 'hello world') -> 5 +locate('o', 'hello world', 6) -> 8 +locate('xyz', 'hello world') -> 0 +locate('', 'hello world') -> 1 +locate('hello', '') -> 0 +locate('', '') -> 1 +locate('l', 'hello world', 1) -> 3 +locate('l', 'hello world', 4) -> 4 +locate('l', 'hello world', 10) -> 10 +# ---------------------------------------------------------------------------- +# LOCATE with empty strings +# ---------------------------------------------------------------------------- +# LOCATE with empty strings +locate('', 'hello world') -> 1 +locate('hello', '') -> 0 +locate('', '') -> 1 +# ---------------------------------------------------------------------------- +# LOCATE with special characters +# ---------------------------------------------------------------------------- +# LOCATE with special characters +locate('+', 'a+b=c') -> 2 +locate('@', 'test@example.com') -> 5 +locate('.', 'file.txt') -> 5 +# ---------------------------------------------------------------------------- +# LOCATE with variables +# ---------------------------------------------------------------------------- +# LOCATE with variables +locate("world", "hello world") -> 7 +locate('o', "hello world", 6) -> 8 +# ---------------------------------------------------------------------------- +# LOCATE edge cases +# ---------------------------------------------------------------------------- +# LOCATE edge cases +locate('hello', 'hello world') -> 1 +locate('world', 'hello world') -> 7 +locate('xyz', 'hello world') -> 0 +locate('o', 'hello world', 1) -> 5 +locate('o', 'hello world', 20) -> 0 +# ---------------------------------------------------------------------------- +# Error cases for LOCATE function +# ---------------------------------------------------------------------------- +# Testing error cases for LOCATE function +# Wrong number of arguments +mysqltest: At line 1: locate() expects 2 or 3 arguments (substr, str [, start]), got 1 +mysqltest: At line 1: locate() expects 2 or 3 arguments (substr, str [, start]), got 4 +# Wrong argument types +mysqltest: The test didn't produce any output +mysqltest: The test didn't produce any output +mysqltest: At line 1: locate() start position must be numeric +# ---------------------------------------------------------------------------- +# Test LOWER function +# ---------------------------------------------------------------------------- +# LOWER function tests +lower('HELLO WORLD') -> hello world +lower('Hello World') -> hello world +lower('hello world') -> hello world +lower('ABC123') -> abc123 +lower('') -> +lower('MIXED Case 123') -> mixed case 123 +lower('SPECIAL@#$%') -> special@#$% +# ---------------------------------------------------------------------------- +# LOWER with empty strings +# ---------------------------------------------------------------------------- +# LOWER with empty strings +lower('') -> +# ---------------------------------------------------------------------------- +# LOWER with special characters +# ---------------------------------------------------------------------------- +# LOWER with special characters +lower('TEST@EXAMPLE.COM') -> test@example.com +lower('FILE.TXT') -> file.txt +lower('HELLO-WORLD_123') -> hello-world_123 +# ---------------------------------------------------------------------------- +# LOWER with variables +# ---------------------------------------------------------------------------- +# LOWER with variables +lower("HELLO WORLD") -> hello world +# ---------------------------------------------------------------------------- +# LOWER edge cases +# ---------------------------------------------------------------------------- +# LOWER edge cases +lower('A') -> a +lower('a') -> a +lower('123') -> 123 +lower('MiXeD cAsE') -> mixed case +# ---------------------------------------------------------------------------- +# Test UPPER function +# ---------------------------------------------------------------------------- +# UPPER function tests +upper('hello world') -> HELLO WORLD +upper('Hello World') -> HELLO WORLD +upper('HELLO WORLD') -> HELLO WORLD +upper('abc123') -> ABC123 +upper('') -> +upper('mixed case 123') -> MIXED CASE 123 +upper('special@#$%') -> SPECIAL@#$% +# ---------------------------------------------------------------------------- +# UPPER with empty strings +# ---------------------------------------------------------------------------- +# UPPER with empty strings +upper('') -> +# ---------------------------------------------------------------------------- +# UPPER with special characters +# ---------------------------------------------------------------------------- +# UPPER with special characters +upper('test@example.com') -> TEST@EXAMPLE.COM +upper('file.txt') -> FILE.TXT +upper('hello-world_123') -> HELLO-WORLD_123 +# ---------------------------------------------------------------------------- +# UPPER with variables +# ---------------------------------------------------------------------------- +# UPPER with variables +upper("hello world") -> HELLO WORLD +# ---------------------------------------------------------------------------- +# UPPER edge cases +# ---------------------------------------------------------------------------- +# UPPER edge cases +upper('a') -> A +upper('A') -> A +upper('123') -> 123 +upper('MiXeD cAsE') -> MIXED CASE +# ---------------------------------------------------------------------------- +# Test REVERSE function +# ---------------------------------------------------------------------------- +# REVERSE function tests +reverse('hello') -> olleh +reverse('hello world') -> dlrow olleh +reverse('12345') -> 54321 +reverse('') -> +reverse('a') -> a +reverse('ab') -> ba +reverse('ABC123') -> 321CBA +# ---------------------------------------------------------------------------- +# Test TRIM function +# ---------------------------------------------------------------------------- +# TRIM function tests +trim(' hello world ') -> hello world +trim('hello world') -> hello world +trim(' ') -> +trim('') -> +trim(' hello') -> hello +trim('hello ') -> hello +trim(' hello world ') -> hello world +# ---------------------------------------------------------------------------- +# Test LTRIM function +# ---------------------------------------------------------------------------- +# LTRIM function tests +ltrim(' hello world') -> hello world +ltrim('hello world') -> hello world +ltrim(' ') -> +ltrim('') -> +ltrim(' hello world') -> hello world +ltrim('hello world') -> hello world +ltrim(' hello') -> hello +# ---------------------------------------------------------------------------- +# Test RTRIM function +# ---------------------------------------------------------------------------- +# RTRIM function tests +rtrim('hello world ') -> hello world +rtrim('hello world') -> hello world +rtrim(' ') -> +rtrim('') -> +rtrim(' hello world ') -> hello world +rtrim('hello world') -> hello world +rtrim('hello ') -> hello +# ---------------------------------------------------------------------------- +# Test LPAD function +# ---------------------------------------------------------------------------- +# LPAD function tests +lpad('hello', 10, '*') -> *****hello +lpad('hello', 5, '*') -> hello +lpad('hello', 3, '*') -> hel +lpad('hello', 10, ' ') -> hello +lpad('', 5, '*') -> ***** +lpad('hello', 10, 'ab') -> ababahello +lpad('hello', 0, '*') -> +# ---------------------------------------------------------------------------- +# Test RPAD function +# ---------------------------------------------------------------------------- +# RPAD function tests +rpad('hello', 10, '*') -> hello***** +rpad('hello', 5, '*') -> hello +rpad('hello', 3, '*') -> hel +rpad('hello', 10, ' ') -> hello +rpad('', 5, '*') -> ***** +rpad('hello', 10, 'ab') -> helloababa +rpad('hello', 0, '*') -> +# ---------------------------------------------------------------------------- +# Test LENGTH function +# ---------------------------------------------------------------------------- +# LENGTH function tests +length('hello') -> 5 +length('hello world') -> 11 +length('') -> 0 +length('12345') -> 5 +length(' hello ') -> 9 +length('a') -> 1 +length('special@#$%') -> 11 +# ---------------------------------------------------------------------------- +# Test special characters and Latin characters +# ---------------------------------------------------------------------------- +# Special characters and Latin characters tests +length('Björn') -> 6 +upper('björn') -> BJöRN +lower('BJÖRN') -> bjã–rn +reverse('Björn') -> nr¶ÃjB +locate('ö', 'Björn') -> 3 +substr('Björn', 1, 3) -> Bjà +trim(' Björn ') -> Björn +concat('Björn', ' ', 'Müller') -> Björn Müller +replace('Björn Müller', 'Müller', 'Schmidt') -> Björn Schmidt +instr('Björn Müller', 'Müller') -> 8 +lpad('Björn', 10, '*') -> ****Björn +rpad('Björn', 10, '*') -> Björn**** +length('KhÃ¥led Rïyad') -> 14 +upper('josé maría') -> JOSé MARíA +substr('José María', 1, 4) -> Josà +# ---------------------------------------------------------------------------- +# Test special characters and symbols +# ---------------------------------------------------------------------------- +# Special characters and symbols tests +concat('path', '/', 'to', '/', 'file.txt') -> path/to/file.txt +instr('user@domain.com', 'domain.com') -> 6 +length('path/to/file.txt') -> 16 +locate('.', 'file.txt') -> 5 +locate('/', 'path/to/file.txt') -> 5 +upper('test@example.com') -> TEST@EXAMPLE.COM +lower('TEST@EXAMPLE.COM') -> test@example.com +lpad('file', 8, '.') -> ....file +rpad('path', 10, '/') -> path////// +replace('file.txt', 'txt', 'doc') -> file.doc +replace('path/to/file.txt', 'file.txt', 'document.doc') -> path/to/document.doc +reverse('path/to/file.txt') -> txt.elif/ot/htap +substr('path/to/file.txt', 1, 4) -> path +trim(' path/to/file.txt ') -> path/to/file.txt +# ---------------------------------------------------------------------------- +# Test complex combinations of string functions +# ---------------------------------------------------------------------------- +# Complex string function combinations +length(trim(' hello world ')) -> 11 +upper(lower('MiXeD CaSe')) -> MIXED CASE +reverse(lpad('hi', 5, '*')) -> ih*** +locate('o', upper('hello world')) -> 5 +substr(trim(' hello world '), 1, 5) -> hello +length(concat('hello', ' ', 'world')) -> 11 +reverse(upper('hello')) -> OLLEH +lpad(rtrim('hello '), 10, '*') -> *****hello +least(length('hello'), length('world'), length('test')) -> 4 +greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o')) -> 7 +repeat(upper(substr('hello', 1, 2)), 3) -> HEHEHE +insert(lower('HELLO WORLD'), 7, 5, upper('mariadb')) -> hello MARIADB +concat_ws('-', upper('hello'), lower('WORLD'), reverse('test')) -> HELLO-world-tset +ifnull(nullif(trim(' hello '), 'hello'), 'default') -> default +coalesce(nullif('test', 'test'), upper('backup')) -> BACKUP +substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2) -> www.mariadb +# ---------------------------------------------------------------------------- +# Test CONCAT function +# ---------------------------------------------------------------------------- +# Basic CONCAT function tests +concat('a','b','c') -> abc +concat(42, 'a') -> 42a +concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a') -> 123456789101a +concat('') -> +concat('Ã¥', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'Å‚', 'Å›', 'ż', 'ź', 'ć') -> åñçüéößæøîëäïôàùêâýþðłśżźć +concat('', 1) -> 1 +# ---------------------------------------------------------------------------- +# Test SUBSTRING_INDEX function +# ---------------------------------------------------------------------------- +# SUBSTRING_INDEX function tests +substring_index('www.mariadb.org', '.', 2) -> www.mariadb +substring_index('www.mariadb.org', '.', -2) -> mariadb.org +substring_index('www.mariadb.org', '.', 0) -> +substring_index('www.mariadb.org', '', 1) -> +substring_index('www.mariadb.org', '', -1) -> +substring_index('mariadb', '.', 0) -> +substring_index('mariadb', '.', -1) -> mariadb +substring_index('mariadb', '.', 1) -> mariadb +substring_index('mariadb', 'A', 1) -> mariadb +substring_index('mariadb', 'A', -1) -> mariadb +substring_index('mariadb', 'A', 0) -> +substring_index('mariadb', 'z', 2) -> mariadb +substring_index('', 'z', -2) -> +substring_index('mariadb', 'ar', 0) -> +# ---------------------------------------------------------------------------- +# Test REGEXP_INSTR function +# ---------------------------------------------------------------------------- +# REGEXP_INSTR function tests +regexp_instr('abc','b') -> 2 +regexp_instr('abc','x') -> 0 +regexp_instr('abc','') -> 1 +regexp_instr('','a') -> 0 +regexp_instr('','') -> 1 +regexp_instr('BJÖRN','N') -> 6 +regexp_instr('ABC','(?-i)b') -> 0 +regexp_instr('ABC','(?i)b') -> 2 +# ---------------------------------------------------------------------------- +# Test REGEXP_SUBSTR function +# ---------------------------------------------------------------------------- +# REGEXP_SUBSTR function tests +regexp_substr('ab12cd','[0-9]+') -> 12 +regexp_substr('ab12cd','') -> +regexp_substr('abcd','[0-9]+') -> +regexp_substr('','[0-9]+') -> +regexp_substr('','') -> +regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*') -> https://mariadb.org +regexp_substr('ABC','b') -> B +regexp_substr('ABC','(?i)b') -> B +# ---------------------------------------------------------------------------- +# Test REGEXP_REPLACE function +# ---------------------------------------------------------------------------- +# REGEXP_REPLACE function tests +regexp_replace('ABC','b','x') -> AxC +regexp_replace('ab12cd','[0-9]','') -> abcd +regexp_replace('titlebody', '<.+?>',' ') -> title body +regexp_replace('James Bond','^(.*) (.*)$','\2, \1') -> Bond, James +regexp_replace('ABC','b','-') -> A-C +regexp_replace('ABC','(?-i)b','-') -> ABC +regexp_replace('ABC','(?i)b','-') -> A-C +regexp_replace('ABC','b','') -> AC +regexp_replace('ABC','(?-i)b','') -> ABC +regexp_replace('ABC','','') -> ABC +regexp_replace('ABC','','A') -> ABC +regexp_replace('','.','x') -> +regexp_replace('ABC','b','$') -> A$C +regexp_replace('ABC','b','$A') -> A$AC +regexp_replace('ABCC','C$','D') -> ABCD +regexp_replace('ABC$','\$','D') -> ABCD +# ---------------------------------------------------------------------------- +# Test LEAST function +# ---------------------------------------------------------------------------- +# LEAST function tests +least(1, 2, 3) -> 1 +least('a', 'b', 'c') -> a +least(NULL, 1, 2) -> +least(NULL, NULL, NULL) -> +least('a', 1, 'b') -> 0 +least(1, 'a', 'b') -> 0 +least('z', '-2', 'a') -> -2 +least('z', -2, 'a') -> -2 +least(' -4a', -1, 'b') -> -4 +least(' ', 10, 'b') -> 0 +least(' -0 ', 10, 'b') -> 0 +least('', 10, '-b') -> 0 +least(18446744073709551615, 18446744073709551614, 18446744073709551613) -> 18446744073709551613 +least(18446744073709551615, -1, 18446744073709551613) -> -1 +# ---------------------------------------------------------------------------- +# Test GREATEST function +# ---------------------------------------------------------------------------- +# GREATEST function tests +greatest(1, 2, 3) -> 3 +greatest('a', 'b', 'c') -> c +greatest(NULL, 1, 2) -> +greatest(NULL, NULL, NULL) -> +greatest('a', 1, 'b') -> 1 +greatest(1, 'a', 'b') -> 1 +greatest('z', '-2', 'a') -> z +greatest('z', -2, 'a') -> 0 +greatest(' -4a', -1, 'b') -> 0 +greatest(' ', 10, 'b') -> 10 +greatest(' -0 ', 10, 'b') -> 10 +greatest('', 10, '-b') -> 10 +greatest(18446744073709551615, 18446744073709551614, 18446744073709551613) -> 18446744073709551615 +greatest(18446744073709551615, -1, 18446744073709551613) -> 18446744073709551615 +greatest(3.14, 2.71, 3.15) -> 3.15 +greatest(-10, -5, -20) -> -5 +greatest('apple', 'banana', 'cherry') -> cherry +greatest('100', '20', '3') -> 3 +# ---------------------------------------------------------------------------- +# Test REPEAT function +# ---------------------------------------------------------------------------- +# REPEAT function tests +repeat('MariaDB ',4) -> MariaDB MariaDB MariaDB MariaDB +repeat('a', 0) -> +repeat('a', 1) -> a +repeat('', 0) -> +repeat('a', -1) -> +repeat('a', 18446744073709551615) -> +repeat('', 4) -> +repeat('', -1) -> +repeat('a32423413', 10) -> a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413 +# ---------------------------------------------------------------------------- +# Test NULLIF function +# ---------------------------------------------------------------------------- +# NULLIF function tests +nullif('a', 'a') -> +nullif('a', 'b') -> a +nullif('a', NULL) -> a +nullif(NULL, 'a') -> +nullif(NULL, NULL) -> +# ---------------------------------------------------------------------------- +# Test COALESCE function +# ---------------------------------------------------------------------------- +# COALESCE function tests +coalesce(NULL, 'a') -> a +coalesce(NULL, NULL) -> +coalesce(NULL, 'a', 'b') -> a +coalesce('a', 'b', 'c') -> a +coalesce('a', NULL, 'b') -> a +coalesce(NULL, NULL, 'a') -> a +coalesce(NULL, NULL, NULL) -> +coalesce(NULL, 'a', NULL, 'b') -> a +# ---------------------------------------------------------------------------- +# Test IFNULL function +# ---------------------------------------------------------------------------- +# IFNULL function tests +ifnull(NULL, 'a') -> a +ifnull('a', NULL) -> a +ifnull(NULL, NULL) -> +ifnull('a', 'b') -> a +ifnull('a', 'a') -> a +# ---------------------------------------------------------------------------- +# Test INSERT function +# ---------------------------------------------------------------------------- +# INSERT function tests +insert('Hello World', 2, 3, 'Xyz') -> HXyzo World +insert('Hello World', 2, 3, '') -> Ho World +insert('Hello World', 2, 3, NULL) -> +insert('Hello World', 0, 0, 'Xyz') -> Hello World +insert('Hello World', 0, 0, '') -> Hello World +insert('Quadratic', 3, 4, 'What') -> QuWhattic +insert('Quadratic', -1, 4, 'What') -> Quadratic +insert('Quadratic', 3, 100, 'What') -> QuWhat +insert('Quadratic', -32, -100, 'wow') -> Quadratic +insert('Quadratic', 32, 100, 'wow') -> Quadratic +insert('Quadratic', 1, 8, 'wow') -> wowc +insert('Quadratic', 1, 1000, 'wow') -> wow +insert('Quadratic', 4, 2, 'wow') -> Quawowatic +insert('Quadratic', 4, 2, '') -> Quaatic +insert('', 4, 2, 'wow') -> +insert('Quadratic', 4, -2, 'wow') -> Quawow +insert('Quadratic', 4, 0, 'wow') -> Quawowdratic +# ---------------------------------------------------------------------------- +# Test CONCAT_WS function +# ---------------------------------------------------------------------------- +# CONCAT_WS function tests +concat_ws('-', 'a', 'b', 'c') -> a-b-c +concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z') -> a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z +concat_ws(' ,', 'a') -> a +concat_ws('', 'abc', 'def', 'ghi') -> abcdefghi +concat_ws('', 'abc') -> abc +concat_ws('&', 'abc') -> abc +concat_ws(' ,', '') -> +concat_ws('&', 'abc', NULL) -> abc +concat_ws('...', 'abc', NULL, 'def') -> abc...def +concat_ws(NULL, 'abc', NULL, 'def') -> +# ---------------------------------------------------------------------------- +# Test functions with variables +# ---------------------------------------------------------------------------- +# Functions with variables +least('test string', 'string') -> string +greatest('test string', 'string') -> test string +repeat('string', 3) -> stringstringstring +insert('test string', 5, 6, 'value') -> testvalueg +concat_ws(' ', 'test string', 'string', 'value') -> test string string value +ifnull(NULL, 'value') -> value +coalesce(NULL, NULL, 'value') -> value +nullif('test string', 'string') -> test string +# ---------------------------------------------------------------------------- +# Test functions with special characters +# ---------------------------------------------------------------------------- +# Functions with special characters +least('Björn', 'Müller', 'Schmidt') -> Björn +greatest('Björn', 'Müller', 'Schmidt') -> Schmidt +repeat('ö', 5) -> ööööö +insert('Björn Müller', 7, 6, 'Schmidt') -> BjörnSchmidter +concat_ws(' ', 'José', 'María', 'González') -> José María González +ifnull(NULL, 'François') -> François +coalesce(NULL, 'HÃ¥kon', 'Olsen') -> HÃ¥kon +nullif('test@example.com', 'user@domain.com') -> test@example.com +# ---------------------------------------------------------------------------- +# Test functions with mixed data types +# ---------------------------------------------------------------------------- +# Functions with mixed data types +least(123, 'abc', 456) -> 0 +greatest(123, 'abc', 456) -> 456 +repeat('test', 3) -> testtesttest +insert('test123', 5, 3, 'ABC') -> testABC +concat_ws('-', 'prefix', 123, 'suffix') -> prefix-123-suffix +ifnull(123, 'fallback') -> 123 +coalesce(NULL, 456, 'backup') -> 456 +nullif(123, 456) -> 123 +# ---------------------------------------------------------------------------- +# Test functions in complex expressions +# ---------------------------------------------------------------------------- +# Functions in complex expressions +least(1, 2, 3) + 10 -> 11 +greatest(1, 2, 3) * 5 -> 15 +length(repeat('ab', 4)) -> 8 +upper(insert('hello world', 7, 5, 'mariadb')) -> HELLO MARIADB +length(concat_ws(' ', 'hello', 'world', 'test')) -> 16 +ifnull(NULL, 'default') == 'default' -> 1 +coalesce(NULL, NULL, 'found') != 'missing' -> 1 +nullif('same', 'same') -> +# ---------------------------------------------------------------------------- +# Test functions in conditional expressions +# ---------------------------------------------------------------------------- +# Functions in conditional expressions +least returns minimum value correctly +greatest returns maximum value correctly +repeat with count 0 returns empty string +CONCAT_WS joins with separator correctly +ifnull returns first value when not NULL +coalesce returns first non-NULL value +nullif returns first value when values differ +# ---------------------------------------------------------------------------- +# Test functions with arithmetic in arguments +# ---------------------------------------------------------------------------- +# Functions with arithmetic in arguments +least(1+2, 2*2, 3+1) -> 3 +greatest(1+2, 2*2, 3+1) -> 4 +repeat('x', 2+3) -> xxxxx +insert('hello', 1+1, 2*1, 'hi') -> hhilo +insert('testing', 2, 3, 'xyz') -> txyzing +# ---------------------------------------------------------------------------- +# Test nested function calls +# ---------------------------------------------------------------------------- +# Nested function calls +least(length('hello'), length('world'), length('test')) -> 4 +greatest(length('hello'), length('world'), length('test')) -> 5 +repeat(upper('ab'), 3) -> ABABAB +insert(upper('hello world'), 7, 5, lower('MARIADB')) -> HELLO mariadb +concat_ws(' ', upper('hello'), lower('WORLD')) -> HELLO world +ifnull(nullif('same', 'same'), 'default') -> default +coalesce(nullif('test', 'test'), 'backup') -> backup +# Expression evaluation string functions tests completed successfully diff --git a/mysql-test/main/mysqltest_string_functions.test b/mysql-test/main/mysqltest_string_functions.test new file mode 100644 index 00000000000..0c38c1e32f9 --- /dev/null +++ b/mysql-test/main/mysqltest_string_functions.test @@ -0,0 +1,2056 @@ +--echo # ---------------------------------------------------------------------------- +--echo # Test for MDEV-36108: Variable substitutions in mysqltest +--echo # ---------------------------------------------------------------------------- + +--source include/not_embedded.inc + +--echo # ---------------------------------------------------------------------------- +--echo # Test conversion functions (conv, bin, oct, hex) +--echo # ---------------------------------------------------------------------------- + +--echo # Basic conv() function tests + +let $result1 = $(conv(10, 10, 2)); +--echo conv(10, 10, 2) -> $result1 + +let $result2 = $(conv(255, 10, 16)); +--echo conv(255, 10, 16) -> $result2 + +let $result3 = $(conv(FF, 16, 10)); +--echo conv(FF, 16, 10) -> $result3 + +let $result4 = $(conv(1010, 2, 10)); +--echo conv(1010, 2, 10) -> $result4 + +let $result5 = $(conv(64, 10, 8)); +--echo conv(64, 10, 8) -> $result5 + +let $result6 = $(conv(77, 8, 10)); +--echo conv(77, 8, 10) -> $result6 + +--echo # ---------------------------------------------------------------------------- +--echo # Test shortcut functions bin(), oct(), hex() +--echo # ---------------------------------------------------------------------------- + +--echo # Testing bin() function + +let $bin1 = $(bin(10)); +--echo bin(10) -> $bin1 + +let $bin2 = $(bin(255)); +--echo bin(255) -> $bin2 + +let $bin3 = $(bin(0)); +--echo bin(0) -> $bin3 + +--echo # Testing oct() function + +let $oct1 = $(oct(64)); +--echo oct(64) -> $oct1 + +let $oct2 = $(oct(512)); +--echo oct(512) -> $oct2 + +--echo # Testing hex() function + +let $hex1 = $(hex(255)); +--echo hex(255) -> $hex1 + +let $hex2 = $(hex(4095)); +--echo hex(4095) -> $hex2 + +--echo # ---------------------------------------------------------------------------- +--echo # Test extended base support (bases 2-62) +--echo # ---------------------------------------------------------------------------- + +--echo # Testing extended bases + +let $base36 = $(conv(ZZ, 36, 10)); +--echo conv(ZZ, 36, 10) -> $base36 + +let $base62_1 = $(conv(z, 62, 10)); +--echo conv(z, 62, 10) -> $base62_1 + +let $base62_2 = $(conv(Hello, 62, 10)); +--echo conv(Hello, 62, 10) -> $base62_2 + +--echo # ---------------------------------------------------------------------------- +--echo # Test signed vs unsigned interpretation +--echo # ---------------------------------------------------------------------------- + +--echo # Testing signed vs unsigned interpretation + +let $unsigned1 = $(conv(-1, 10, 16)); +--echo conv(-1, 10, 16) -> $unsigned1 + +let $signed1 = $(conv(-1, 10, -16)); +--echo conv(-1, 10, -16) -> $signed1 + +let $unsigned2 = $(conv(-10, 10, 2)); +--echo conv(-10, 10, 2) -> $unsigned2 + +let $signed2 = $(conv(-10, 10, -2)); +--echo conv(-10, 10, -2) -> $signed2 + +let $unsigned3 = $(conv(-255, 10, 16)); +--echo conv(-255, 10, 16) -> $unsigned3 + +let $signed3 = $(conv(-255, 10, -16)); +--echo conv(-255, 10, -16) -> $signed3 + +let $signed4 = $(conv(-1234, -10, 2)); +--echo conv(-1234, -10, 2) -> $signed4 + +let $signed5 = $(conv(-1234, -10, -2)); +--echo conv(-1234, -10, -2) -> $signed5 + +--echo # ---------------------------------------------------------------------------- +--echo # Edge cases and boundary conditions +--echo # ---------------------------------------------------------------------------- + +--echo # Testing edge cases and boundaries + +let $zero1 = $(conv(0, 10, 2)); +--echo conv(0, 10, 2) -> $zero1 + +let $zero2 = $(conv(0, 16, 10)); +--echo conv(0, 16, 10) -> $zero2 + +let $max1 = $(conv(9223372036854775807, 10, 16)); +--echo conv(9223372036854775807, 10, 16) -> $max1 + +let $max2 = $(conv(~0, 10, 2)); +--echo conv(~0, 10, 2) -> $max2 + +let $large1 = $(conv(7FFFFFFFFFFFFFFF, 16, 10)); +--echo conv(7FFFFFFFFFFFFFFF, 16, 10) -> $large1 + +let $large2 = $(conv('777777777777777777777', 8, 10)); +--echo conv(777777777777777777777, 8, 10) -> $large2 + +let $large3 = $(conv('1111111111111111111111111111111111111111111111111111111111111111', 2, 10)); +--echo conv(1111111111111111111111111111111111111111111111111111111111111111, 2, 10) -> $large3 + +let $large4 = $(conv('9223372036854775807', 10, 2)); +--echo conv(9223372036854775807, 10, 2) -> $large4 + +let $large5 = $(conv('18446744073709551615', 10, 16)); +--echo conv(18446744073709551615, 10, 16) -> $large5 + +let $large6 = $(conv('18446744073709551615', 10, 2)); +--echo conv(18446744073709551615, 10, 2) -> $large6 + +let $min1 = $(conv(-~0, 10, 2)); +--echo conv(-~0, 10, 2) -> $min1 + +let $leading1 = $(conv(0000123, 10, 16)); +--echo conv(0000123, 10, 16) -> $leading1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test case sensitivity in conversion +--echo # ---------------------------------------------------------------------------- + +--echo # Testing case sensitivity + +let $case1 = $(conv(AbCd, 16, 10)); +--echo conv(AbCd, 16, 10) -> $case1 + +let $case2 = $(conv(abcd, 16, 10)); +--echo conv(abcd, 16, 10) -> $case2 + +let $case3 = $(conv(ABCD, 16, 10)); +--echo conv(ABCD, 16, 10) -> $case3 + +--echo # ---------------------------------------------------------------------------- +--echo # Test with variables and expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Testing with variables and expressions + +let $base_var = 16; +let $value_var = FF; +let $target_base = 10; + +let $var_result = $(conv($value_var, $base_var, $target_base)); +--echo conv($value_var, $base_var, $target_base) -> $var_result + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Invalid bases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Invalid bases + +--echo # Base too small (< 2) +--error 1 +--exec echo "let \$invalid1= \$(conv(123, 1, 10));" | $MYSQL_TEST 2>&1 + +--echo # Base too large (> 62 for our parser, > 36 for MariaDB) +--error 1 +--exec echo "let \$invalid2= \$(conv(123, 63, 10));" | $MYSQL_TEST 2>&1 + +--echo # Zero base +--error 1 +--exec echo "let \$invalid3= \$(conv(123, 0, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Invalid characters for base +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Invalid characters + +--echo # Character not valid for base 8 +--error 1 +--exec echo "let \$invalid5= \$(conv(189, 8, 10));" | $MYSQL_TEST 2>&1 + +--echo # Character not valid for base 16 +--error 1 +--exec echo "let \$invalid6= \$(conv(XYZ, 16, 10));" | $MYSQL_TEST 2>&1 + +--echo # Special characters +--error 1 +--exec echo "let \$invalid7= \$(conv(@#\\\$, 36, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Function argument count +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Wrong argument count + +--echo # Too few arguments for conv +--error 1 +--exec echo "let \$invalid8= \$(conv(123, 10));" | $MYSQL_TEST 2>&1 + +--echo # Too many arguments for conv +--error 1 +--exec echo "let \$invalid9= \$(conv(123, 10, 16, 2));" | $MYSQL_TEST 2>&1 + +--echo # Too many arguments for bin +--error 1 +--exec echo "let \$invalid10= \$(bin(123, 456));" | $MYSQL_TEST 2>&1 + +--echo # No arguments for hex +--error 1 +--exec echo "let \$invalid11= \$(hex());" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Overflow cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing overflow cases + +--echo # Number too large for 64-bit +--error 1 +--exec echo "let \$overflow1= \$(conv(99999999999999999999999999999999, 10, 16));" | $MYSQL_TEST 2>&1 + +--echo # Very long hex string that would cause overflow +--error 1 +--exec echo "let \$overflow2= \$(conv(FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 16, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # Basic REPLACE function tests + +let $replace1 = $(replace("hello world", "world", "mariadb")); +--echo replace("hello world", "world", "mariadb") -> "$replace1" + +let $replace2 = $(replace("hello hello hello", "hello", "hi")); +--echo replace("hello hello hello", "hello", "hi") -> "$replace2" + +let $replace3 = $(replace("test string", "test", "")); +--echo replace("test string", "test", "") -> "$replace3" + +let $replace4 = $(replace("no change", "missing", "replacement")); +--echo replace("no change", "missing", "replacement") -> "$replace4" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with empty strings + +let $empty1 = $(replace("hello world", "", "test")); +--echo replace("hello world", "", "test") -> "$empty1" + +let $empty2 = $(replace("hello world", "hello", "")); +--echo replace("hello world", "hello", "") -> "$empty2" + +let $empty3 = $(replace("", "test", "replacement")); +--echo replace("", "test", "replacement") -> "$empty3" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with special characters + +let $special1 = $(replace("a+b=c", "+", "-")); +--echo replace("a+b=c", "+", "-") -> "$special1" + +let $special2 = $(replace("test\\nstring", "\\n", " ")); +--echo replace("test\\nstring", "\\n", " ") -> "$special2" + +let $special3 = $(replace("quoted 'string'", "'", "")); +--echo replace("quoted 'string'", "'", "") -> "$special3" + +let $special4 = $(replace('quoted "string"', '"', "")); +--echo replace('quoted "string"', '"', "") -> "$special4" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with variables +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with variables + +let $text = "hello world"; +let $search = "world"; +let $replacement = "mariadb"; +let $var_result = $(replace($text, $search, $replacement)); +--echo replace($text, $search, $replacement) -> "$var_result" + +let $multi_var = $(replace("test test test", "test", $replacement)); +--echo replace("test test test", "test", $replacement) -> "$multi_var" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE edge cases + +let $edge1 = $(replace("aaa", "aa", "b")); +--echo replace("aaa", "aa", "b") -> "$edge1" + +let $edge2 = $(replace("aaaa", "aa", "b")); +--echo replace("aaaa", "aa", "b") -> "$edge2" + +let $edge3 = $(replace("test", "test", "test")); +--echo replace("test", "test", "test") -> "$edge3" + +let $edge4 = $(replace("", "", "something")); +--echo replace("", "", "something") -> "$edge4" + +--echo # ---------------------------------------------------------------------------- +--echo # Test SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR function + +let $str = "hello"; + +let $from = -7; +while ($from <= 7) +{ + let $to = -7; + while ($to <= 7) + { + let $result = $(substr($str, $from, $to)); + --echo substr("hello", $from, $to) -> "$result" + --inc $to + } + --inc $from +} + +let $substr1 = $(substr("hello world", 1, 5)); +--echo substr("hello world", 1, 5) -> "$substr1" + +let $substr2 = $(substr("hello world", 7)); +--echo substr("hello world", 7) -> "$substr2" + +let $substr3 = $(substr("hello world", 1, 3)); +--echo substr("hello world", 1, 3) -> "$substr3" + +let $substr4 = $(substr("hello world", 7, 5)); +--echo substr("hello world", 7, 5) -> "$substr4" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR with negative indices +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR with negative indices + +let $neg1 = $(substr("hello world", -5)); +--echo substr("hello world", -5) -> "$neg1" + +let $neg2 = $(substr("hello world", -5, 3)); +--echo substr("hello world", -5, 3) -> "$neg2" + +let $neg3 = $(substr("hello world", -10, 5)); +--echo substr("hello world", -10, 5) -> "$neg3" + +let $neg4 = $(substr("hello world", -20)); +--echo substr("hello world", -20) -> "$neg4" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR boundary conditions +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR boundary conditions + +let $bound1 = $(substr("hello world", 1, 0)); +--echo substr("hello world", 1, 0) -> "$bound1" + +let $bound2 = $(substr("hello world", 1, 20)); +--echo substr("hello world", 1, 20) -> "$bound2" + +let $bound3 = $(substr("hello world", 12)); +--echo substr("hello world", 12) -> "$bound3" + +let $bound4 = $(substr("hello world", 0)); +--echo substr("hello world", 0) -> "$bound4" + +let $bound5 = $(substr("hello world", 0, 5)); +--echo substr("hello world", 0, 5) -> "$bound5" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR with variables +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR with variables + +let $text_var = "hello world"; +let $start_var = 7; +let $len_var = 5; +let $var_substr = $(substr($text_var, $start_var, $len_var)); +--echo substr($text_var, $start_var, $len_var) -> "$var_substr" + +let $neg_var = $(substr($text_var, -5)); +--echo substr($text_var, -5) -> "$neg_var" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR edge cases + +let $edge_substr1 = $(substr("", 1)); +--echo substr("", 1) -> "$edge_substr1" + +let $edge_substr2 = $(substr("a", 1, 5)); +--echo substr("a", 1, 5) -> "$edge_substr2" + +let $edge_substr3 = $(substr("hello", 1, -1)); +--echo substr("hello", 1, -1) -> "$edge_substr3" + +let $edge_substr4 = $(substr("hello", 5, 1)); +--echo substr("hello", 5, 1) -> "$edge_substr4" + +--echo # ---------------------------------------------------------------------------- +--echo # Combined function tests +--echo # ---------------------------------------------------------------------------- + +--echo # Combined function tests + +let $combined1 = $(replace(substr("hello world", 1, 5), "hello", "hi")); +--echo replace(substr("hello world", 1, 5), "hello", "hi") -> "$combined1" + +let $combined2 = $(substr(replace("hello world", "world", "mariadb"), 7)); +--echo substr(replace("hello world", "world", "mariadb"), 7) -> "$combined2" + +let $combined3 = $(replace(substr("test test test", 1, 9), "test", "check")); +--echo replace(substr("test test test", 1, 9), "test", "check") -> "$combined3" + +let $combined4 = $(upper(replace("hello world", "world", "mariadb"))); +--echo upper(replace("hello world", "world", "mariadb")) -> "$combined4" + +let $combined5 = $(length(trim(replace(" hello world ", "world", "mariadb")))); +--echo length(trim(replace(" hello world ", "world", "mariadb"))) -> "$combined5" + +let $combined6 = $(instr(lower("HELLO WORLD"), "world")); +--echo instr(lower("HELLO WORLD"), "world") -> $combined6 + +let $combined7 = $(locate(upper("o"), upper("hello world"))); +--echo locate(upper("o"), upper("hello world")) -> $combined7 + +let $combined8 = $(reverse(substr(upper("hello world"), 1, 5))); +--echo reverse(substr(upper("hello world"), 1, 5)) -> "$combined8" + + +--echo # ---------------------------------------------------------------------------- +--echo # String functions in while loops +--echo # ---------------------------------------------------------------------------- + +--echo # String functions in while loops +let $counter = 1; +let $text_loop = "hello world"; +while ($(substr($text_loop, $counter, 1))) +{ + let $char = $(substr($text_loop, $counter, 1)); + --echo Character at position $counter: $char (upper: $(upper($char)), lower: $(lower($char))) + --inc $counter +} + +--echo # String processing with multiple functions +let $input_text = "HelloWorld"; +let $pos = 1; +let $total_length = $(length($input_text)); +let $processed = ""; +while ($pos <= $total_length) +{ + let $current_char = $(substr($input_text, $pos, 1)); + if ($(instr("AEIOU", upper($current_char)))) + { + let $processed = $(concat($processed, lower($current_char))); + } + if (!$(instr("AEIOU", upper($current_char)))) + { + let $processed = $(concat($processed, upper($current_char))); + } + --inc $pos +} +--echo Original: $input_text -> Processed: $processed + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for REPLACE function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(replace('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(replace('hello', 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error3= \$(replace('hello', 'world', 'test', 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error4= \$(replace(123, 'world', 'test'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error5= \$(replace('hello', 456, 'test'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error6= \$(replace('hello', 'world', 789));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for SUBSTR function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error7= \$(substr('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error8= \$(substr('hello', 1, 2, 3));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error9= \$(substr(123, 1, 2));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error10= \$(substr('hello', 'world', 2));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error11= \$(substr('hello', 1, 'world'));" | $MYSQL_TEST 2>&1 + +--echo # Expression evaluation tests completed successfully + +--echo # ---------------------------------------------------------------------------- +--echo # Basic INSTR function tests +--echo # ---------------------------------------------------------------------------- + +--echo # Basic INSTR function tests + +let $instr1 = $(instr("hello world", "world")); +--echo instr("hello world", "world") -> $instr1 + +let $instr2 = $(instr("hello world", "hello")); +--echo instr("hello world", "hello") -> $instr2 + +let $instr3 = $(instr("hello world", "o")); +--echo instr("hello world", "o") -> $instr3 + +let $instr4 = $(instr("hello world", "xyz")); +--echo instr("hello world", "xyz") -> $instr4 + +let $instr5 = $(instr("hello world", "")); +--echo instr("hello world", "") -> $instr5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with single characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with single characters +let $instr_char1 = $(instr("hello", "h")); +--echo instr("hello", "h") -> $instr_char1 + +let $instr_char2 = $(instr("hello", "e")); +--echo instr("hello", "e") -> $instr_char2 + +let $instr_char3 = $(instr("hello", "l")); +--echo instr("hello", "l") -> $instr_char3 + +let $instr_char4 = $(instr("hello", "o")); +--echo instr("hello", "o") -> $instr_char4 + +let $instr_char5 = $(instr("hello", "x")); +--echo instr("hello", "x") -> $instr_char5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with repeated characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with repeated characters +let $instr_repeat1 = $(instr("hello", "l")); +--echo instr("hello", "l") -> $instr_repeat1 + +let $instr_repeat2 = $(instr("hello hello", "hello")); +--echo instr("hello hello", "hello") -> $instr_repeat2 + +let $instr_repeat3 = $(instr("aaa", "aa")); +--echo instr("aaa", "aa") -> $instr_repeat3 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with empty strings +let $instr_empty1 = $(instr("", "hello")); +--echo instr("", "hello") -> $instr_empty1 + +let $instr_empty2 = $(instr("hello", "")); +--echo instr("hello", "") -> $instr_empty2 + +let $instr_empty3 = $(instr("", "")); +--echo instr("", "") -> $instr_empty3 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with special characters +let $instr_special1 = $(instr("a+b=c", "+")); +--echo instr("a+b=c", "+") -> $instr_special1 + +let $instr_special2 = $(instr("test\\nstring", "\\n")); +--echo instr("test\\nstring", "\\n") -> $instr_special2 + +let $instr_special3 = $(instr("quoted 'string'", "'")); +--echo instr("quoted 'string'", "'") -> $instr_special3 + +let $instr_special4 = $(instr('quoted "string"', '"')); +--echo instr('quoted "string"', '"') -> $instr_special4 + +let $instr_special5 = $(instr("test@example.com", "@")); +--echo instr("test@example.com", "@") -> $instr_special5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with variables +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with variables +let $text = "hello world"; +let $search = "world"; +let $instr_var_result = $(instr($text, $search)); +--echo instr($text, $search) -> $instr_var_result + +let $char_var = "o"; +let $instr_char_result = $(instr($text, $char_var)); +--echo instr($text, $char_var) -> $instr_char_result + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR edge cases +let $instr_edge1 = $(instr("hello", "hello")); +--echo instr("hello", "hello") -> $instr_edge1 + +let $instr_edge2 = $(instr("hello", "hellox")); +--echo instr("hello", "hellox") -> $instr_edge2 + +let $instr_edge3 = $(instr("hello", "h")); +--echo instr("hello", "h") -> $instr_edge3 + +let $instr_edge4 = $(instr("hello", "o")); +--echo instr("hello", "o") -> $instr_edge4 + +let $instr_edge5 = $(instr("a", "a")); +--echo instr("a", "a") -> $instr_edge5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with case sensitivity +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with case sensitivity +let $case1 = $(instr("Hello World", "hello")); +--echo instr("Hello World", "hello") -> $case1 + +let $case2 = $(instr("Hello World", "HELLO")); +--echo instr("Hello World", "HELLO") -> $case2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with whitespace +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with whitespace +let $space1 = $(instr("hello world", " ")); +--echo instr("hello world", " ") -> $space1 + +let $space2 = $(instr(" hello ", "hello")); +--echo instr(" hello ", "hello") -> $space2 + +let $space3 = $(instr("hello world", " ")); +--echo instr("hello world", " ") -> $space3 + +let $space4 = $(instr("hello\tworld", "\t")); +--echo instr("hello\tworld", "\t") -> $space4 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with complex expressions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with complex expressions +let $complex1 = $(instr("hello world", substr("world test", 1, 5))); +--echo instr("hello world", substr("world test", 1, 5)) -> $complex1 + +let $complex2 = $(instr(replace("hello world", "world", "mariadb"), "mariadb")); +--echo instr(replace("hello world", "world", "mariadb"), "mariadb") -> $complex2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with arithmetic expressions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with arithmetic expressions +let $arith1 = $(instr("hello world", "world") + 5); +--echo instr("hello world", "world") + 5 -> $arith1 + +let $arith2 = $(instr("hello world", "hello") * 2); +--echo instr("hello world", "hello") * 2 -> $arith2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with logical operators +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with logical operators +let $logical1 = $(instr("hello world", "hello") > 0 && instr("hello world", "world") > 0); +--echo instr("hello world", "hello") > 0 && instr("hello world", "world") > 0 -> $logical1 + +let $logical2 = $(instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0); +--echo instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0 -> $logical2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR integration with other functions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR integration with other functions + +let $instr_complex1 = $(instr("hello world", substr("world test", 1, 5))); +--echo instr("hello world", substr("world test", 1, 5)) -> $instr_complex1 + +let $instr_complex2 = $(instr(replace("hello world", "world", "mariadb"), "mariadb")); +--echo instr(replace("hello world", "world", "mariadb"), "mariadb") -> $instr_complex2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR error cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for INSTR function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(instr('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(instr('hello', 'world', 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error3= \$(instr(123, 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error4= \$(instr('hello', 456));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LOCATE function +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE function tests +let $loc1 = $(locate('world', 'hello world')); +--echo locate('world', 'hello world') -> $loc1 + +let $loc2 = $(locate('o', 'hello world')); +--echo locate('o', 'hello world') -> $loc2 + +let $loc3 = $(locate('o', 'hello world', 6)); +--echo locate('o', 'hello world', 6) -> $loc3 + +let $loc4 = $(locate('xyz', 'hello world')); +--echo locate('xyz', 'hello world') -> $loc4 + +let $loc5 = $(locate('', 'hello world')); +--echo locate('', 'hello world') -> $loc5 + +let $loc6 = $(locate('hello', '')); +--echo locate('hello', '') -> $loc6 + +let $loc7 = $(locate('', '')); +--echo locate('', '') -> $loc7 + +let $loc8 = $(locate('l', 'hello world', 1)); +--echo locate('l', 'hello world', 1) -> $loc8 + +let $loc9 = $(locate('l', 'hello world', 4)); +--echo locate('l', 'hello world', 4) -> $loc9 + +let $loc10 = $(locate('l', 'hello world', 10)); +--echo locate('l', 'hello world', 10) -> $loc10 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with empty strings +let $locate_empty1 = $(locate('', 'hello world')); +--echo locate('', 'hello world') -> $locate_empty1 + +let $locate_empty2 = $(locate('hello', '')); +--echo locate('hello', '') -> $locate_empty2 + +let $locate_empty3 = $(locate('', '')); +--echo locate('', '') -> $locate_empty3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with special characters +let $locate_special1 = $(locate('+', 'a+b=c')); +--echo locate('+', 'a+b=c') -> $locate_special1 + +let $locate_special2 = $(locate('@', 'test@example.com')); +--echo locate('@', 'test@example.com') -> $locate_special2 + +let $locate_special3 = $(locate('.', 'file.txt')); +--echo locate('.', 'file.txt') -> $locate_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with variables +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with variables +let $locate_text = "hello world"; +let $locate_search = "world"; +let $locate_var_result = $(locate($locate_search, $locate_text)); +--echo locate($locate_search, $locate_text) -> $locate_var_result + +let $locate_pos = 6; +let $locate_var_pos = $(locate('o', $locate_text, $locate_pos)); +--echo locate('o', $locate_text, $locate_pos) -> $locate_var_pos + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE edge cases +let $locate_edge1 = $(locate('hello', 'hello world')); +--echo locate('hello', 'hello world') -> $locate_edge1 + +let $locate_edge2 = $(locate('world', 'hello world')); +--echo locate('world', 'hello world') -> $locate_edge2 + +let $locate_edge3 = $(locate('xyz', 'hello world')); +--echo locate('xyz', 'hello world') -> $locate_edge3 + +let $locate_edge4 = $(locate('o', 'hello world', 1)); +--echo locate('o', 'hello world', 1) -> $locate_edge4 + +let $locate_edge5 = $(locate('o', 'hello world', 20)); +--echo locate('o', 'hello world', 20) -> $locate_edge5 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for LOCATE function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for LOCATE function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(locate('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(locate('hello', 'world', 1, 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error3= \$(locate(123, 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error4= \$(locate('hello', 456));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error5= \$(locate('hello', 'world', 'invalid'));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LOWER function +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER function tests +let $low1 = $(lower('HELLO WORLD')); +--echo lower('HELLO WORLD') -> $low1 + +let $low2 = $(lower('Hello World')); +--echo lower('Hello World') -> $low2 + +let $low3 = $(lower('hello world')); +--echo lower('hello world') -> $low3 + +let $low4 = $(lower('ABC123')); +--echo lower('ABC123') -> $low4 + +let $low5 = $(lower('')); +--echo lower('') -> $low5 + +let $low6 = $(lower('MIXED Case 123')); +--echo lower('MIXED Case 123') -> $low6 + +let $low7 = $(lower('SPECIAL@#\$%')); +--echo lower('SPECIAL@#\$%') -> $low7 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with empty strings +let $lower_empty1 = $(lower('')); +--echo lower('') -> $lower_empty1 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with special characters +let $lower_special1 = $(lower('TEST@EXAMPLE.COM')); +--echo lower('TEST@EXAMPLE.COM') -> $lower_special1 + +let $lower_special2 = $(lower('FILE.TXT')); +--echo lower('FILE.TXT') -> $lower_special2 + +let $lower_special3 = $(lower('HELLO-WORLD_123')); +--echo lower('HELLO-WORLD_123') -> $lower_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with variables +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with variables +let $lower_text = "HELLO WORLD"; +let $lower_var_result = $(lower($lower_text)); +--echo lower($lower_text) -> $lower_var_result + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER edge cases +let $lower_edge1 = $(lower('A')); +--echo lower('A') -> $lower_edge1 + +let $lower_edge2 = $(lower('a')); +--echo lower('a') -> $lower_edge2 + +let $lower_edge3 = $(lower('123')); +--echo lower('123') -> $lower_edge3 + +let $lower_edge4 = $(lower('MiXeD cAsE')); +--echo lower('MiXeD cAsE') -> $lower_edge4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test UPPER function +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER function tests +let $up1 = $(upper('hello world')); +--echo upper('hello world') -> $up1 + +let $up2 = $(upper('Hello World')); +--echo upper('Hello World') -> $up2 + +let $up3 = $(upper('HELLO WORLD')); +--echo upper('HELLO WORLD') -> $up3 + +let $up4 = $(upper('abc123')); +--echo upper('abc123') -> $up4 + +let $up5 = $(upper('')); +--echo upper('') -> $up5 + +let $up6 = $(upper('mixed case 123')); +--echo upper('mixed case 123') -> $up6 + +let $up7 = $(upper('special@#\$%')); +--echo upper('special@#\$%') -> $up7 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with empty strings +let $upper_empty1 = $(upper('')); +--echo upper('') -> $upper_empty1 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with special characters +let $upper_special1 = $(upper('test@example.com')); +--echo upper('test@example.com') -> $upper_special1 + +let $upper_special2 = $(upper('file.txt')); +--echo upper('file.txt') -> $upper_special2 + +let $upper_special3 = $(upper('hello-world_123')); +--echo upper('hello-world_123') -> $upper_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with variables +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with variables +let $upper_text = "hello world"; +let $upper_var_result = $(upper($upper_text)); +--echo upper($upper_text) -> $upper_var_result + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER edge cases +let $upper_edge1 = $(upper('a')); +--echo upper('a') -> $upper_edge1 + +let $upper_edge2 = $(upper('A')); +--echo upper('A') -> $upper_edge2 + +let $upper_edge3 = $(upper('123')); +--echo upper('123') -> $upper_edge3 + +let $upper_edge4 = $(upper('MiXeD cAsE')); +--echo upper('MiXeD cAsE') -> $upper_edge4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REVERSE function +--echo # ---------------------------------------------------------------------------- + +--echo # REVERSE function tests +let $rev1 = $(reverse('hello')); +--echo reverse('hello') -> $rev1 + +let $rev2 = $(reverse('hello world')); +--echo reverse('hello world') -> $rev2 + +let $rev3 = $(reverse('12345')); +--echo reverse('12345') -> $rev3 + +let $rev4 = $(reverse('')); +--echo reverse('') -> $rev4 + +let $rev5 = $(reverse('a')); +--echo reverse('a') -> $rev5 + +let $rev6 = $(reverse('ab')); +--echo reverse('ab') -> $rev6 + +let $rev7 = $(reverse('ABC123')); +--echo reverse('ABC123') -> $rev7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test TRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # TRIM function tests +let $trim1 = $(trim(' hello world ')); +--echo trim(' hello world ') -> $trim1 + +let $trim2 = $(trim('hello world')); +--echo trim('hello world') -> $trim2 + +let $trim3 = $(trim(' ')); +--echo trim(' ') -> $trim3 + +let $trim4 = $(trim('')); +--echo trim('') -> $trim4 + +let $trim5 = $(trim(' hello')); +--echo trim(' hello') -> $trim5 + +let $trim6 = $(trim('hello ')); +--echo trim('hello ') -> $trim6 + +let $trim7 = $(trim(' hello world ')); +--echo trim(' hello world ') -> $trim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LTRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # LTRIM function tests +let $ltrim1 = $(ltrim(' hello world')); +--echo ltrim(' hello world') -> $ltrim1 + +let $ltrim2 = $(ltrim('hello world')); +--echo ltrim('hello world') -> $ltrim2 + +let $ltrim3 = $(ltrim(' ')); +--echo ltrim(' ') -> $ltrim3 + +let $ltrim4 = $(ltrim('')); +--echo ltrim('') -> $ltrim4 + +let $ltrim5 = $(ltrim(' hello world')); +--echo ltrim(' hello world') -> $ltrim5 + +let $ltrim6 = $(ltrim('hello world')); +--echo ltrim('hello world') -> $ltrim6 + +let $ltrim7 = $(ltrim(' hello')); +--echo ltrim(' hello') -> $ltrim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test RTRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # RTRIM function tests +let $rtrim1 = $(rtrim('hello world ')); +--echo rtrim('hello world ') -> $rtrim1 + +let $rtrim2 = $(rtrim('hello world')); +--echo rtrim('hello world') -> $rtrim2 + +let $rtrim3 = $(rtrim(' ')); +--echo rtrim(' ') -> $rtrim3 + +let $rtrim4 = $(rtrim('')); +--echo rtrim('') -> $rtrim4 + +let $rtrim5 = $(rtrim(' hello world ')); +--echo rtrim(' hello world ') -> $rtrim5 + +let $rtrim6 = $(rtrim('hello world')); +--echo rtrim('hello world') -> $rtrim6 + +let $rtrim7 = $(rtrim('hello ')); +--echo rtrim('hello ') -> $rtrim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LPAD function +--echo # ---------------------------------------------------------------------------- + +--echo # LPAD function tests +let $lpad1 = $(lpad('hello', 10, '*')); +--echo lpad('hello', 10, '*') -> $lpad1 + +let $lpad2 = $(lpad('hello', 5, '*')); +--echo lpad('hello', 5, '*') -> $lpad2 + +let $lpad3 = $(lpad('hello', 3, '*')); +--echo lpad('hello', 3, '*') -> $lpad3 + +let $lpad4 = $(lpad('hello', 10, ' ')); +--echo lpad('hello', 10, ' ') -> $lpad4 + +let $lpad5 = $(lpad('', 5, '*')); +--echo lpad('', 5, '*') -> $lpad5 + +let $lpad6 = $(lpad('hello', 10, 'ab')); +--echo lpad('hello', 10, 'ab') -> $lpad6 + +let $lpad7 = $(lpad('hello', 0, '*')); +--echo lpad('hello', 0, '*') -> $lpad7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test RPAD function +--echo # ---------------------------------------------------------------------------- + +--echo # RPAD function tests +let $rpad1 = $(rpad('hello', 10, '*')); +--echo rpad('hello', 10, '*') -> $rpad1 + +let $rpad2 = $(rpad('hello', 5, '*')); +--echo rpad('hello', 5, '*') -> $rpad2 + +let $rpad3 = $(rpad('hello', 3, '*')); +--echo rpad('hello', 3, '*') -> $rpad3 + +let $rpad4 = $(rpad('hello', 10, ' ')); +--echo rpad('hello', 10, ' ') -> $rpad4 + +let $rpad5 = $(rpad('', 5, '*')); +--echo rpad('', 5, '*') -> $rpad5 + +let $rpad6 = $(rpad('hello', 10, 'ab')); +--echo rpad('hello', 10, 'ab') -> $rpad6 + +let $rpad7 = $(rpad('hello', 0, '*')); +--echo rpad('hello', 0, '*') -> $rpad7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LENGTH function +--echo # ---------------------------------------------------------------------------- + +--echo # LENGTH function tests +let $len1 = $(length('hello')); +--echo length('hello') -> $len1 + +let $len2 = $(length('hello world')); +--echo length('hello world') -> $len2 + +let $len3 = $(length('')); +--echo length('') -> $len3 + +let $len4 = $(length('12345')); +--echo length('12345') -> $len4 + +let $len5 = $(length(' hello ')); +--echo length(' hello ') -> $len5 + +let $len6 = $(length('a')); +--echo length('a') -> $len6 + +let $len7 = $(length('special@#\$%')); +--echo length('special@#\$%') -> $len7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test special characters and Latin characters +--echo # ---------------------------------------------------------------------------- + +--echo # Special characters and Latin characters tests +let $latin1 = $(length('Björn')); +--echo length('Björn') -> $latin1 +let $latin2 = $(upper('björn')); +--echo upper('björn') -> $latin2 +let $latin3 = $(lower('BJÖRN')); +--echo lower('BJÖRN') -> $latin3 +let $latin4 = $(reverse('Björn')); +--echo reverse('Björn') -> $latin4 +let $latin5 = $(locate('ö', 'Björn')); +--echo locate('ö', 'Björn') -> $latin5 +let $latin6 = $(substr('Björn', 1, 3)); +--echo substr('Björn', 1, 3) -> $latin6 +let $latin7 = $(trim(' Björn ')); +--echo trim(' Björn ') -> $latin7 +let $latin8 = $(concat('Björn', ' ', 'Müller')); +--echo concat('Björn', ' ', 'Müller') -> $latin8 +let $latin9 = $(replace('Björn Müller', 'Müller', 'Schmidt')); +--echo replace('Björn Müller', 'Müller', 'Schmidt') -> $latin9 +let $latin10 = $(instr('Björn Müller', 'Müller')); +--echo instr('Björn Müller', 'Müller') -> $latin10 +let $latin11 = $(lpad('Björn', 10, '*')); +--echo lpad('Björn', 10, '*') -> $latin11 +let $latin12 = $(rpad('Björn', 10, '*')); +--echo rpad('Björn', 10, '*') -> $latin12 +let $latin13 = $(length('KhÃ¥led Rïyad')); +--echo length('KhÃ¥led Rïyad') -> $latin13 +let $latin14 = $(upper('josé maría')); +--echo upper('josé maría') -> $latin14 +let $latin15 = $(substr('José María', 1, 4)); +--echo substr('José María', 1, 4) -> $latin15 + +--echo # ---------------------------------------------------------------------------- +--echo # Test special characters and symbols +--echo # ---------------------------------------------------------------------------- + +--echo # Special characters and symbols tests +let $symbols1 = $(concat('path', '/', 'to', '/', 'file.txt')); +--echo concat('path', '/', 'to', '/', 'file.txt') -> $symbols1 +let $symbols2 = $(instr('user@domain.com', 'domain.com')); +--echo instr('user@domain.com', 'domain.com') -> $symbols2 +let $symbols3 = $(length('path/to/file.txt')); +--echo length('path/to/file.txt') -> $symbols3 +let $symbols4 = $(locate('.', 'file.txt')); +--echo locate('.', 'file.txt') -> $symbols4 +let $symbols5 = $(locate('/', 'path/to/file.txt')); +--echo locate('/', 'path/to/file.txt') -> $symbols5 +let $symbols6 = $(upper('test@example.com')); +--echo upper('test@example.com') -> $symbols6 +let $symbols7 = $(lower('TEST@EXAMPLE.COM')); +--echo lower('TEST@EXAMPLE.COM') -> $symbols7 +let $symbols8 = $(lpad('file', 8, '.')); +--echo lpad('file', 8, '.') -> $symbols8 +let $symbols9 = $(rpad('path', 10, '/')); +--echo rpad('path', 10, '/') -> $symbols9 +let $symbols10 = $(replace('file.txt', 'txt', 'doc')); +--echo replace('file.txt', 'txt', 'doc') -> $symbols10 +let $symbols11 = $(replace('path/to/file.txt', 'file.txt', 'document.doc')); +--echo replace('path/to/file.txt', 'file.txt', 'document.doc') -> $symbols11 +let $symbols12 = $(reverse('path/to/file.txt')); +--echo reverse('path/to/file.txt') -> $symbols12 +let $symbols13 = $(substr('path/to/file.txt', 1, 4)); +--echo substr('path/to/file.txt', 1, 4) -> $symbols13 +let $symbols14 = $(trim(' path/to/file.txt ')); +--echo trim(' path/to/file.txt ') -> $symbols14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test complex combinations of string functions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex string function combinations + +let $complex1 = $(length(trim(' hello world '))); +--echo length(trim(' hello world ')) -> $complex1 + +let $complex2 = $(upper(lower('MiXeD CaSe'))); +--echo upper(lower('MiXeD CaSe')) -> $complex2 + +let $complex3 = $(reverse(lpad('hi', 5, '*'))); +--echo reverse(lpad('hi', 5, '*')) -> $complex3 + +let $complex4 = $(locate('o', upper('hello world'))); +--echo locate('o', upper('hello world')) -> $complex4 + +let $complex5 = $(substr(trim(' hello world '), 1, 5)); +--echo substr(trim(' hello world '), 1, 5) -> $complex5 + +let $complex6 = $(length(concat('hello', ' ', 'world'))); +--echo length(concat('hello', ' ', 'world')) -> $complex6 + +let $complex7 = $(reverse(upper('hello'))); +--echo reverse(upper('hello')) -> $complex7 + +let $complex8 = $(lpad(rtrim('hello '), 10, '*')); +--echo lpad(rtrim('hello '), 10, '*') -> $complex8 + +let $complex9 = $(least(length('hello'), length('world'), length('test'))); +--echo least(length('hello'), length('world'), length('test')) -> $complex9 + +let $complex10 = $(greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o'))); +--echo greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o')) -> $complex10 + +let $complex11 = $(repeat(upper(substr('hello', 1, 2)), 3)); +--echo repeat(upper(substr('hello', 1, 2)), 3) -> $complex11 + +let $complex12 = $(insert(lower('HELLO WORLD'), 7, 5, upper('mariadb'))); +--echo insert(lower('HELLO WORLD'), 7, 5, upper('mariadb')) -> $complex12 + +let $complex13 = $(concat_ws('-', upper('hello'), lower('WORLD'), reverse('test'))); +--echo concat_ws('-', upper('hello'), lower('WORLD'), reverse('test')) -> $complex13 + +let $complex14 = $(ifnull(nullif(trim(' hello '), 'hello'), 'default')); +--echo ifnull(nullif(trim(' hello '), 'hello'), 'default') -> $complex14 + +let $complex15 = $(coalesce(nullif('test', 'test'), upper('backup'))); +--echo coalesce(nullif('test', 'test'), upper('backup')) -> $complex15 + +let $complex16 = $(substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2)); +--echo substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2) -> $complex16 + +--echo # ---------------------------------------------------------------------------- +--echo # Test CONCAT function +--echo # ---------------------------------------------------------------------------- + +--echo # Basic CONCAT function tests + +let $concat1 = $(concat('a','b','c')); +--echo concat('a','b','c') -> $concat1 + +let $concat2 = $(concat(42, 'a')); +--echo concat(42, 'a') -> $concat2 + +let $concat3 = $(concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a')); +--echo concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a') -> $concat3 + +let $concat4 = $(concat('')); +--echo concat('') -> $concat4 + +let $concat5 = $(concat('Ã¥', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'Å‚', 'Å›', 'ż', 'ź', 'ć')); +--echo concat('Ã¥', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'Å‚', 'Å›', 'ż', 'ź', 'ć') -> $concat5 + +let $concat6 = $(concat('', 1)); +--echo concat('', 1) -> $concat6 + +--echo # ---------------------------------------------------------------------------- +--echo # Test SUBSTRING_INDEX function +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTRING_INDEX function tests + +let $substr_idx1 = $(substring_index('www.mariadb.org', '.', 2)); +--echo substring_index('www.mariadb.org', '.', 2) -> $substr_idx1 + +let $substr_idx2 = $(substring_index('www.mariadb.org', '.', -2)); +--echo substring_index('www.mariadb.org', '.', -2) -> $substr_idx2 + +let $substr_idx3 = $(substring_index('www.mariadb.org', '.', 0)); +--echo substring_index('www.mariadb.org', '.', 0) -> $substr_idx3 + +let $substr_idx4 = $(substring_index('www.mariadb.org', '', 1)); +--echo substring_index('www.mariadb.org', '', 1) -> $substr_idx4 + +let $substr_idx5 = $(substring_index('www.mariadb.org', '', -1)); +--echo substring_index('www.mariadb.org', '', -1) -> $substr_idx5 + +let $substr_idx6 = $(substring_index('mariadb', '.', 0)); +--echo substring_index('mariadb', '.', 0) -> $substr_idx6 + +let $substr_idx7 = $(substring_index('mariadb', '.', -1)); +--echo substring_index('mariadb', '.', -1) -> $substr_idx7 + +let $substr_idx8 = $(substring_index('mariadb', '.', 1)); +--echo substring_index('mariadb', '.', 1) -> $substr_idx8 + +let $substr_idx9 = $(substring_index('mariadb', 'A', 1)); +--echo substring_index('mariadb', 'A', 1) -> $substr_idx9 + +let $substr_idx10 = $(substring_index('mariadb', 'A', -1)); +--echo substring_index('mariadb', 'A', -1) -> $substr_idx10 + +let $substr_idx11 = $(substring_index('mariadb', 'A', 0)); +--echo substring_index('mariadb', 'A', 0) -> $substr_idx11 + +let $substr_idx12 = $(substring_index('mariadb', 'z', 2)); +--echo substring_index('mariadb', 'z', 2) -> $substr_idx12 + +let $substr_idx13 = $(substring_index('', 'z', -2)); +--echo substring_index('', 'z', -2) -> $substr_idx13 + +let $substr_idx14 = $(substring_index('mariadb', 'ar', 0)); +--echo substring_index('mariadb', 'ar', 0) -> $substr_idx14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_INSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_INSTR function tests + +let $regexp_instr1 = $(regexp_instr('abc','b')); +--echo regexp_instr('abc','b') -> $regexp_instr1 + +let $regexp_instr2 = $(regexp_instr('abc','x')); +--echo regexp_instr('abc','x') -> $regexp_instr2 + +let $regexp_instr3 = $(regexp_instr('abc','')); +--echo regexp_instr('abc','') -> $regexp_instr3 + +let $regexp_instr4 = $(regexp_instr('','a')); +--echo regexp_instr('','a') -> $regexp_instr4 + +let $regexp_instr5 = $(regexp_instr('','')); +--echo regexp_instr('','') -> $regexp_instr5 + +let $regexp_instr6 = $(regexp_instr('BJÖRN','N')); +--echo regexp_instr('BJÖRN','N') -> $regexp_instr6 + +let $regexp_instr7 = $(regexp_instr('ABC','(?-i)b')); +--echo regexp_instr('ABC','(?-i)b') -> $regexp_instr7 + +let $regexp_instr8 = $(regexp_instr('ABC','(?i)b')); +--echo regexp_instr('ABC','(?i)b') -> $regexp_instr8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_SUBSTR function tests + +let $regexp_substr1 = $(regexp_substr('ab12cd','[0-9]+')); +--echo regexp_substr('ab12cd','[0-9]+') -> $regexp_substr1 + +let $regexp_substr2 = $(regexp_substr('ab12cd','')); +--echo regexp_substr('ab12cd','') -> $regexp_substr2 + +let $regexp_substr3 = $(regexp_substr('abcd','[0-9]+')); +--echo regexp_substr('abcd','[0-9]+') -> $regexp_substr3 + +let $regexp_substr4 = $(regexp_substr('','[0-9]+')); +--echo regexp_substr('','[0-9]+') -> $regexp_substr4 + +let $regexp_substr5 = $(regexp_substr('','')); +--echo regexp_substr('','') -> $regexp_substr5 + +let $regexp_substr6 = $(regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*')); +--echo regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*') -> $regexp_substr6 + +let $regexp_substr7 = $(regexp_substr('ABC','b')); +--echo regexp_substr('ABC','b') -> $regexp_substr7 + +let $regexp_substr8 = $(regexp_substr('ABC','(?i)b')); +--echo regexp_substr('ABC','(?i)b') -> $regexp_substr8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_REPLACE function tests + +let $regexp_replace1 = $(regexp_replace('ABC','b','x')); +--echo regexp_replace('ABC','b','x') -> $regexp_replace1 + +let $regexp_replace2 = $(regexp_replace('ab12cd','[0-9]','')); +--echo regexp_replace('ab12cd','[0-9]','') -> $regexp_replace2 + +let $regexp_replace3 = $(regexp_replace('titlebody', '<.+?>',' ')); +--echo regexp_replace('titlebody', '<.+?>',' ') -> $regexp_replace3 + +let $regexp_replace4 = $(regexp_replace('James Bond','^(.*) (.*)\$','\2, \1')); +--echo regexp_replace('James Bond','^(.*) (.*)\$','\2, \1') -> $regexp_replace4 + +let $regexp_replace5 = $(regexp_replace('ABC','b','-')); +--echo regexp_replace('ABC','b','-') -> $regexp_replace5 + +let $regexp_replace6 = $(regexp_replace('ABC','(?-i)b','-')); +--echo regexp_replace('ABC','(?-i)b','-') -> $regexp_replace6 + +let $regexp_replace7 = $(regexp_replace('ABC','(?i)b','-')); +--echo regexp_replace('ABC','(?i)b','-') -> $regexp_replace7 + +let $regexp_replace8 = $(regexp_replace('ABC','b','')); +--echo regexp_replace('ABC','b','') -> $regexp_replace8 + +let $regexp_replace9 = $(regexp_replace('ABC','(?-i)b','')); +--echo regexp_replace('ABC','(?-i)b','') -> $regexp_replace9 + +let $regexp_replace10 = $(regexp_replace('ABC','','')); +--echo regexp_replace('ABC','','') -> $regexp_replace10 + +let $regexp_replace11 = $(regexp_replace('ABC','','A')); +--echo regexp_replace('ABC','','A') -> $regexp_replace11 + +let $regexp_replace12 = $(regexp_replace('','.','x')); +--echo regexp_replace('','.','x') -> $regexp_replace12 + +let $dollar1 = $(regexp_replace('ABC','b','\$')); +--echo regexp_replace('ABC','b','\$') -> $dollar1 + +let $dollar2 = $(regexp_replace('ABC','b','\$A')); +--echo regexp_replace('ABC','b','\$A') -> $dollar2 + +let $dollar3 = $(regexp_replace('ABCC','C\$','D')); +--echo regexp_replace('ABCC','C\$','D') -> $dollar3 + +let $dollar4 = $(regexp_replace('ABC\$','\\\$','D')); +--echo regexp_replace('ABC\$','\\\$','D') -> $dollar4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LEAST function +--echo # ---------------------------------------------------------------------------- + +--echo # LEAST function tests + +let $least1 = $(least(1, 2, 3)); +--echo least(1, 2, 3) -> $least1 + +let $least2 = $(least('a', 'b', 'c')); +--echo least('a', 'b', 'c') -> $least2 + +let $least3 = $(least(NULL, 1, 2)); +--echo least(NULL, 1, 2) -> $least3 + +let $least4 = $(least(NULL, NULL, NULL)); +--echo least(NULL, NULL, NULL) -> $least4 + +let $least5 = $(least('a', 1, 'b')); +--echo least('a', 1, 'b') -> $least5 + +let $least6 = $(least(1, 'a', 'b')); +--echo least(1, 'a', 'b') -> $least6 + +let $least7 = $(least('z', '-2', 'a')); +--echo least('z', '-2', 'a') -> $least7 + +let $least8 = $(least('z', -2, 'a')); +--echo least('z', -2, 'a') -> $least8 + +let $least9 = $(least(' -4a', -1, 'b')); +--echo least(' -4a', -1, 'b') -> $least9 + +let $least10 = $(least(' ', 10, 'b')); +--echo least(' ', 10, 'b') -> $least10 + +let $least11 = $(least(' -0 ', 10, 'b')); +--echo least(' -0 ', 10, 'b') -> $least11 + +let $least12 = $(least('', 10, '-b')); +--echo least('', 10, '-b') -> $least12 + +let $least13 = $(least(18446744073709551615, 18446744073709551614, 18446744073709551613)); +--echo least(18446744073709551615, 18446744073709551614, 18446744073709551613) -> $least13 + +let $least14 = $(least(18446744073709551615, -1, 18446744073709551613)); +--echo least(18446744073709551615, -1, 18446744073709551613) -> $least14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test GREATEST function +--echo # ---------------------------------------------------------------------------- + +--echo # GREATEST function tests + +let $greatest1 = $(greatest(1, 2, 3)); +--echo greatest(1, 2, 3) -> $greatest1 + +let $greatest2 = $(greatest('a', 'b', 'c')); +--echo greatest('a', 'b', 'c') -> $greatest2 + +let $greatest3 = $(greatest(NULL, 1, 2)); +--echo greatest(NULL, 1, 2) -> $greatest3 + +let $greatest4 = $(greatest(NULL, NULL, NULL)); +--echo greatest(NULL, NULL, NULL) -> $greatest4 + +let $greatest5 = $(greatest('a', 1, 'b')); +--echo greatest('a', 1, 'b') -> $greatest5 + +let $greatest6 = $(greatest(1, 'a', 'b')); +--echo greatest(1, 'a', 'b') -> $greatest6 + +let $greatest7 = $(greatest('z', '-2', 'a')); +--echo greatest('z', '-2', 'a') -> $greatest7 + +let $greatest8 = $(greatest('z', -2, 'a')); +--echo greatest('z', -2, 'a') -> $greatest8 + +let $greatest9 = $(greatest(' -4a', -1, 'b')); +--echo greatest(' -4a', -1, 'b') -> $greatest9 + +let $greatest10 = $(greatest(' ', 10, 'b')); +--echo greatest(' ', 10, 'b') -> $greatest10 + +let $greatest11 = $(greatest(' -0 ', 10, 'b')); +--echo greatest(' -0 ', 10, 'b') -> $greatest11 + +let $greatest12 = $(greatest('', 10, '-b')); +--echo greatest('', 10, '-b') -> $greatest12 + +let $greatest13 = $(greatest(18446744073709551615, 18446744073709551614, 18446744073709551613)); +--echo greatest(18446744073709551615, 18446744073709551614, 18446744073709551613) -> $greatest13 + +let $greatest14 = $(greatest(18446744073709551615, -1, 18446744073709551613)); +--echo greatest(18446744073709551615, -1, 18446744073709551613) -> $greatest14 + +let $greatest15 = $(greatest(3.14, 2.71, 3.15)); +--echo greatest(3.14, 2.71, 3.15) -> $greatest15 + +let $greatest16 = $(greatest(-10, -5, -20)); +--echo greatest(-10, -5, -20) -> $greatest16 + +let $greatest17 = $(greatest('apple', 'banana', 'cherry')); +--echo greatest('apple', 'banana', 'cherry') -> $greatest17 + +let $greatest18 = $(greatest('100', '20', '3')); +--echo greatest('100', '20', '3') -> $greatest18 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REPEAT function +--echo # ---------------------------------------------------------------------------- + +--echo # REPEAT function tests + +let $repeat1 = $(repeat('MariaDB ',4)); +--echo repeat('MariaDB ',4) -> $repeat1 + +let $repeat2 = $(repeat('a', 0)); +--echo repeat('a', 0) -> $repeat2 + +let $repeat3 = $(repeat('a', 1)); +--echo repeat('a', 1) -> $repeat3 + +let $repeat4 = $(repeat('', 0)); +--echo repeat('', 0) -> $repeat4 + +let $repeat5 = $(repeat('a', -1)); +--echo repeat('a', -1) -> $repeat5 + +let $repeat6 = $(repeat('a', 18446744073709551615)); +--echo repeat('a', 18446744073709551615) -> $repeat6 + +let $repeat7 = $(repeat('', 4)); +--echo repeat('', 4) -> $repeat7 + +let $repeat8 = $(repeat('', -1)); +--echo repeat('', -1) -> $repeat8 + +let $repeat9 = $(repeat('a32423413', 100)); +--echo repeat('a32423413', 10) -> $repeat9 + +--echo # ---------------------------------------------------------------------------- +--echo # Test NULLIF function +--echo # ---------------------------------------------------------------------------- + +--echo # NULLIF function tests + +let $nullif1 = $(nullif('a', 'a')); +--echo nullif('a', 'a') -> $nullif1 + +let $nullif2 = $(nullif('a', 'b')); +--echo nullif('a', 'b') -> $nullif2 + +let $nullif3 = $(nullif('a', NULL)); +--echo nullif('a', NULL) -> $nullif3 + +let $nullif4 = $(nullif(NULL, 'a')); +--echo nullif(NULL, 'a') -> $nullif4 + +let $nullif5 = $(nullif(NULL, NULL)); +--echo nullif(NULL, NULL) -> $nullif5 + +--echo # ---------------------------------------------------------------------------- +--echo # Test COALESCE function +--echo # ---------------------------------------------------------------------------- + +--echo # COALESCE function tests + +let $coalesce1 = $(coalesce(NULL, 'a')); +--echo coalesce(NULL, 'a') -> $coalesce1 + +let $coalesce2 = $(coalesce(NULL, NULL)); +--echo coalesce(NULL, NULL) -> $coalesce2 + +let $coalesce3 = $(coalesce(NULL, 'a', 'b')); +--echo coalesce(NULL, 'a', 'b') -> $coalesce3 + +let $coalesce4 = $(coalesce('a', 'b', 'c')); +--echo coalesce('a', 'b', 'c') -> $coalesce4 + +let $coalesce5 = $(coalesce('a', NULL, 'b')); +--echo coalesce('a', NULL, 'b') -> $coalesce5 + +let $coalesce6 = $(coalesce(NULL, NULL, 'a')); +--echo coalesce(NULL, NULL, 'a') -> $coalesce6 + +let $coalesce7 = $(coalesce(NULL, NULL, NULL)); +--echo coalesce(NULL, NULL, NULL) -> $coalesce7 + +let $coalesce8 = $(coalesce(NULL, 'a', NULL, 'b')); +--echo coalesce(NULL, 'a', NULL, 'b') -> $coalesce8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test IFNULL function +--echo # ---------------------------------------------------------------------------- + +--echo # IFNULL function tests + +let $ifnull1 = $(ifnull(NULL, 'a')); +--echo ifnull(NULL, 'a') -> $ifnull1 + +let $ifnull2 = $(ifnull('a', NULL)); +--echo ifnull('a', NULL) -> $ifnull2 + +let $ifnull3 = $(ifnull(NULL, NULL)); +--echo ifnull(NULL, NULL) -> $ifnull3 + +let $ifnull4 = $(ifnull('a', 'b')); +--echo ifnull('a', 'b') -> $ifnull4 + +let $ifnull5 = $(ifnull('a', 'a')); +--echo ifnull('a', 'a') -> $ifnull5 + +--echo # ---------------------------------------------------------------------------- +--echo # Test INSERT function +--echo # ---------------------------------------------------------------------------- + +--echo # INSERT function tests + +let $insert1 = $(insert('Hello World', 2, 3, 'Xyz')); +--echo insert('Hello World', 2, 3, 'Xyz') -> $insert1 + +let $insert2 = $(insert('Hello World', 2, 3, '')); +--echo insert('Hello World', 2, 3, '') -> $insert2 + +let $insert3 = $(insert('Hello World', 2, 3, NULL)); +--echo insert('Hello World', 2, 3, NULL) -> $insert3 + +let $insert4 = $(insert('Hello World', 0, 0, 'Xyz')); +--echo insert('Hello World', 0, 0, 'Xyz') -> $insert4 + +let $insert5 = $(insert('Hello World', 0, 0, '')); +--echo insert('Hello World', 0, 0, '') -> $insert5 + +let $insert6 = $(insert('Quadratic', 3, 4, 'What')); +--echo insert('Quadratic', 3, 4, 'What') -> $insert6 + +let $insert7 = $(insert('Quadratic', -1, 4, 'What')); +--echo insert('Quadratic', -1, 4, 'What') -> $insert7 + +let $insert8 = $(insert('Quadratic', 3, 100, 'What')); +--echo insert('Quadratic', 3, 100, 'What') -> $insert8 + +let $insert9 = $(insert('Quadratic', -32, -100, 'wow')); +--echo insert('Quadratic', -32, -100, 'wow') -> $insert9 + +let $insert10 = $(insert('Quadratic', 32, 100, 'wow')); +--echo insert('Quadratic', 32, 100, 'wow') -> $insert10 + +let $insert11 = $(insert('Quadratic', 1, 8, 'wow')); +--echo insert('Quadratic', 1, 8, 'wow') -> $insert11 + +let $insert12 = $(insert('Quadratic', 1, 1000, 'wow')); +--echo insert('Quadratic', 1, 1000, 'wow') -> $insert12 + +let $insert13 = $(insert('Quadratic', 4, 2, 'wow')); +--echo insert('Quadratic', 4, 2, 'wow') -> $insert13 + +let $insert14 = $(insert('Quadratic', 4, 2, '')); +--echo insert('Quadratic', 4, 2, '') -> $insert14 + +let $insert15 = $(insert('', 4, 2, 'wow')); +--echo insert('', 4, 2, 'wow') -> $insert15 + +let $insert16 = $(insert('Quadratic', 4, -2, 'wow')); +--echo insert('Quadratic', 4, -2, 'wow') -> $insert16 + +let $insert17 = $(insert('Quadratic', 4, 0, 'wow')); +--echo insert('Quadratic', 4, 0, 'wow') -> $insert17 + +--echo # ---------------------------------------------------------------------------- +--echo # Test CONCAT_WS function +--echo # ---------------------------------------------------------------------------- + +--echo # CONCAT_WS function tests + +let $concat_ws1 = $(concat_ws('-', 'a', 'b', 'c')); +--echo concat_ws('-', 'a', 'b', 'c') -> $concat_ws1 + +let $concat_ws2 = $(concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')); +--echo concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z') -> $concat_ws2 + +let $concat_ws3 = $(concat_ws(' ,', 'a')); +--echo concat_ws(' ,', 'a') -> $concat_ws3 + +let $concat_ws4 = $(concat_ws('', 'abc', 'def', 'ghi')); +--echo concat_ws('', 'abc', 'def', 'ghi') -> $concat_ws4 + +let $concat_ws5 = $(concat_ws('', 'abc')); +--echo concat_ws('', 'abc') -> $concat_ws5 + +let $concat_ws6 = $(concat_ws('&', 'abc')); +--echo concat_ws('&', 'abc') -> $concat_ws6 + +let $concat_ws7 = $(concat_ws(' ,', '')); +--echo concat_ws(' ,', '') -> $concat_ws7 + +let $concat_ws8 = $(concat_ws('&', 'abc', NULL)); +--echo concat_ws('&', 'abc', NULL) -> $concat_ws8 + +let $concat_ws9 = $(concat_ws('...', 'abc', NULL, 'def')); +--echo concat_ws('...', 'abc', NULL, 'def') -> $concat_ws9 + +let $concat_ws10 = $(concat_ws(NULL, 'abc', NULL, 'def')); +--echo concat_ws(NULL, 'abc', NULL, 'def') -> $concat_ws10 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with variables +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with variables + +let $text = 'test string'; +let $search = 'string'; +let $replacement = 'value'; + +let $result1 = $(least($text, $search)); +--echo least($text, $search) -> $result1 + +let $result1a = $(greatest($text, $search)); +--echo greatest($text, $search) -> $result1a + +let $result2 = $(repeat($search, 3)); +--echo repeat($search, 3) -> $result2 + +let $result3 = $(insert($text, 5, 6, $replacement)); +--echo insert($text, 5, 6, $replacement) -> $result3 + +let $result4 = $(concat_ws(' ', $text, $search, $replacement)); +--echo concat_ws(' ', $text, $search, $replacement) -> $result4 + +let $result5 = $(ifnull(NULL, $replacement)); +--echo ifnull(NULL, $replacement) -> $result5 + +let $result6 = $(coalesce(NULL, NULL, $replacement)); +--echo coalesce(NULL, NULL, $replacement) -> $result6 + +let $result7 = $(nullif($text, $search)); +--echo nullif($text, $search) -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with special characters + +let $result1 = $(least('Björn', 'Müller', 'Schmidt')); +--echo least('Björn', 'Müller', 'Schmidt') -> $result1 + +let $result1a = $(greatest('Björn', 'Müller', 'Schmidt')); +--echo greatest('Björn', 'Müller', 'Schmidt') -> $result1a + +let $result2 = $(repeat('ö', 5)); +--echo repeat('ö', 5) -> $result2 + +let $result3 = $(insert('Björn Müller', 7, 6, 'Schmidt')); +--echo insert('Björn Müller', 7, 6, 'Schmidt') -> $result3 + +let $result4 = $(concat_ws(' ', 'José', 'María', 'González')); +--echo concat_ws(' ', 'José', 'María', 'González') -> $result4 + +let $result5 = $(ifnull(NULL, 'François')); +--echo ifnull(NULL, 'François') -> $result5 + +let $result6 = $(coalesce(NULL, 'HÃ¥kon', 'Olsen')); +--echo coalesce(NULL, 'HÃ¥kon', 'Olsen') -> $result6 + +let $result7 = $(nullif('test@example.com', 'user@domain.com')); +--echo nullif('test@example.com', 'user@domain.com') -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with mixed data types +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with mixed data types + +let $result1 = $(least(123, 'abc', 456)); +--echo least(123, 'abc', 456) -> $result1 + +let $result1a = $(greatest(123, 'abc', 456)); +--echo greatest(123, 'abc', 456) -> $result1a + +let $result2 = $(repeat('test', 3)); +--echo repeat('test', 3) -> $result2 + +let $result3 = $(insert('test123', 5, 3, 'ABC')); +--echo insert('test123', 5, 3, 'ABC') -> $result3 + +let $result4 = $(concat_ws('-', 'prefix', 123, 'suffix')); +--echo concat_ws('-', 'prefix', 123, 'suffix') -> $result4 + +let $result5 = $(ifnull(123, 'fallback')); +--echo ifnull(123, 'fallback') -> $result5 + +let $result6 = $(coalesce(NULL, 456, 'backup')); +--echo coalesce(NULL, 456, 'backup') -> $result6 + +let $result7 = $(nullif(123, 456)); +--echo nullif(123, 456) -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions in complex expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Functions in complex expressions + +let $result1 = $(least(1, 2, 3) + 10); +--echo least(1, 2, 3) + 10 -> $result1 + +let $result1a = $(greatest(1, 2, 3) * 5); +--echo greatest(1, 2, 3) * 5 -> $result1a + +let $result2 = $(length(repeat('ab', 4))); +--echo length(repeat('ab', 4)) -> $result2 + +let $result3 = $(upper(insert('hello world', 7, 5, 'mariadb'))); +--echo upper(insert('hello world', 7, 5, 'mariadb')) -> $result3 + +let $result4 = $(length(concat_ws(' ', 'hello', 'world', 'test'))); +--echo length(concat_ws(' ', 'hello', 'world', 'test')) -> $result4 + +let $result5 = $(ifnull(NULL, 'default') == 'default'); +--echo ifnull(NULL, 'default') == 'default' -> $result5 + +let $result6 = $(coalesce(NULL, NULL, 'found') != 'missing'); +--echo coalesce(NULL, NULL, 'found') != 'missing' -> $result6 + +let $result7 = $(nullif('same', 'same')); +--echo nullif('same', 'same') -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions in conditional expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Functions in conditional expressions + +if ($(least(5, 3, 8) == 3)) +{ + --echo least returns minimum value correctly +} + +if ($(greatest(5, 3, 8) == 8)) +{ + --echo greatest returns maximum value correctly +} + +if ($(repeat('x', 0) == '')) +{ + --echo repeat with count 0 returns empty string +} + +if ($(insert('test', 1, 2, 'best') == 'best')) +{ + --echo insert replaces correctly at start +} + +if ($(concat_ws(',', 'a', 'b') == 'a,b')) +{ + --echo CONCAT_WS joins with separator correctly +} + +if ($(ifnull('value', 'default') == 'value')) +{ + --echo ifnull returns first value when not NULL +} + +if ($(coalesce(NULL, 'second', 'third') == 'second')) +{ + --echo coalesce returns first non-NULL value +} + +if ($(nullif('different', 'values') == 'different')) +{ + --echo nullif returns first value when values differ +} + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with arithmetic in arguments +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with arithmetic in arguments + +let $result1 = $(least(1+2, 2*2, 3+1)); +--echo least(1+2, 2*2, 3+1) -> $result1 + +let $result1a = $(greatest(1+2, 2*2, 3+1)); +--echo greatest(1+2, 2*2, 3+1) -> $result1a + +let $result2 = $(repeat('x', 2+3)); +--echo repeat('x', 2+3) -> $result2 + +let $result3 = $(insert('hello', 1+1, 2*1, 'hi')); +--echo insert('hello', 1+1, 2*1, 'hi') -> $result3 + +let $start_pos = 2; +let $length_val = 3; +let $result4 = $(insert('testing', $start_pos, $length_val, 'xyz')); +--echo insert('testing', $start_pos, $length_val, 'xyz') -> $result4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test nested function calls +--echo # ---------------------------------------------------------------------------- + +--echo # Nested function calls + +let $result1 = $(least(length('hello'), length('world'), length('test'))); +--echo least(length('hello'), length('world'), length('test')) -> $result1 + +let $result1a = $(greatest(length('hello'), length('world'), length('test'))); +--echo greatest(length('hello'), length('world'), length('test')) -> $result1a + +let $result2 = $(repeat(upper('ab'), 3)); +--echo repeat(upper('ab'), 3) -> $result2 + +let $result3 = $(insert(upper('hello world'), 7, 5, lower('MARIADB'))); +--echo insert(upper('hello world'), 7, 5, lower('MARIADB')) -> $result3 + +let $result4 = $(concat_ws(' ', upper('hello'), lower('WORLD'))); +--echo concat_ws(' ', upper('hello'), lower('WORLD')) -> $result4 + +let $result5 = $(ifnull(nullif('same', 'same'), 'default')); +--echo ifnull(nullif('same', 'same'), 'default') -> $result5 + +let $result6 = $(coalesce(nullif('test', 'test'), 'backup')); +--echo coalesce(nullif('test', 'test'), 'backup') -> $result6 + +--echo # Expression evaluation string functions tests completed successfully From b505b7421a25f043949c37220c3d6c4635a8b6df Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 8 Oct 2025 18:14:29 +0200 Subject: [PATCH 091/152] 10.6 adjasts --- client/mysqltest.cc | 12 ++++++++++-- mysql-test/main/mysqltest_string_functions.result | 2 -- mysql-test/main/mysqltest_string_functions.test | 12 +++++++----- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ba9ed6ec9b2..c4a6ff48cd1 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6542,7 +6542,11 @@ void func_lower(Expression_value args[], int count, Expression_value *result) die("lower() expects 1 argument, got %d", count); My_string result_str; - result_str.copy_casedn(charset_info, args[0].to_string().to_lex_cstring()); + // replace with + // result_str.copy_casedn(charset_info, args[0].to_string().to_lex_cstring()); + // in higher versions + result_str.copy(args[0].to_string()); + my_casedn_str(charset_info, (char*) result_str.ptr()); result->set_string(result_str.ptr(), result_str.length()); } @@ -6567,7 +6571,11 @@ void func_upper(Expression_value args[], int count, Expression_value *result) die("upper() expects 1 argument, got %d", count); My_string result_str; - result_str.copy_caseup(charset_info, args[0].to_string().to_lex_cstring()); + // replace with + //result_str.copy_caseup(charset_info, args[0].to_string().to_lex_cstring()); + // in higher versions + result_str.copy(args[0].to_string()); + my_caseup_str(charset_info, (char*) result_str.ptr()); result->set_string(result_str.ptr(), result_str.length()); } diff --git a/mysql-test/main/mysqltest_string_functions.result b/mysql-test/main/mysqltest_string_functions.result index e89fe942601..e6f848cef6f 100644 --- a/mysql-test/main/mysqltest_string_functions.result +++ b/mysql-test/main/mysqltest_string_functions.result @@ -29,8 +29,6 @@ hex(4095) -> FFF # ---------------------------------------------------------------------------- # Testing extended bases conv(ZZ, 36, 10) -> 1295 -conv(z, 62, 10) -> 61 -conv(Hello, 62, 10) -> 260914464 # ---------------------------------------------------------------------------- # Test signed vs unsigned interpretation # ---------------------------------------------------------------------------- diff --git a/mysql-test/main/mysqltest_string_functions.test b/mysql-test/main/mysqltest_string_functions.test index 0c38c1e32f9..9115e46923d 100644 --- a/mysql-test/main/mysqltest_string_functions.test +++ b/mysql-test/main/mysqltest_string_functions.test @@ -68,11 +68,13 @@ let $hex2 = $(hex(4095)); let $base36 = $(conv(ZZ, 36, 10)); --echo conv(ZZ, 36, 10) -> $base36 -let $base62_1 = $(conv(z, 62, 10)); ---echo conv(z, 62, 10) -> $base62_1 - -let $base62_2 = $(conv(Hello, 62, 10)); ---echo conv(Hello, 62, 10) -> $base62_2 +# uncomment in 11.4 +#let $base62_1 = $(conv(z, 62, 10)); +#--echo conv(z, 62, 10) -> $base62_1 +#conv(z, 62, 10) -> 61 +#let $base62_2 = $(conv(Hello, 62, 10)); +#--echo conv(Hello, 62, 10) -> $base62_2 +#conv(Hello, 62, 10) -> 260914464 --echo # ---------------------------------------------------------------------------- --echo # Test signed vs unsigned interpretation From 6a32ccc5b95ebcb00259e778419e3d0334764834 Mon Sep 17 00:00:00 2001 From: Rex Johnston Date: Thu, 8 Jan 2026 13:55:07 +1300 Subject: [PATCH 092/152] MDEV-38473 Incorrect Empty Set with HAVING clause when SELECT and GROUP BY use different aliases for the same column MDEV-29300 fix causes a wrong result by incorrectly removing a wrapper to an item that needed to be wrapped for the correct result. Direct access to the item causes an incorrect table reference to be used during join evaluation. We revert that fix. Our original problem query is this SELECT (SELECT 0 GROUP BY c1 HAVING (SELECT c1)) FROM t1 group by c1; JOIN::prepare on /* select#2 */ select 0 group by t1.c1 having (subquery#3) fixing t1.c1 in group by clause, calls fix_outer_field() this item is resolved in an outer select (#1) and it is a grouping select, so we wrap it in Item_outer_ref and set this item to unfixed for later fixing in fix_inner_refs(). JOIN::prepare continues onto the having clause and fixes (subquery#3) which calls initiates the prepare series of calls, leading to setup_fields on the fields in this JOIN, one of which is an outer reference c1. This is resolved to the item in the next most outer select in the group by clause. This item has been wrapped with an unfixed Item_outer_ref. It is found in resolve_ref_in_select_and_group() is it expected that this item will have already been fixed, hence this call in Item_field::fix_outer_field() DBUG_ASSERT(*ref && (*ref)->fixed()); but as explained above, it isn't fixed and debug builds assert here. Because this wrapper cannot be resolved here for reasons detailed in fix_inner_refs, and we cannot remove this wrapper without potentially returning an incorrect result, we have to relax this assertion. Approved by: Oleksandr "Sanja" Byelkin (sanja@mariadb.com) --- mysql-test/main/subselect4.result | 23 +++++++++++++++++++++++ mysql-test/main/subselect4.test | 18 ++++++++++++++++++ sql/item.cc | 25 +++++++++++++++++++------ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index c0c67707231..ba4e6f17a95 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -3373,4 +3373,27 @@ CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; (SELECT 0 GROUP BY c HAVING (SELECT c)) DROP TABLE t; +# +# MDEV-38476 Wrong Result (Empty Set) with derived_merge=on using AVG() on text column in HAVING clause +# +CREATE TABLE t1(c1 TEXT); +INSERT INTO t1(c1) VALUES ('a'),('ab'),('cc'); +SELECT MAX(ca1) FROM (SELECT c1 AS ca1 FROM t1) AS ta1 +GROUP BY ca1 +HAVING AVG(ca1) RLIKE (TRUE & CHARACTER_LENGTH(ca1)); +MAX(ca1) +ab +cc +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a' +Warning 1292 Truncated incorrect DOUBLE value: 'ab' +Warning 1292 Truncated incorrect DOUBLE value: 'cc' +TRUNCATE t1; +INSERT INTO t1 (c1) VALUES (NULL), ('abc'); +SELECT ca1 FROM (SELECT c1 AS ca1, c1 AS ca2 FROM t1) AS ta1 +GROUP BY ca2 +HAVING (ca2 = ANY (SELECT c1 FROM t1)) IS NOT TRUE; +ca1 +NULL +DROP TABLE t1; # End of 10.11 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 083da1647b2..e76c4638ddf 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2695,4 +2695,22 @@ CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; DROP TABLE t; +--echo # +--echo # MDEV-38476 Wrong Result (Empty Set) with derived_merge=on using AVG() on text column in HAVING clause +--echo # + +CREATE TABLE t1(c1 TEXT); +INSERT INTO t1(c1) VALUES ('a'),('ab'),('cc'); +SELECT MAX(ca1) FROM (SELECT c1 AS ca1 FROM t1) AS ta1 + GROUP BY ca1 + HAVING AVG(ca1) RLIKE (TRUE & CHARACTER_LENGTH(ca1)); + +TRUNCATE t1; +INSERT INTO t1 (c1) VALUES (NULL), ('abc'); +SELECT ca1 FROM (SELECT c1 AS ca1, c1 AS ca2 FROM t1) AS ta1 + GROUP BY ca2 + HAVING (ca2 = ANY (SELECT c1 FROM t1)) IS NOT TRUE; + +DROP TABLE t1; + --echo # End of 10.11 tests diff --git a/sql/item.cc b/sql/item.cc index 0f7aff680f7..d745b3cd36f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5782,8 +5782,6 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) DBUG_ASSERT((*select_ref)->fixed()); return &select->ref_pointer_array[counter]; } - if (group_by_ref && (*group_by_ref)->type() == Item::REF_ITEM) - return ((Item_ref*)(*group_by_ref))->ref; if (group_by_ref) return group_by_ref; DBUG_ASSERT(FALSE); @@ -6063,8 +6061,24 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) return -1; /* Some error occurred (e.g. ambiguous names). */ if (ref != not_found_item) { - DBUG_ASSERT(*ref && (*ref)->fixed()); - prev_subselect_item->used_tables_and_const_cache_join(*ref); + DBUG_ASSERT(*ref); + + /* + If this item isn't yet fixed, it is an Item_outer_ref, wrapping an + item. If that item is fixed, we can fix this wrapper now. Otherwise + it will need to wait until the fix_inner_refs() in JOIN::prepare() + */ + if (!(*ref)->fixed() && + (*ref)->type() == Item::REF_ITEM) + { + Item_ref *item_ref= static_cast(*ref); + Item *refref= *(item_ref->ref); + if (refref->fixed()) + (*ref)->fix_fields_if_needed( thd, reference); + } + if ((*ref)->fixed()) + prev_subselect_item->used_tables_and_const_cache_join(*ref); + break; } } @@ -6105,8 +6119,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) Item *save; Item_ref *rf; - /* Should have been checked in resolve_ref_in_select_and_group(). */ - DBUG_ASSERT(*ref && (*ref)->fixed()); + DBUG_ASSERT(*ref); /* Here, a subset of actions performed by Item_ref::set_properties is not enough. So we pass ptr to NULL into Item_[direct]_ref From c882f9b25a4fe27fa38aafe04593807369573c9f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 16 Dec 2025 20:38:03 +0100 Subject: [PATCH 093/152] MDEV-37527 Client plugins are underlinked Provide test case --- mysql-test/suite/plugins/r/auth_ed25519.result | 2 ++ mysql-test/suite/plugins/t/auth_ed25519.test | 3 +++ 2 files changed, 5 insertions(+) diff --git a/mysql-test/suite/plugins/r/auth_ed25519.result b/mysql-test/suite/plugins/r/auth_ed25519.result index 6769d867167..5a560d7d5de 100644 --- a/mysql-test/suite/plugins/r/auth_ed25519.result +++ b/mysql-test/suite/plugins/r/auth_ed25519.result @@ -70,6 +70,8 @@ current_user() test1@localhost disconnect con1; connection default; +# Executing 'mariadb-admin' +mysqld is alive drop user test1@localhost; uninstall plugin ed25519; select ed25519_password("foo"); diff --git a/mysql-test/suite/plugins/t/auth_ed25519.test b/mysql-test/suite/plugins/t/auth_ed25519.test index 8e0bdd1d460..16614057490 100644 --- a/mysql-test/suite/plugins/t/auth_ed25519.test +++ b/mysql-test/suite/plugins/t/auth_ed25519.test @@ -50,6 +50,9 @@ select current_user(); disconnect con1; connection default; +--echo # Executing 'mariadb-admin' +--exec $MYSQLADMIN -u test1 -S $MASTER_MYSOCK -P $MASTER_MYPORT --password=secret ping + drop user test1@localhost; uninstall plugin ed25519; error ER_CANT_INITIALIZE_UDF; From 11f228cbb2b37f2516e3697ff6c7d2cd20017aab Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Thu, 8 Jan 2026 13:54:00 -0700 Subject: [PATCH 094/152] MDEV-38506: Failed GRANT on a procedure breaks replication When GRANT EXECUTE ON PROCEDURE fails on the master, it will erroneously be replicated and executed successfully on the slave. This both breaks replication and is a security violation. The underlying issue is that a failed GRANT EXECUTE ON PROCEDURE will still be replicated when sql_mode does not have NO_AUTO_CREATE_USER. This is because the function mysql_routine_grant() does not check if an error occured while performing the GRANT before binlogging, it simply always binlogs. This patch fixes this problem by checking if an error happened previously before binlogging, and if so, then skip binlogging. Note there is still a broader issue in this area leading to replication divergence. Reported in MDEV-29848, a partially-completed GRANT statment (where some earlier GRANTS succeed and a later fails) will not binlog. Note this affects all grant types, whereas the issue addressed in this patch is limited to GRANT EXECUTE ON PROCEDURE. This patch makes GRANT EXECUTE ON PROCEDURE binlogging behavior consistent with the other grant types. A separate follow-up patch will address the broader MDEV-29848 issue. Also note that a test case in rpl_do_grant.test took advantage of MDEV-38506 so a partially-failing REVOKE EXECUTE ON PROCEDURE would still replicate. This test case is disabled with a TODO note to re-enable it once MDEV-29848 is fixed Reviewed-by: Sergei Golubchik Signed-off-by: Brandon Nesterenko --- mysql-test/suite/rpl/r/rpl_do_grant.result | 68 +--------------------- mysql-test/suite/rpl/r/rpl_grant.result | 29 +++++++++ mysql-test/suite/rpl/t/rpl_do_grant.test | 15 ++++- mysql-test/suite/rpl/t/rpl_grant.test | 43 ++++++++++++++ sql/sql_acl.cc | 2 +- 5 files changed, 88 insertions(+), 69 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index 0d2908809b9..0e3b578adda 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -211,71 +211,9 @@ connection master; DROP TABLE t1; DROP PROCEDURE p1; connection slave; -### ii) Test case in which REVOKE partially succeeds -connection master; -include/rpl_reset.inc -connection master; -CREATE TABLE t1(c1 INT); -CREATE PROCEDURE p1() SELECT * FROM t1 | -CREATE USER 'user49119'@'localhost'; -GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost'; -############################################################## -### Showing grants for both users: root and user49119 (master) -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -GRANT EXECUTE ON PROCEDURE `test`.`p1` TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection slave; -############################################################## -### Showing grants for both users: root and user49119 (master) -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -GRANT EXECUTE ON PROCEDURE `test`.`p1` TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection master; -## This statement will make the revoke fail because root has no -## execute grant. However, it will still revoke the grant for -## user49119. -REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost'; -ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1' -############################################################## -### Showing grants for both users: root and user49119 (master) -### after revoke statement failure -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection slave; -############################################################# -### Showing grants for both users: root and user49119 (slave) -### after revoke statement failure (should match -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection master; -DROP TABLE t1; -DROP PROCEDURE p1; -DROP USER 'user49119'@'localhost'; -connection slave; +# +# TODO: Re-enable test-case after fixing MDEV-29848 +# include/rpl_reset.inc connection master; grant all on *.* to foo@"1.2.3.4"; diff --git a/mysql-test/suite/rpl/r/rpl_grant.result b/mysql-test/suite/rpl/r/rpl_grant.result index 274a8505fb8..bb0e682ac78 100644 --- a/mysql-test/suite/rpl/r/rpl_grant.result +++ b/mysql-test/suite/rpl/r/rpl_grant.result @@ -38,4 +38,33 @@ User Host SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; COUNT(*) 0 +# +# MDEV-38506: Failed GRANT on a procedure breaks replication +# +# Disable NO_AUTO_CREATE_USER so grant will auto-create users +connection master; +SET @old_sql_mode= @@GLOBAL.sql_mode; +SET GLOBAL sql_mode=''; +# Create new stored procedure for GRANT EXECUTE ON PROCEDURE +CREATE PROCEDURE test.sp() SELECT 1; +# Create a new user with limited privileges to grant sp execution +CREATE USER 'test_user'@'%' IDENTIFIED BY 'somepass'; +GRANT EXECUTE ON test.* TO 'test_user'@'%' WITH GRANT OPTION; +connect con_test_user,localhost,test_user,somepass; +GRANT EXECUTE ON PROCEDURE test.sp TO 'nonexistentuser'@''; +ERROR 42000: You are not allowed to create a user with GRANT +# Ensuring the failed GRANT is not replicated.. +include/rpl_sync.inc +connection master; +connection slave; +SHOW GRANTS for 'nonexistentuser'@''; +ERROR 42000: There is no such grant defined for user 'nonexistentuser' on host '%' +# ..PASS +connection master; +disconnect con_test_user; +SET GLOBAL sql_mode= @old_sql_mode; +DROP USER test_user@'%'; +DROP PROCEDURE test.sp; +# End of MDEV-38506 test case include/rpl_end.inc +# End of rpl_grant.test diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 2b757f57692..c5c116e0f86 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -212,8 +212,11 @@ USE test; # when binlogging is active, the master will not hit an # assertion. # -# ii) a test case that partially succeeds on the master will also -# partially succeed on the slave. +# ii) (DISABLED) To pass, this test case took advantage of a vulnerability, +# MDEV-38506. Please uncomment this test case when MDEV-29848 is fixed. +# +# test case that partially succeeds on the master will also +# partially succeed on the slave. # # - The revoke statement that partially succeeds tries to revoke # an EXECUTE grant for two users, and only one of the user has @@ -242,6 +245,11 @@ DROP PROCEDURE p1; -- sync_slave_with_master +--echo # +--echo # TODO: Re-enable test-case after fixing MDEV-29848 +--echo # +if (0) +{ -- echo ### ii) Test case in which REVOKE partially succeeds -- connection master @@ -289,7 +297,7 @@ SHOW GRANTS FOR CURRENT_USER; -- echo ############################################################# -- echo ### Showing grants for both users: root and user49119 (slave) --- echo ### after revoke statement failure (should match +-- echo ### after revoke statement failure (should match) SHOW GRANTS FOR 'user49119'@'localhost'; SHOW GRANTS FOR CURRENT_USER; -- echo ############################################################## @@ -300,6 +308,7 @@ DROP PROCEDURE p1; DROP USER 'user49119'@'localhost'; -- sync_slave_with_master +} # # Bug #51987 revoke privileges logs wrong error code diff --git a/mysql-test/suite/rpl/t/rpl_grant.test b/mysql-test/suite/rpl/t/rpl_grant.test index 0220645380a..cd3ed4ec2a6 100644 --- a/mysql-test/suite/rpl/t/rpl_grant.test +++ b/mysql-test/suite/rpl/t/rpl_grant.test @@ -34,4 +34,47 @@ sync_slave_with_master; SELECT user,host FROM mysql.user WHERE user like 'dummy%'; SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; +--echo # +--echo # MDEV-38506: Failed GRANT on a procedure breaks replication +--echo # + +--echo # Disable NO_AUTO_CREATE_USER so grant will auto-create users +connection master; +SET @old_sql_mode= @@GLOBAL.sql_mode; +SET GLOBAL sql_mode=''; + +--echo # Create new stored procedure for GRANT EXECUTE ON PROCEDURE +CREATE PROCEDURE test.sp() SELECT 1; + +--echo # Create a new user with limited privileges to grant sp execution +CREATE USER 'test_user'@'%' IDENTIFIED BY 'somepass'; +GRANT EXECUTE ON test.* TO 'test_user'@'%' WITH GRANT OPTION; +connect (con_test_user,localhost,test_user,somepass); +let $old_binlog_gtid= `SELECT @@global.gtid_binlog_pos`; # Tag the GTID before the failed GRANT +error ER_CANT_CREATE_USER_WITH_GRANT; +GRANT EXECUTE ON PROCEDURE test.sp TO 'nonexistentuser'@''; + +--echo # Ensuring the failed GRANT is not replicated.. +source include/rpl_sync.inc; +connection master; +let $new_binlog_gtid= `SELECT @@global.gtid_binlog_pos`; +if (`SELECT strcmp('$old_binlog_gtid', '$new_binlog_gtid') != 0`) +{ + --echo # binlog_gtid_pos before GRANT: $old_binlog_gtid + --echo # binlog_gtid_pos after GRANT: $new_binlog_gtid + --die Failed GRANT was binlogged +} +connection slave; +error ER_NONEXISTING_GRANT; +SHOW GRANTS for 'nonexistentuser'@''; +--echo # ..PASS + +connection master; +disconnect con_test_user; +SET GLOBAL sql_mode= @old_sql_mode; +DROP USER test_user@'%'; +DROP PROCEDURE test.sp; +--echo # End of MDEV-38506 test case + --source include/rpl_end.inc +--echo # End of rpl_grant.test diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5b4a3ebb3cf..1ad90da04f1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7636,7 +7636,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, thd->mem_root= old_root; mysql_mutex_unlock(&acl_cache->lock); - if (write_to_binlog) + if (write_to_binlog && !result) { if (write_bin_log(thd, FALSE, thd->query(), thd->query_length())) result= TRUE; From 16b5bf03d7b69daf890161105b965c1ec9da5880 Mon Sep 17 00:00:00 2001 From: Raghunandan Bhat Date: Tue, 13 Jan 2026 16:22:06 +0530 Subject: [PATCH 095/152] MDEV-37474: Privilege check of information_schema.TRIGGERS does not correspond to the standards According to SQL standard, rows from `INFORMATION_SCHEMA.TRIGGERS` table should be visible to users with non-SELECT privileges on the columns. `ACTION_CONDITION`, `ACTION_STATEMENT` and `DEFINER` columns should be visible only if the user is the owner of the schema. MariaDB uses `TRIGGER` privilege instead of owner, which controls the visibilty of all columns, including those which only need non-SELECT privileges. This fix - Allows users with non-SELECT privileges- INSERT, DELETE or UPDATE, to see rows in `INFORMATION_SCHEMA.TRIGGERS` table. - Ensure `ACTION_CONDITION`, `ACTION_STATEMENT` and `DEFINER` columns are `NULL` unless the user is the owner of the schema or has `TRIGGER` privilege. --- mysql-test/main/show_check.result | 8 +- mysql-test/main/trigger_notembedded.result | 81 ++++++++++++++ mysql-test/main/trigger_notembedded.test | 101 ++++++++++++++++++ .../suite/funcs_1/r/innodb_trig_03e.result | 4 + .../suite/funcs_1/r/is_columns_is.result | 4 +- .../funcs_1/r/is_columns_is_embedded.result | 4 +- mysql-test/suite/funcs_1/r/is_triggers.result | 14 +-- .../funcs_1/r/is_triggers_embedded.result | 12 +-- .../suite/funcs_1/r/memory_trig_03e.result | 4 + .../suite/funcs_1/r/myisam_trig_03e.result | 4 + .../triggers/triggers_03e_global_db_mix.inc | 3 +- sql/sql_show.cc | 45 ++++++-- 12 files changed, 252 insertions(+), 32 deletions(-) diff --git a/mysql-test/main/show_check.result b/mysql-test/main/show_check.result index 9cbf1d19716..7b884cb7692 100644 --- a/mysql-test/main/show_check.result +++ b/mysql-test/main/show_check.result @@ -1019,11 +1019,11 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def information_schema TRIGGERS TRIGGERS TRIGGER_NAME Trigger 253 192 5 N 4097 0 33 def information_schema TRIGGERS TRIGGERS EVENT_MANIPULATION Event 253 18 6 N 4097 0 33 def information_schema TRIGGERS TRIGGERS EVENT_OBJECT_TABLE Table 253 192 2 N 4097 0 33 -def information_schema TRIGGERS TRIGGERS ACTION_STATEMENT Statement 252 589815 10 N 4113 0 33 +def information_schema TRIGGERS TRIGGERS ACTION_STATEMENT Statement 252 589815 10 Y 4112 0 33 def information_schema TRIGGERS TRIGGERS ACTION_TIMING Timing 253 18 6 N 4097 0 33 def information_schema TRIGGERS TRIGGERS CREATED Created 12 22 22 Y 4224 2 63 def information_schema TRIGGERS TRIGGERS SQL_MODE sql_mode 253 24576 89 N 4097 0 33 -def information_schema TRIGGERS TRIGGERS DEFINER Definer 253 1152 14 N 4097 0 33 +def information_schema TRIGGERS TRIGGERS DEFINER Definer 253 1152 14 Y 4096 0 33 def information_schema TRIGGERS TRIGGERS CHARACTER_SET_CLIENT character_set_client 253 96 6 N 4097 0 33 def information_schema TRIGGERS TRIGGERS COLLATION_CONNECTION collation_connection 253 192 6 N 4097 0 33 def information_schema TRIGGERS TRIGGERS DATABASE_COLLATION Database Collation 253 192 17 N 4097 0 33 @@ -1059,7 +1059,7 @@ def information_schema TRIGGERS TRIGGERS EVENT_OBJECT_CATALOG EVENT_OBJECT_CATAL def information_schema TRIGGERS TRIGGERS EVENT_OBJECT_SCHEMA EVENT_OBJECT_SCHEMA 253 192 4 N 4097 0 33 def information_schema TRIGGERS TRIGGERS EVENT_OBJECT_TABLE EVENT_OBJECT_TABLE 253 192 2 N 4097 0 33 def information_schema TRIGGERS TRIGGERS ACTION_CONDITION ACTION_CONDITION 252 589815 0 Y 4112 0 33 -def information_schema TRIGGERS TRIGGERS ACTION_STATEMENT ACTION_STATEMENT 252 589815 10 N 4113 0 33 +def information_schema TRIGGERS TRIGGERS ACTION_STATEMENT ACTION_STATEMENT 252 589815 10 Y 4112 0 33 def information_schema TRIGGERS TRIGGERS ACTION_ORIENTATION ACTION_ORIENTATION 253 27 3 N 4097 0 33 def information_schema TRIGGERS TRIGGERS ACTION_TIMING ACTION_TIMING 253 18 6 N 4097 0 33 def information_schema TRIGGERS TRIGGERS ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_OLD_TABLE 253 192 0 Y 4096 0 33 @@ -1067,7 +1067,7 @@ def information_schema TRIGGERS TRIGGERS ACTION_REFERENCE_NEW_TABLE ACTION_REFER def information_schema TRIGGERS TRIGGERS ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_OLD_ROW 253 9 3 N 4097 0 33 def information_schema TRIGGERS TRIGGERS ACTION_REFERENCE_NEW_ROW ACTION_REFERENCE_NEW_ROW 253 9 3 N 4097 0 33 def information_schema TRIGGERS TRIGGERS SQL_MODE SQL_MODE 253 24576 89 N 4097 0 33 -def information_schema TRIGGERS TRIGGERS DEFINER DEFINER 253 1152 14 N 4097 0 33 +def information_schema TRIGGERS TRIGGERS DEFINER DEFINER 253 1152 14 Y 4096 0 33 TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW SQL_MODE DEFINER def test t1_bi INSERT def test t1 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost SELECT CREATED FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name='t1_bi'; diff --git a/mysql-test/main/trigger_notembedded.result b/mysql-test/main/trigger_notembedded.result index 41547ac1e99..69e05e00a03 100644 --- a/mysql-test/main/trigger_notembedded.result +++ b/mysql-test/main/trigger_notembedded.result @@ -570,3 +570,84 @@ disconnect con1; connection default; USE test; End of 5.1 tests. +# +# MDEV-37474: Privilege check of information_schema.TRIGGERS does not correspond the standard +# +CREATE TABLE t (a INT); +CREATE TABLE t1 (count INT); +INSERT INTO t1 VALUES (0); +CREATE TRIGGER trg_ai AFTER INSERT ON t FOR EACH ROW UPDATE t1 SET t1.count = t1.count + 1; +INSERT INTO t VALUES (1), (2); +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL UPDATE t1 SET t1.count = t1.count + 1 ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t UPDATE t1 SET t1.count = t1.count + 1 AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +CREATE USER user@localhost; +GRANT TRIGGER ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL UPDATE t1 SET t1.count = t1.count + 1 ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t UPDATE t1 SET t1.count = t1.count + 1 AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +connection default; +disconnect conn1; +# Revoke TRIGGER & grant INSERT, UPDATE, DELETE one after another +REVOKE TRIGGER ON t FROM user@localhost; +GRANT INSERT ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL NULL ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t NULL AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +connection default; +disconnect conn1; +REVOKE INSERT ON t FROM user@localhost; +GRANT UPDATE ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL NULL ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t NULL AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +connection default; +disconnect conn1; +REVOKE UPDATE ON t FROM user@localhost; +GRANT DELETE ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL NULL ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t NULL AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci +connection default; +disconnect conn1; +REVOKE DELETE ON t FROM user@localhost; +GRANT SELECT ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +connection default; +disconnect conn1; +GRANT TRIGGER ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test trg_ai INSERT def test t 1 NULL UPDATE t1 SET t1.count = t1.count + 1 ROW AFTER NULL NULL OLD NEW - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW TRIGGERS FROM test WHERE `Table` = 't'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg_ai INSERT t UPDATE t1 SET t1.count = t1.count + 1 AFTER - STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +connection default; +disconnect conn1; +DROP USER user@localhost; +DROP TABLE t, t1; +# End of 10.11 tests diff --git a/mysql-test/main/trigger_notembedded.test b/mysql-test/main/trigger_notembedded.test index 509d247f55a..36c65171d00 100644 --- a/mysql-test/main/trigger_notembedded.test +++ b/mysql-test/main/trigger_notembedded.test @@ -995,3 +995,104 @@ DROP USER mysqltest_u1@localhost; USE test; --echo End of 5.1 tests. + + +--echo # +--echo # MDEV-37474: Privilege check of information_schema.TRIGGERS does not correspond the standard +--echo # + +CREATE TABLE t (a INT); + +CREATE TABLE t1 (count INT); +INSERT INTO t1 VALUES (0); + +CREATE TRIGGER trg_ai AFTER INSERT ON t FOR EACH ROW UPDATE t1 SET t1.count = t1.count + 1; +INSERT INTO t VALUES (1), (2); + +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CREATE USER user@localhost; +GRANT TRIGGER ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show all columns including ACTION_CONDITION and ACTION_STATEMENT +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +--echo # Revoke TRIGGER & grant INSERT, UPDATE, DELETE one after another +REVOKE TRIGGER ON t FROM user@localhost; +GRANT INSERT ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show all columns excluding ACTION_CONDITION and ACTION_STATEMENT +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +REVOKE INSERT ON t FROM user@localhost; +GRANT UPDATE ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show all columns excluding ACTION_CONDITION and ACTION_STATEMENT +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +REVOKE UPDATE ON t FROM user@localhost; +GRANT DELETE ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show all columns excluding ACTION_CONDITION and ACTION_STATEMENT +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +REVOKE DELETE ON t FROM user@localhost; +GRANT SELECT ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show no rows +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +# keep only the TRIGGER privilege +GRANT TRIGGER ON t TO user@localhost; +CONNECT conn1, localhost, user, , test; + +# show all columns +--replace_column 17 - +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'trg_ai'; +--replace_column 6 - +SHOW TRIGGERS FROM test WHERE `Table` = 't'; + +CONNECTION default; +DISCONNECT conn1; + +DROP USER user@localhost; +DROP TABLE t, t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result index 51f4eca4f1a..c5030d4fd4d 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result @@ -615,8 +615,12 @@ test_yesprivs@localhost use priv_db; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1_1 INSERT t1 NULL BEFORE # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci select * from information_schema.triggers; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def mtr gs_insert INSERT def mtr global_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def mtr ts_insert INSERT def mtr test_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def priv_db trg1_1 INSERT def priv_db t1 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci drop trigger trg1_1; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table `priv_db`.`t1` connection default; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index f1d819fa9ef..9b0684a1913 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -436,13 +436,13 @@ def information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NULL NO varchar 3 9 def information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) select NEVER NULL def information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext select NEVER NULL +def information_schema TRIGGERS ACTION_STATEMENT 10 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext select NEVER NULL def information_schema TRIGGERS ACTION_TIMING 12 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) select NEVER NULL def information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NULL NO varchar 32 96 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(32) select NEVER NULL def information_schema TRIGGERS COLLATION_CONNECTION 21 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 2 NULL NULL datetime(2) select NEVER NULL def information_schema TRIGGERS DATABASE_COLLATION 22 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema TRIGGERS DEFINER 19 NULL NO varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) select NEVER NULL +def information_schema TRIGGERS DEFINER 19 NULL YES varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) select NEVER NULL def information_schema TRIGGERS EVENT_MANIPULATION 4 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) select NEVER NULL def information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL def information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index 6b4aa6fcb8e..b52413f3244 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -436,13 +436,13 @@ def information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NULL NO varchar 3 9 def information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) NEVER NULL def information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext NEVER NULL +def information_schema TRIGGERS ACTION_STATEMENT 10 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext NEVER NULL def information_schema TRIGGERS ACTION_TIMING 12 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) NEVER NULL def information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NULL NO varchar 32 96 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(32) NEVER NULL def information_schema TRIGGERS COLLATION_CONNECTION 21 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 2 NULL NULL datetime(2) NEVER NULL def information_schema TRIGGERS DATABASE_COLLATION 22 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema TRIGGERS DEFINER 19 NULL NO varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) NEVER NULL +def information_schema TRIGGERS DEFINER 19 NULL YES varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) NEVER NULL def information_schema TRIGGERS EVENT_MANIPULATION 4 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) NEVER NULL def information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) NEVER NULL def information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL diff --git a/mysql-test/suite/funcs_1/r/is_triggers.result b/mysql-test/suite/funcs_1/r/is_triggers.result index 99e514cfed9..7c0a27b85c2 100644 --- a/mysql-test/suite/funcs_1/r/is_triggers.result +++ b/mysql-test/suite/funcs_1/r/is_triggers.result @@ -39,7 +39,7 @@ EVENT_OBJECT_SCHEMA varchar(64) NO NULL EVENT_OBJECT_TABLE varchar(64) NO NULL ACTION_ORDER bigint(4) NO NULL ACTION_CONDITION longtext YES NULL -ACTION_STATEMENT longtext NO NULL +ACTION_STATEMENT longtext YES NULL ACTION_ORIENTATION varchar(9) NO NULL ACTION_TIMING varchar(6) NO NULL ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL @@ -48,7 +48,7 @@ ACTION_REFERENCE_OLD_ROW varchar(3) NO NULL ACTION_REFERENCE_NEW_ROW varchar(3) NO NULL CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO NULL -DEFINER varchar(384) NO NULL +DEFINER varchar(384) YES NULL CHARACTER_SET_CLIENT varchar(32) NO NULL COLLATION_CONNECTION varchar(64) NO NULL DATABASE_COLLATION varchar(64) NO NULL @@ -64,7 +64,7 @@ TRIGGERS CREATE TEMPORARY TABLE `TRIGGERS` ( `EVENT_OBJECT_TABLE` varchar(64) NOT NULL, `ACTION_ORDER` bigint(4) NOT NULL, `ACTION_CONDITION` longtext, - `ACTION_STATEMENT` longtext NOT NULL, + `ACTION_STATEMENT` longtext, `ACTION_ORIENTATION` varchar(9) NOT NULL, `ACTION_TIMING` varchar(6) NOT NULL, `ACTION_REFERENCE_OLD_TABLE` varchar(64), @@ -73,7 +73,7 @@ TRIGGERS CREATE TEMPORARY TABLE `TRIGGERS` ( `ACTION_REFERENCE_NEW_ROW` varchar(3) NOT NULL, `CREATED` datetime(2), `SQL_MODE` varchar(8192) NOT NULL, - `DEFINER` varchar(384) NOT NULL, + `DEFINER` varchar(384), `CHARACTER_SET_CLIENT` varchar(32) NOT NULL, `COLLATION_CONNECTION` varchar(64) NOT NULL, `DATABASE_COLLATION` varchar(64) NOT NULL @@ -89,7 +89,7 @@ EVENT_OBJECT_SCHEMA varchar(64) NO NULL EVENT_OBJECT_TABLE varchar(64) NO NULL ACTION_ORDER bigint(4) NO NULL ACTION_CONDITION longtext YES NULL -ACTION_STATEMENT longtext NO NULL +ACTION_STATEMENT longtext YES NULL ACTION_ORIENTATION varchar(9) NO NULL ACTION_TIMING varchar(6) NO NULL ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL @@ -98,7 +98,7 @@ ACTION_REFERENCE_OLD_ROW varchar(3) NO NULL ACTION_REFERENCE_NEW_ROW varchar(3) NO NULL CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO NULL -DEFINER varchar(384) NO NULL +DEFINER varchar(384) YES NULL CHARACTER_SET_CLIENT varchar(32) NO NULL COLLATION_CONNECTION varchar(64) NO NULL DATABASE_COLLATION varchar(64) NO NULL @@ -151,8 +151,10 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CR SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def db_datadict trg1 INSERT def db_datadict t1 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci SHOW TRIGGERS FROM db_datadict; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1 INSERT t1 NULL BEFORE # NULL latin1 latin1_swedish_ci latin1_swedish_ci connect testuser3, localhost, testuser3, , test; SHOW GRANTS FOR 'testuser3'@'localhost'; Grants for testuser3@localhost diff --git a/mysql-test/suite/funcs_1/r/is_triggers_embedded.result b/mysql-test/suite/funcs_1/r/is_triggers_embedded.result index a16493912ad..6b0406a3a3a 100644 --- a/mysql-test/suite/funcs_1/r/is_triggers_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_triggers_embedded.result @@ -39,7 +39,7 @@ EVENT_OBJECT_SCHEMA varchar(64) NO NULL EVENT_OBJECT_TABLE varchar(64) NO NULL ACTION_ORDER bigint(4) NO NULL ACTION_CONDITION longtext YES NULL -ACTION_STATEMENT longtext NO NULL +ACTION_STATEMENT longtext YES NULL ACTION_ORIENTATION varchar(9) NO NULL ACTION_TIMING varchar(6) NO NULL ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL @@ -48,7 +48,7 @@ ACTION_REFERENCE_OLD_ROW varchar(3) NO NULL ACTION_REFERENCE_NEW_ROW varchar(3) NO NULL CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO NULL -DEFINER varchar(384) NO NULL +DEFINER varchar(384) YES NULL CHARACTER_SET_CLIENT varchar(32) NO NULL COLLATION_CONNECTION varchar(64) NO NULL DATABASE_COLLATION varchar(64) NO NULL @@ -64,7 +64,7 @@ TRIGGERS CREATE TEMPORARY TABLE `TRIGGERS` ( `EVENT_OBJECT_TABLE` varchar(64) NOT NULL, `ACTION_ORDER` bigint(4) NOT NULL, `ACTION_CONDITION` longtext, - `ACTION_STATEMENT` longtext NOT NULL, + `ACTION_STATEMENT` longtext, `ACTION_ORIENTATION` varchar(9) NOT NULL, `ACTION_TIMING` varchar(6) NOT NULL, `ACTION_REFERENCE_OLD_TABLE` varchar(64), @@ -73,7 +73,7 @@ TRIGGERS CREATE TEMPORARY TABLE `TRIGGERS` ( `ACTION_REFERENCE_NEW_ROW` varchar(3) NOT NULL, `CREATED` datetime(2), `SQL_MODE` varchar(8192) NOT NULL, - `DEFINER` varchar(384) NOT NULL, + `DEFINER` varchar(384), `CHARACTER_SET_CLIENT` varchar(32) NOT NULL, `COLLATION_CONNECTION` varchar(64) NOT NULL, `DATABASE_COLLATION` varchar(64) NOT NULL @@ -89,7 +89,7 @@ EVENT_OBJECT_SCHEMA varchar(64) NO NULL EVENT_OBJECT_TABLE varchar(64) NO NULL ACTION_ORDER bigint(4) NO NULL ACTION_CONDITION longtext YES NULL -ACTION_STATEMENT longtext NO NULL +ACTION_STATEMENT longtext YES NULL ACTION_ORIENTATION varchar(9) NO NULL ACTION_TIMING varchar(6) NO NULL ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL @@ -98,7 +98,7 @@ ACTION_REFERENCE_OLD_ROW varchar(3) NO NULL ACTION_REFERENCE_NEW_ROW varchar(3) NO NULL CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO NULL -DEFINER varchar(384) NO NULL +DEFINER varchar(384) YES NULL CHARACTER_SET_CLIENT varchar(32) NO NULL COLLATION_CONNECTION varchar(64) NO NULL DATABASE_COLLATION varchar(64) NO NULL diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03e.result b/mysql-test/suite/funcs_1/r/memory_trig_03e.result index 9397e0766ef..f81cb1357e1 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result @@ -616,8 +616,12 @@ test_yesprivs@localhost use priv_db; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1_1 INSERT t1 NULL BEFORE # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci select * from information_schema.triggers; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def mtr gs_insert INSERT def mtr global_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def mtr ts_insert INSERT def mtr test_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def priv_db trg1_1 INSERT def priv_db t1 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci drop trigger trg1_1; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table `priv_db`.`t1` connection default; diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result index b16beda5752..b8ddf38bce8 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result @@ -616,8 +616,12 @@ test_yesprivs@localhost use priv_db; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1_1 INSERT t1 NULL BEFORE # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci select * from information_schema.triggers; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def mtr gs_insert INSERT def mtr global_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def mtr ts_insert INSERT def mtr test_suppressions 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # NULL latin1 latin1_swedish_ci latin1_swedish_ci +def priv_db trg1_1 INSERT def priv_db t1 1 NULL NULL ROW BEFORE NULL NULL OLD NEW # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL latin1 latin1_swedish_ci latin1_swedish_ci drop trigger trg1_1; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table `priv_db`.`t1` connection default; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc index f84474f1541..b531f714694 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc @@ -86,6 +86,8 @@ let $message= trigger privilege on user level for create:; use priv_db; --replace_column 6 # show triggers; +--replace_column 17 # +--sorted_result select * from information_schema.triggers; --error ER_TABLEACCESS_DENIED_ERROR drop trigger trg1_1; @@ -213,4 +215,3 @@ let $message= trigger privilege on db level for create:; drop user test_yesprivs@localhost; drop user test_noprivs@localhost; --enable_warnings - diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b2e1a550aaa..390b74463ac 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7393,9 +7393,9 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, } -static bool store_trigger(THD *thd, Trigger *trigger, - TABLE *table, const LEX_CSTRING *db_name, - const LEX_CSTRING *table_name) +static bool store_trigger(THD *thd, Trigger *trigger, TABLE *table, + const LEX_CSTRING *db_name, + const LEX_CSTRING *table_name, bool trigger_priv) { CHARSET_INFO *cs= system_charset_info; LEX_CSTRING sql_mode_rep; @@ -7417,7 +7417,20 @@ static bool store_trigger(THD *thd, Trigger *trigger, table->field[5]->store(db_name->str, db_name->length, cs); table->field[6]->store(table_name->str, table_name->length, cs); table->field[7]->store(trigger->action_order); - table->field[9]->store(trigger_body.str, trigger_body.length, cs); + + if (trigger_priv) + { + table->field[9]->set_notnull(); + table->field[18]->set_notnull(); + table->field[9]->store(trigger_body.str, trigger_body.length, cs); + table->field[18]->store(definer_buffer.str, definer_buffer.length, cs); + } + else + { + table->field[9]->set_null(); + table->field[18]->set_null(); + } + table->field[10]->store(STRING_WITH_LEN("ROW"), cs); table->field[11]->store(trg_action_time_type_names[trigger->action_time].str, trg_action_time_type_names[trigger->action_time].length, cs); @@ -7437,7 +7450,6 @@ static bool store_trigger(THD *thd, Trigger *trigger, sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep); table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs); - table->field[18]->store(definer_buffer.str, definer_buffer.length, cs); table->field[19]->store(&trigger->client_cs_name, cs); table->field[20]->store(&trigger->connection_cl_name, cs); table->field[21]->store(&trigger->db_cl_name, cs); @@ -7470,8 +7482,20 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, Table_triggers_list *triggers= tables->table->triggers; int event, timing; - if (check_table_access(thd, TRIGGER_ACL, tables, FALSE, 1, TRUE)) - goto ret; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool trigger_priv= + !check_table_access(thd, TRIGGER_ACL, tables, FALSE, 1, TRUE); + + const privilege_t need= (INSERT_ACL | UPDATE_ACL | DELETE_ACL); + if (!(trigger_priv || (thd->col_access & need))) + { + check_grant(thd, need, tables, 0, 1, 1); + if (!(tables->grant.all_privilege() & need)) + DBUG_RETURN(0); + } +#else + bool trigger_priv= true; +#endif for (event= 0; event < (int)TRG_EVENT_MAX; event++) { @@ -7484,13 +7508,12 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, trigger; trigger= trigger->next) { - if (store_trigger(thd, trigger, table, db_name, table_name)) + if (store_trigger(thd, trigger, table, db_name, table_name, trigger_priv)) DBUG_RETURN(1); } } } } -ret: DBUG_RETURN(0); } @@ -9776,7 +9799,7 @@ ST_FIELD_INFO triggers_fields_info[]= Column("EVENT_OBJECT_TABLE", Name(), NOT_NULL, "Table", OPEN_FRM_ONLY), Column("ACTION_ORDER", SLonglong(4), NOT_NULL, OPEN_FRM_ONLY), Column("ACTION_CONDITION", Longtext(65535), NULLABLE, OPEN_FRM_ONLY), - Column("ACTION_STATEMENT", Longtext(65535), NOT_NULL, "Statement",OPEN_FRM_ONLY), + Column("ACTION_STATEMENT", Longtext(65535), NULLABLE, "Statement",OPEN_FRM_ONLY), Column("ACTION_ORIENTATION", Varchar(9), NOT_NULL, OPEN_FRM_ONLY), Column("ACTION_TIMING", Varchar(6), NOT_NULL, "Timing", OPEN_FRM_ONLY), Column("ACTION_REFERENCE_OLD_TABLE",Name(), NULLABLE, OPEN_FRM_ONLY), @@ -9786,7 +9809,7 @@ ST_FIELD_INFO triggers_fields_info[]= /* 2 here indicates 2 decimals */ Column("CREATED", Datetime(2), NULLABLE, "Created", OPEN_FRM_ONLY), Column("SQL_MODE", SQLMode(), NOT_NULL, "sql_mode", OPEN_FRM_ONLY), - Column("DEFINER", Definer(), NOT_NULL, "Definer", OPEN_FRM_ONLY), + Column("DEFINER", Definer(), NULLABLE, "Definer", OPEN_FRM_ONLY), Column("CHARACTER_SET_CLIENT", CSName(), NOT_NULL, "character_set_client", OPEN_FRM_ONLY), Column("COLLATION_CONNECTION", CLName(), NOT_NULL, "collation_connection", From a84b8ec5b13a36735a3257ae07fcd3d8e15b7ec8 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 22 Jan 2026 12:47:52 +0400 Subject: [PATCH 096/152] MDEV-38626 Unexpected `Data too long` error on subselect as a multiplication argument Item_singerow_subselect::fix_length_and_dec() incorrectly calculated its Item::max_length when the underlying expression was Item_int. The reason of the problem: Item_int has an optimized max_length to make CONCAT(1) create a VARCHAR(1) column rather than a VARCHAR(2) column. Its max_length does not include one extra character for the sign in case the value is positive but the value is not marked as Item::unsigned==true. So copying max_length from the underlying Item_int (with value==9) in cases like this: SELECT CONCAT((SELECT 9 FROM t0)); was not correct. Implementing a new virtual method Type_handler::Item_type_std_attributes_generic(const Item *item) - The default implementation just copies attributes from "item" as is. - In case of Type_handler_int_result it evaluates max_length using item->decimal_precision() rather than item->max_length. This works correctly for both "optimized" items like Item_int and non-"optimized" Items whose max_length includes +1 for the sign in case of signed expressions. --- mysql-test/main/subselect4.result | 14 ++++++++++++++ mysql-test/main/subselect4.test | 12 ++++++++++++ sql/item_subselect.cc | 5 ++--- sql/sql_type.cc | 31 +++++++++++++++++++++++++++++++ sql/sql_type.h | 4 ++++ 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index ba4e6f17a95..696ba7de592 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -3396,4 +3396,18 @@ HAVING (ca2 = ANY (SELECT c1 FROM t1)) IS NOT TRUE; ca1 NULL DROP TABLE t1; +# +# MDEV-38626 Unexpected `Data too long` error on subselect as a multiplication argument +# +CREATE TABLE t0 AS SELECT 1; +CREATE TABLE t1 AS +SELECT CONCAT((SELECT 9 FROM t0) * (SELECT 9 FROM t0)) AS c1, +CONCAT(9 * 9) AS c2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` varchar(3) DEFAULT NULL, + `c2` varchar(3) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t0, t1; # End of 10.11 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index e76c4638ddf..303d39c93f3 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2713,4 +2713,16 @@ SELECT ca1 FROM (SELECT c1 AS ca1, c1 AS ca2 FROM t1) AS ta1 DROP TABLE t1; +--echo # +--echo # MDEV-38626 Unexpected `Data too long` error on subselect as a multiplication argument +--echo # + +CREATE TABLE t0 AS SELECT 1; +CREATE TABLE t1 AS + SELECT CONCAT((SELECT 9 FROM t0) * (SELECT 9 FROM t0)) AS c1, + CONCAT(9 * 9) AS c2; +SHOW CREATE TABLE t1; +DROP TABLE t0, t1; + + --echo # End of 10.11 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0378aad8537..43747623213 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3990,10 +3990,9 @@ bool subselect_engine::set_row(List &item_list, Item_cache **row) set_handler(&type_handler_varchar); for (uint i= 0; (sel_item= li++); i++) { - item->max_length= sel_item->max_length; set_handler(sel_item->type_handler()); - item->decimals= sel_item->decimals; - item->unsigned_flag= sel_item->unsigned_flag; + item->Type_std_attributes::operator=( + sel_item->type_handler()->Item_type_std_attributes_generic(sel_item)); maybe_null= sel_item->maybe_null(); if (!(row[i]= sel_item->get_cache(thd))) return TRUE; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 6fac86b8755..752e4e4bc1e 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -7313,6 +7313,37 @@ Item_divisor_precision_increment_with_seconds(const Item *item) const TIME_SECOND_PART_DIGITS; } + +/***************************************************************************/ +Type_std_attributes +Type_handler::Item_type_std_attributes_generic(const Item *item) const +{ + return *item; +} + + +Type_std_attributes +Type_handler_int_result::Item_type_std_attributes_generic(const Item *item) + const +{ + /* + Item_int is a special item, it optimizes it's metadata to have + shorter strings in string contexts: CONCAT(1) -> VARCHAR(1). + When we want to convert its attributes to a generic non-optimized + Item (e.g. for subselect), we need to add one extra character for + a possible sign. + The code below works both for optimized Item_int and other item kinds. + It evaluates max_length from the precision and the optinal sign length. + */ + DBUG_ASSERT(item->decimals == 0); + uint32 max_length= item->decimal_precision() + (item->unsigned_flag ? 0 : 1); + return Type_std_attributes( + Type_numeric_attributes(max_length, 0, item->unsigned_flag), + item->collation); + return *item; +} + + /***************************************************************************/ decimal_digits_t Type_handler_string_result::Item_decimal_precision(const Item *item) const diff --git a/sql/sql_type.h b/sql/sql_type.h index e39f16a5738..7d543f400d2 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3940,6 +3940,8 @@ public: virtual bool can_return_extract_source(interval_type type) const; virtual bool is_bool_type() const { return false; } virtual bool is_general_purpose_string_type() const { return false; } + virtual Type_std_attributes Item_type_std_attributes_generic( + const Item *item) const; virtual decimal_digits_t Item_time_precision(THD *thd, Item *item) const; virtual decimal_digits_t Item_datetime_precision(THD *thd, Item *item) const; virtual decimal_digits_t Item_decimal_scale(const Item *item) const; @@ -5287,6 +5289,8 @@ public: bool binary_cmp) const override; bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr, Item *a, Item *b) const override; + Type_std_attributes Item_type_std_attributes_generic( + const Item *item) const override; decimal_digits_t Item_decimal_precision(const Item *item) const override; bool Item_save_in_value(THD *thd, Item *item, st_value *value) const override; bool Item_param_set_from_value(THD *thd, From 251f76d39e3b5fae78dcb1e4e23e0c90a4b9cd59 Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Thu, 22 Jan 2026 08:31:45 +0530 Subject: [PATCH 097/152] MDEV-36353: Crash with explain for connection SHOW EXPLAIN FOR, and EXPLAIN/DESC FOR CONNECTION should behave identically. However, for a query with an addition expression containing INTERVAL and NOT IN sub-select SHOW EXPLAIN FOR was correctly throwing parse error, where as EXPLAIN/DESC FOR CONNECTION was crashing. The reason for the crash is that select block was not initialized and was being accessed inside the NOT IN sub-select in the EXPLAIN/DESC FOR CONNECTION case. --- mysql-test/main/show_explain.result | 8 ++++++++ mysql-test/main/show_explain.test | 9 +++++++++ sql/sql_yacc.yy | 12 ++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/show_explain.result b/mysql-test/main/show_explain.result index 22ac7de6153..f60360418ad 100644 --- a/mysql-test/main/show_explain.result +++ b/mysql-test/main/show_explain.result @@ -1442,3 +1442,11 @@ count(*) - count(*) connection default; disconnect con1; set debug_sync='RESET'; +# +# MDEV-36353: Server crashes with EXPLAIN/DESC FOR CONNECTION +# instead of displaying an error. +# +EXPLAIN FOR CONNECTION INTERVAL TRUE IN (SELECT 1) YEAR_MONTH + FALSE=TRUE NOT IN (SELECT 1); +ERROR HY000: You may only use constant expressions in this statement +DESC FOR CONNECTION INTERVAL TRUE IN (SELECT 1) YEAR_MONTH + FALSE=TRUE NOT IN (SELECT 1); +ERROR HY000: You may only use constant expressions in this statement diff --git a/mysql-test/main/show_explain.test b/mysql-test/main/show_explain.test index 749c08b1804..44b7db271d9 100644 --- a/mysql-test/main/show_explain.test +++ b/mysql-test/main/show_explain.test @@ -1330,3 +1330,12 @@ connection default; disconnect con1; set debug_sync='RESET'; +--echo # +--echo # MDEV-36353: Server crashes with EXPLAIN/DESC FOR CONNECTION +--echo # instead of displaying an error. +--echo # +--error ER_SET_CONSTANTS_ONLY +EXPLAIN FOR CONNECTION INTERVAL TRUE IN (SELECT 1) YEAR_MONTH + FALSE=TRUE NOT IN (SELECT 1); + +--error ER_SET_CONSTANTS_ONLY +DESC FOR CONNECTION INTERVAL TRUE IN (SELECT 1) YEAR_MONTH + FALSE=TRUE NOT IN (SELECT 1); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 35f81d02942..b8c43643661 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14249,15 +14249,19 @@ explain_for_connection: SHOW EXPLAIN FOR command. It was introduced for compatibility with MySQL which implements EXPLAIN FOR CONNECTION command */ - describe_command opt_format_json FOR_SYM CONNECTION_SYM expr + describe_command opt_format_json { - LEX *lex=Lex; - lex->wild=0; + LEX *lex= Lex; + lex->wild= 0; lex->ident= null_clex_str; if (Lex->main_select_push()) MYSQL_YYABORT; lex->init_select(); lex->current_select->parsing_place= SELECT_LIST; + } + FOR_SYM CONNECTION_SYM expr + { + LEX *lex= Lex; lex->create_info.init(); Select->parsing_place= NO_MATTER; Lex->pop_select(); //main select @@ -14265,7 +14269,7 @@ explain_for_connection: if (unlikely(prepare_schema_table(thd, Lex, 0, Lex->explain_json ? SCH_EXPLAIN_JSON : SCH_EXPLAIN_TABULAR))) MYSQL_YYABORT; - add_value_to_list(thd, $5); + add_value_to_list(thd, $6); } ; From f2b48e565c091e0bc913cf8f171ebc5e82e00940 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Mon, 19 Jan 2026 17:04:46 +0700 Subject: [PATCH 098/152] MDEV-38574 Rename cloning functions of class Item and descendants Rename cloning methods of class Item and its descendants in the following way: (from) (to) do_build_clone -> deep_copy build_clone -> deep_copy_with_checks do_get_copy -> shallow_copy get_copy -> shallow_copy_with_checks to better reflect their functionality. Also make Item::deep_copy() and shallow_copy() protected. Outside users should call deep_copy_with_checks() and shallow_copy_with_checks(). --- plugin/func_test/plugin.cc | 2 +- plugin/type_inet/item_inetfunc.h | 16 +- sql/field.cc | 2 +- sql/item.cc | 25 +- sql/item.h | 390 ++++++++++++++++++++----------- sql/item_cmpfunc.cc | 18 +- sql/item_cmpfunc.h | 192 ++++++++++----- sql/item_func.h | 321 +++++++++++++++++-------- sql/item_geofunc.h | 170 ++++++++++---- sql/item_jsonfunc.h | 104 ++++++--- sql/item_row.cc | 6 +- sql/item_row.h | 6 +- sql/item_strfunc.h | 341 +++++++++++++++++++-------- sql/item_subselect.h | 7 +- sql/item_sum.h | 110 ++++++--- sql/item_timefunc.h | 195 ++++++++++++---- sql/item_vers.h | 18 +- sql/item_windowfunc.h | 50 ++-- sql/item_xmlfunc.cc | 51 ++-- sql/item_xmlfunc.h | 8 +- sql/opt_split.cc | 4 +- sql/opt_subselect.cc | 4 +- sql/procedure.h | 16 +- sql/sql_derived.cc | 2 +- sql/sql_lex.cc | 2 +- sql/sql_table.cc | 2 +- sql/sql_type_fixedbin.h | 29 ++- sql/table.cc | 2 +- 28 files changed, 1464 insertions(+), 629 deletions(-) diff --git a/plugin/func_test/plugin.cc b/plugin/func_test/plugin.cc index 2b60be68042..560c1819977 100644 --- a/plugin/func_test/plugin.cc +++ b/plugin/func_test/plugin.cc @@ -42,7 +42,7 @@ public: } const char *fully_qualified_func_name() const override { return "sysconst_test()"; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/plugin/type_inet/item_inetfunc.h b/plugin/type_inet/item_inetfunc.h index 73aed8c1f44..3e31a817ff3 100644 --- a/plugin/type_inet/item_inetfunc.h +++ b/plugin/type_inet/item_inetfunc.h @@ -45,7 +45,7 @@ public: unsigned_flag= 1; return FALSE; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -72,7 +72,7 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -118,7 +118,7 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } String *val_str(String *to) override; @@ -156,7 +156,7 @@ public: return FALSE; } String *val_str_ascii(String *to) override; - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -178,7 +178,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("is_ipv4") }; return name; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } bool val_bool() override; @@ -201,7 +201,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("is_ipv6") }; return name; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } bool val_bool() override; @@ -223,7 +223,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("is_ipv4_compat") }; return name; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } bool val_bool() override; }; @@ -244,7 +244,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("is_ipv4_mapped") }; return name; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } bool val_bool() override; }; diff --git a/sql/field.cc b/sql/field.cc index 849bb7d33c7..6b4c089e830 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11743,7 +11743,7 @@ Virtual_column_info* Virtual_column_info::clone(THD *thd) return NULL; if (expr) { - dst->expr= expr->build_clone(thd); + dst->expr= expr->deep_copy_with_checks(thd); if (!dst->expr) return NULL; } diff --git a/sql/item.cc b/sql/item.cc index a651ef452a0..735f1cbd8c4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2305,7 +2305,8 @@ public: Item_ident::print(str, query_type); } Ref_Type ref_type() override final { return AGGREGATE_REF; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2803,7 +2804,7 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, @retval 0 on a failure */ -Item* Item_func_or_sum::do_build_clone(THD *thd) const +Item* Item_func_or_sum::deep_copy(THD *thd) const { Item *copy_tmp_args[2]= {0,0}; Item **copy_args= copy_tmp_args; @@ -2816,12 +2817,12 @@ Item* Item_func_or_sum::do_build_clone(THD *thd) const } for (uint i= 0; i < arg_count; i++) { - Item *arg_clone= args[i]->build_clone(thd); + Item *arg_clone= args[i]->deep_copy_with_checks(thd); if (unlikely(!arg_clone)) return 0; copy_args[i]= arg_clone; } - Item_func_or_sum *copy= static_cast(get_copy(thd)); + Item_func_or_sum *copy= static_cast(shallow_copy_with_checks(thd)); if (unlikely(!copy)) return 0; if (arg_count > 2) @@ -3123,13 +3124,13 @@ Item_sp::init_result_field(THD *thd, uint max_length, uint maybe_null, 0 if an error occurred */ -Item* Item_ref::do_build_clone(THD *thd) const +Item* Item_ref::deep_copy(THD *thd) const { - Item_ref *copy= (Item_ref *) get_copy(thd); + Item_ref *copy= (Item_ref *) shallow_copy_with_checks(thd); if (unlikely(!copy) || unlikely(!(copy->ref= (Item**) alloc_root(thd->mem_root, sizeof(Item*)))) || - unlikely(!(*copy->ref= (* ref)->build_clone(thd)))) + unlikely(!(*copy->ref= (* ref)->deep_copy_with_checks(thd)))) return 0; return copy; } @@ -7955,7 +7956,7 @@ Item *Item::build_pushable_cond(THD *thd, { if (with_sum_func()) return 0; - return build_clone(thd); + return deep_copy_with_checks(thd); } return 0; } @@ -8073,7 +8074,7 @@ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg) Item *producing_item= find_producing_item(this, sel); if (producing_item) { - Item *producing_clone= producing_item->build_clone(thd); + Item *producing_clone= producing_item->deep_copy_with_checks(thd); if (producing_clone) producing_clone->marker|= MARKER_SUBSTITUTION; return producing_clone; @@ -8091,7 +8092,7 @@ Item *Item_direct_view_ref::derived_field_transformer_for_where(THD *thd, st_select_lex *sel= (st_select_lex *)arg; Item *producing_item= find_producing_item(this, sel); DBUG_ASSERT (producing_item != NULL); - return producing_item->build_clone(thd); + return producing_item->deep_copy_with_checks(thd); } return (*ref); } @@ -8104,7 +8105,7 @@ Item *Item_field::grouping_field_transformer_for_where(THD *thd, uchar *arg) if (gr_field) { Item *producing_clone= - gr_field->corresponding_item->build_clone(thd); + gr_field->corresponding_item->deep_copy_with_checks(thd); if (producing_clone) producing_clone->marker|= MARKER_SUBSTITUTION; return producing_clone; @@ -8127,7 +8128,7 @@ Item_direct_view_ref::grouping_field_transformer_for_where(THD *thd, st_select_lex *sel= (st_select_lex *)arg; Field_pair *gr_field= find_matching_field_pair(this, sel->grouping_tmp_fields); - return gr_field->corresponding_item->build_clone(thd); + return gr_field->corresponding_item->deep_copy_with_checks(thd); } void Item_field::print(String *str, enum_query_type query_type) diff --git a/sql/item.h b/sql/item.h index cbfaa2dd1c4..1cfef72b536 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1888,15 +1888,15 @@ public: /* Create a shallow copy of the item (usually invoking copy constructor). - For deep copying see build_clone(). + For deep copying see deep_copy_with_checks(). Return value: - pointer to a copy of the Item - nullptr if the item is not copyable */ - Item *get_copy(THD *thd) const + Item *shallow_copy_with_checks(THD *thd) const { - Item *copy= do_get_copy(thd); + Item *copy= shallow_copy(thd); if (copy) { // Make sure the copy is of same type as this item @@ -1912,9 +1912,9 @@ public: - pointer to a clone of the Item - nullptr if the item is not clonable */ - Item* build_clone(THD *thd) const + Item* deep_copy_with_checks(THD *thd) const { - Item *clone= do_build_clone(thd); + Item *clone= deep_copy(thd); if (clone) { // Make sure the clone is of same type as this item @@ -1932,7 +1932,8 @@ public: Note: the clone may have item type different from this (i.e., instance of another basic constant class may be returned). - For real clones look at build_clone()/get_copy() methods + For real clones look at deep_copy_with_checks()/shallow_copy_with_checks() + methods */ virtual Item *clone_item(THD *thd) const { return nullptr; } @@ -2795,18 +2796,18 @@ public: protected: /* - Service function for public method get_copy(). See comments for get_copy() - above. Override this method in derived classes to create shallow copies of - the item + Service function for public method shallow_copy_with_checks(). + See comments for shallow_copy_with_checks() above. Override this method + in derived classes to create shallow copies of the item */ - virtual Item *do_get_copy(THD *thd) const = 0; + virtual Item *shallow_copy(THD *thd) const = 0; /* - Service function for public method build_clone(). See comments for - build_clone() above. Override this method in derived classes to create - deep copies (clones) of the item where possible + Service function for public method deep_copy_with_checks(). See comments + for deep_copy_with_checks() above. Override this method in derived classes + to create deep copies (clones) of the item where possible */ - virtual Item* do_build_clone(THD *thd) const = 0; + virtual Item *deep_copy(THD *thd) const = 0; }; MEM_ROOT *get_thd_memroot(THD *thd); @@ -3268,10 +3269,6 @@ public: bool append_for_log(THD *thd, String *str) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } - /* Override the inherited create_field_for_create_select(), because we want to preserve the exact data type for: @@ -3297,6 +3294,12 @@ public: my_error(ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0)); return false; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -3316,8 +3319,9 @@ public: pos_in_q, len_in_q) { } - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } +protected: + Item *shallow_copy(THD *) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -3351,8 +3355,9 @@ public: bool append_for_log(THD *thd, String *str) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } +protected: + Item *shallow_copy(THD *) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -3374,8 +3379,9 @@ public: bool fix_fields(THD *thd, Item **it) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } +protected: + Item *shallow_copy(THD *) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -3419,11 +3425,13 @@ public: purposes. */ void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } private: uint m_case_expr_id; + +protected: + Item *shallow_copy(THD *) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; /***************************************************************************** @@ -3500,9 +3508,12 @@ public: { return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -3879,9 +3890,6 @@ public: bool cleanup_excluding_const_fields_processor(void *arg) override { return field && const_item() ? 0 : cleanup_processor(arg); } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - Item* do_build_clone(THD *thd) const override { return get_copy(thd); } bool is_outer_field() const override { DBUG_ASSERT(fixed()); @@ -3891,6 +3899,12 @@ public: friend class Item_default_value; friend class Item_insert_value; friend class st_select_lex_unit; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item* deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -3905,8 +3919,6 @@ public: :Item_field(thd, field), Item_args() { } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } const Type_handler *type_handler() const override { return &type_handler_row; } @@ -3923,6 +3935,10 @@ public: return false; } bool row_create_items(THD *thd, List *list); + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -4009,9 +4025,12 @@ public: Item_basic_constant *make_string_literal_concat(THD *thd, const LEX_CSTRING *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; class Item_null_result :public Item_null @@ -4456,8 +4475,6 @@ public: bool append_for_log(THD *thd, String *str) override; bool check_vcol_func_processor(void *) override { return false; } - Item *do_get_copy(THD *thd) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } bool add_as_clone(THD *thd); void sync_clones(); @@ -4467,6 +4484,7 @@ public: { invalid_default_param(); } + private: void invalid_default_param() const; bool set_value(THD *thd, sp_rcontext *ctx, Item **it) override; @@ -4499,6 +4517,10 @@ private: Mem_root_array m_clones; Item_field *m_associated_field; Field *m_default_field; + +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -4558,9 +4580,12 @@ public: Item *neg(THD *thd) override; decimal_digits_t decimal_precision() const override { return (decimal_digits_t) (max_length - MY_TEST(value < 0)); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -4590,9 +4615,12 @@ public: predicate at various condition optimization stages in sql_select. */ } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -4604,7 +4632,9 @@ public: void set_join_tab_idx(uint8 join_tab_idx_arg) override { DBUG_ASSERT(0); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4621,7 +4651,9 @@ public: Item *neg(THD *thd) override; decimal_digits_t decimal_precision() const override { return decimal_digits_t(max_length); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4687,9 +4719,12 @@ public: decimal_digits_t decimal_precision() const override { return decimal_value.precision(); } void set_decimal_value(my_decimal *value_par); - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -4736,9 +4771,12 @@ public: Item *clone_item(THD *thd) const override; Item *neg(THD *thd) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -4758,7 +4796,9 @@ public: { return const_charset_converter(thd, tocs, true, func_name); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4900,10 +4940,11 @@ public: const LEX_CSTRING *) override; Item *make_odbc_literal(THD *thd, const LEX_CSTRING *typestr) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } - + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -4922,7 +4963,9 @@ public: { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4936,7 +4979,9 @@ public: Item_string_sys(THD *thd, const char *str): Item_string(thd, str, (uint) strlen(str), system_charset_info) { } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4952,7 +4997,9 @@ public: Item_string(thd, str, (uint) strlen(str), &my_charset_latin1, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII) { } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4990,7 +5037,9 @@ public: // require fix_fields() to be re-run for every statement. return mark_unsupported_function(func_name.str, arg, VCOL_TIME_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -5009,7 +5058,9 @@ public: { return mark_unsupported_function("safe_string", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -5126,9 +5177,12 @@ public: return field->store_hex_hybrid(str_value.ptr(), str_value.length()); } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5171,9 +5225,12 @@ public: collation.collation); } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5182,7 +5239,9 @@ class Item_bin_string: public Item_hex_hybrid public: Item_bin_string(THD *thd, const char *str, size_t str_length); void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -5236,9 +5295,12 @@ public: { m_value= value; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5332,9 +5394,12 @@ public: return update_null() ? 0 : cached_time.valid_date_to_packed(); } bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5384,9 +5449,12 @@ public: { return Time(thd, this).to_native(to, decimals); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5449,9 +5517,12 @@ public: return update_null() ? 0 : cached_time.valid_datetime_to_packed(); } bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5494,9 +5565,12 @@ public: cached_time.copy_to_mysql_time(ltime); return (null_value= false); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5519,9 +5593,12 @@ public: cached_time.copy_to_mysql_time(ltime); return (null_value= false); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -5743,7 +5820,7 @@ public: virtual bool fix_length_and_dec()= 0; bool const_item() const override { return const_item_cache; } table_map used_tables() const override { return used_tables_cache; } - Item* do_build_clone(THD *thd) const override; + Item* deep_copy(THD *thd) const override; Sql_mode_dependency value_depends_on_sql_mode() const override { return Item_args::value_depends_on_sql_mode_bit_or().soft_to_hard(); @@ -5998,12 +6075,6 @@ public: DBUG_ASSERT(ref); return (*ref)->is_outer_field(); } - Item *do_build_clone(THD *thd) const override; - /** - Checks if the item tree that ref points to contains a subquery. - */ - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } bool excl_dep_on_table(table_map tab_map) override { table_map used= used_tables(); @@ -6033,6 +6104,11 @@ public: } Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg) override { return (*ref)->field_transformer_for_having_pushdown(thd, arg); } + +protected: + Item *deep_copy(THD *thd) const override; + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -6078,14 +6154,16 @@ public: longlong val_datetime_packed(THD *) override; longlong val_time_packed(THD *) override; Ref_Type ref_type() override { return DIRECT_REF; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } /* Should be called if ref is changed */ inline void ref_changed() { set_properties(); } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -6245,9 +6323,10 @@ public: { return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *) const override { return nullptr; } + Item *deep_copy(THD *) const override { return nullptr; } }; @@ -6459,8 +6538,10 @@ public: my_decimal *val_decimal_result(my_decimal *val) override; bool val_bool_result() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: Item *field_transformer_for_having_pushdown(THD *, uchar *) override { return this; } }; @@ -6522,9 +6603,11 @@ public: table_map not_null_tables() const override { return 0; } Ref_Type ref_type() override { return OUTER_REF; } bool check_inner_refs_processor(void * arg) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -6561,7 +6644,8 @@ public: bool val_native(THD *thd, Native *to) override; void print(String *str, enum_query_type query_type) override; table_map used_tables() const override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -6589,9 +6673,11 @@ public: } Item *clone_item(THD *thd) const override; Item *real_item() override { return ref; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; #ifdef MYSQL_SERVER @@ -6737,9 +6823,11 @@ public: } void copy() override; int save_in_field(Field *field, bool no_conversions) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -6819,9 +6907,11 @@ public: DBUG_ASSERT(sane()); return null_value || m_value.to_native(to, decimals); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7021,7 +7111,8 @@ public: description */ bool associate_with_target_field(THD *thd, Item_field *field) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { Item_default_value *new_item= (Item_default_value *) get_item_copy(thd, this); @@ -7029,7 +7120,8 @@ public: new_item->m_share_field= 1; return new_item; } - Item* do_build_clone(THD *thd) const override { return get_copy(thd); } + Item* deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } private: bool tie_field(THD *thd); }; @@ -7116,9 +7208,11 @@ public: param->set_default(true); return false; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7151,9 +7245,11 @@ public: return false; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7201,7 +7297,8 @@ public: { return mark_unsupported_function("value()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -7276,9 +7373,11 @@ Item_trigger_field(THD *thd, Name_resolution_context *context_arg, Item *copy_or_same(THD *) override { return this; } Item *get_tmp_table_item(THD *thd) override { return copy_or_same(thd); } void cleanup() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } private: void set_required_privilege(bool rw) override; @@ -7508,9 +7607,11 @@ public: bool cache_value() override; int save_in_field(Field *field, bool no_conversions) override; Item *convert_to_basic_const_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7530,7 +7631,8 @@ public: DBUG_ASSERT(!is_cond()); return Item_cache_bool::val_bool(); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -7544,7 +7646,8 @@ public: { return type_handler_year.Item_get_date_with_warn(thd, this, to, mode); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7581,7 +7684,7 @@ public: Item_cache_time(THD *thd) :Item_cache_temporal(thd, &type_handler_time2) { } bool cache_value() override; - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } Item *make_literal(THD *) override; longlong val_datetime_packed(THD *thd) override @@ -7621,8 +7724,10 @@ class Item_cache_datetime: public Item_cache_temporal public: Item_cache_datetime(THD *thd) :Item_cache_temporal(thd, &type_handler_datetime2) { } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: Item *make_literal(THD *) override; longlong val_datetime_packed(THD *) override { @@ -7656,8 +7761,10 @@ class Item_cache_date: public Item_cache_temporal public: Item_cache_date(THD *thd) :Item_cache_temporal(thd, &type_handler_newdate) { } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: Item *make_literal(THD *) override; longlong val_datetime_packed(THD *) override { @@ -7689,9 +7796,12 @@ class Item_cache_timestamp: public Item_cache public: Item_cache_timestamp(THD *thd) :Item_cache(thd, &type_handler_timestamp2) { } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } +public: bool cache_value() override; String* val_str(String *to) override { @@ -7750,9 +7860,11 @@ public: :Item_cache_real(thd, &type_handler_double) { } String *val_str(String *str) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7763,9 +7875,11 @@ public: :Item_cache_real(thd, &type_handler_float) { } String *val_str(String *str) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7787,9 +7901,11 @@ public: } bool cache_value() override; Item *convert_to_basic_const_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7818,9 +7934,11 @@ public: int save_in_field(Field *field, bool no_conversions) override; bool cache_value() override; Item *convert_to_basic_const_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -7844,9 +7962,13 @@ public: */ return Item::safe_charset_converter(thd, tocs); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { + return shallow_copy_with_checks(thd); + } }; @@ -7922,9 +8044,13 @@ public: } bool cache_value() override; void set_null() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { + return shallow_copy_with_checks(thd); + } }; @@ -7993,8 +8119,9 @@ public: make_and_init_table_field(root, &name, Record_addr(maybe_null()), *this, table); } - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *) const override { return nullptr; } +protected: + Item *shallow_copy(THD *) const override { return nullptr; } + Item *deep_copy(THD *) const override { return nullptr; } }; @@ -8148,8 +8275,10 @@ public: Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override; Item *get_tmp_table_item(THD *thd) override { return m_item->get_tmp_table_item(thd); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: COND *build_equal_items(THD *thd, COND_EQUAL *inherited, bool link_item_fields, COND_EQUAL **cond_equal_ref) override @@ -8219,12 +8348,13 @@ public: { return m_item->excl_dep_on_grouping_fields(sel); } bool is_expensive() override { return m_item->is_expensive(); } void set_item(Item *item) { m_item= item; } - Item *do_build_clone(THD *thd) const override + Item *deep_copy(THD *thd) const override { - Item *clone_item= m_item->build_clone(thd); + Item *clone_item= m_item->deep_copy_with_checks(thd); if (clone_item) { - Item_direct_ref_to_item *copy= (Item_direct_ref_to_item *) get_copy(thd); + Item_direct_ref_to_item *copy= + (Item_direct_ref_to_item *) shallow_copy_with_checks(thd); if (!copy) return 0; copy->set_item(clone_item); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2135729046f..ce507fa5a49 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1853,13 +1853,13 @@ bool Item_func_eq::val_bool() } -Item *Item_func_eq::do_build_clone(THD *thd) const +Item *Item_func_eq::deep_copy(THD *thd) const { /* Clone the parent and cast to the child class since there is nothing specific for Item_func_eq */ - return (Item_func_eq*) Item_bool_rowready_func2::do_build_clone(thd); + return (Item_func_eq*) Item_bool_rowready_func2::deep_copy(thd); } @@ -5551,16 +5551,16 @@ void Item_cond::neg_arguments(THD *thd) 0 if an error occurred */ -Item *Item_cond::do_build_clone(THD *thd) const +Item *Item_cond::deep_copy(THD *thd) const { - Item_cond *copy= (Item_cond *) get_copy(thd); + Item_cond *copy= (Item_cond *) shallow_copy_with_checks(thd); if (!copy) return 0; copy->list.empty(); for (const Item &item : list) { - Item *arg_clone= item.build_clone(thd); + Item *arg_clone= item.deep_copy_with_checks(thd); if (!arg_clone) return 0; if (copy->list.push_back(arg_clone, thd->mem_root)) @@ -7903,9 +7903,9 @@ bool Item_equal::create_pushable_equalities(THD *thd, if (right_item) { Item_func_eq *eq= 0; - Item *left_item_clone= left_item->build_clone(thd); + Item *left_item_clone= left_item->deep_copy_with_checks(thd); Item *right_item_clone= !clone_const ? - right_item : right_item->build_clone(thd); + right_item : right_item->deep_copy_with_checks(thd); if (!left_item_clone || !right_item_clone) return true; eq= new (thd->mem_root) Item_func_eq(thd, @@ -7932,8 +7932,8 @@ bool Item_equal::create_pushable_equalities(THD *thd, if (checker && !((item->*checker) (arg))) continue; Item_func_eq *eq= 0; - Item *left_item_clone= left_item->build_clone(thd); - Item *right_item_clone= item->build_clone(thd); + Item *left_item_clone= left_item->deep_copy_with_checks(thd); + Item *right_item_clone= item->deep_copy_with_checks(thd); if (!(left_item_clone && right_item_clone)) return true; left_item_clone->set_item_equal(NULL); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index bb6f9009daf..2112ca72ebc 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -310,7 +310,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("istrue") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -331,10 +333,12 @@ public: return name; } bool find_not_null_fields(table_map allowed) override { return false; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } bool eval_not_null_tables(void *) override { not_null_tables_cache= 0; return false; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -352,7 +356,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("isfalse") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -373,10 +379,12 @@ public: return name; } bool find_not_null_fields(table_map allowed) override { return false; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } bool eval_not_null_tables(void *) override { not_null_tables_cache= 0; return false; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -450,9 +458,11 @@ public: void restore_first_argument(); Item* get_wrapped_in_subselect_item() { return args[1]; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } enum precedence precedence() const override { return args[1]->precedence(); } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -623,10 +633,10 @@ public: return add_key_fields_optimize_op(join, key_fields, and_level, usable_tables, sargables, false); } - Item *do_build_clone(THD *thd) const override + Item *deep_copy(THD *thd) const override { Item_bool_rowready_func2 *clone= - (Item_bool_rowready_func2 *) Item_func::do_build_clone(thd); + (Item_bool_rowready_func2 *) Item_func::deep_copy(thd); if (clone) { clone->cmp.comparators= 0; @@ -661,7 +671,8 @@ public: Item_args::propagate_equal_fields(thd, Context_boolean(), cond); return this; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -685,7 +696,8 @@ public: Item *neg_transformer(THD *thd) override; bool fix_fields(THD *, Item **) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -738,7 +750,8 @@ public: void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -771,11 +784,11 @@ public: void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; test_sum_item= 0;}; bool empty_underlying_subquery(); Item *neg_transformer(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; - class Item_func_nop_all :public Item_func_not_all { public: @@ -788,11 +801,11 @@ public: return name; } Item *neg_transformer(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; - class Item_func_eq :public Item_bool_rowready_func2 { bool abort_on_null; @@ -833,9 +846,11 @@ public: uint in_equality_no; uint exists2in_reserved_items() override { return 1; }; friend class Arg_comparator; - Item *do_get_copy(THD *thd) const override + Item *deep_copy(THD *thd) const override; + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override; }; class Item_func_equal final :public Item_bool_rowready_func2 @@ -864,7 +879,9 @@ public: return add_key_fields_optimize_op(join, key_fields, and_level, usable_tables, sargables, true); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -884,7 +901,9 @@ public: return name; } Item *negated_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -904,7 +923,9 @@ public: return name; } Item *negated_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -924,7 +945,9 @@ public: return name; } Item *negated_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -944,7 +967,9 @@ public: return name; } Item *negated_item(THD *thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -969,7 +994,9 @@ public: Item *negated_item(THD *thd) override; void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1070,9 +1097,6 @@ public: cond); return this; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - longlong val_int_cmp_string(); longlong val_int_cmp_datetime(); longlong val_int_cmp_time(); @@ -1080,6 +1104,10 @@ public: longlong val_int_cmp_int(); longlong val_int_cmp_real(); longlong val_int_cmp_decimal(); + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -1106,7 +1134,9 @@ public: fix_char_length(2); // returns "1" or "0" or "-1" return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1144,7 +1174,9 @@ public: str->append(func_name_cstring()); print_args(str, 0, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1176,7 +1208,9 @@ public: return name; } table_map not_null_tables() const override { return 0; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1271,7 +1305,9 @@ public: } table_map not_null_tables() const override { return 0; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1350,8 +1386,11 @@ public: bool eval_not_null_tables(void *opt_arg) override; void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } + private: void cache_type_info(Item *source); }; @@ -1376,7 +1415,9 @@ public: { return fix_length_and_dec2_eliminate_null(args + 1); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1470,8 +1511,6 @@ public: cond, &args[2]); return this; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } Item *derived_field_transformer_for_having(THD *thd, uchar *arg) override { reset_first_arg_if_needed(); return this; } Item *derived_field_transformer_for_where(THD *thd, uchar *arg) override @@ -1482,6 +1521,10 @@ public: { reset_first_arg_if_needed(); return this; } Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg) override { reset_first_arg_if_needed(); return this; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -2421,7 +2464,9 @@ public: return this; } Item *find_item() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2471,16 +2516,18 @@ public: Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) override; Item *find_item() override; - Item *do_build_clone(THD *thd) const override +protected: + Item *deep_copy(THD *thd) const override { Item_func_case_simple *clone= (Item_func_case_simple *) - Item_func_case::do_build_clone(thd); + Item_func_case::deep_copy(thd); uint ncases= when_count(); if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases)) return NULL; return clone; - } - Item *do_get_copy(THD *thd) const override + } + + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2500,7 +2547,9 @@ public: void print(String *str, enum_query_type query_type) override; bool fix_length_and_dec() override; Item *find_item() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2672,11 +2721,9 @@ public: void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge) override; bool count_sargable_conds(void *arg) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override + Item *deep_copy(THD *thd) const override { - Item_func_in *clone= (Item_func_in *) Item_func::do_build_clone(thd); + Item_func_in *clone= (Item_func_in *) Item_func::deep_copy(thd); if (clone) { clone->array= 0; @@ -2691,6 +2738,10 @@ public: Item *in_predicate_to_in_subs_transformer(THD *thd, uchar *arg) override; Item *in_predicate_to_equality_transformer(THD *thd, uchar *arg) override; uint32 max_length_of_left_expr(); + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class cmp_item_row :public cmp_item @@ -2824,7 +2875,9 @@ public: table_map not_null_tables() const override { return 0; } bool find_not_null_fields(table_map allowed) override; Item *neg_transformer(THD *thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2880,7 +2933,9 @@ public: Item *neg_transformer(THD *thd) override; void print(String *str, enum_query_type query_type) override; void top_level_item() override { abort_on_null=1; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3042,15 +3097,16 @@ public: } bool find_selective_predicates_list_processor(void *arg) override; - - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; - typedef struct pcre2_real_code_8 pcre2_code; typedef struct pcre2_real_match_data_8 pcre2_match_data; #define PCRE2_SIZE size_t + class Regexp_processor_pcre { pcre2_code *m_pcre; @@ -3140,7 +3196,6 @@ public: return name; } enum precedence precedence() const override { return IN_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override { return 0; } void print(String *str, enum_query_type query_type) override { print_op(str, query_type); @@ -3148,6 +3203,8 @@ public: CHARSET_INFO *compare_collation() const override { return cmp_collation.collation; } +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; @@ -3184,7 +3241,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("regexp_instr") }; return name; } - Item *do_get_copy(THD *thd) const override { return 0; } +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; @@ -3283,7 +3341,7 @@ public: } bool eval_not_null_tables(void *opt_arg) override; bool find_not_null_fields(table_map allowed) override; - Item *do_build_clone(THD *thd) const override; + Item *deep_copy(THD *thd) const override; bool excl_dep_on_table(table_map tab_map) override; bool excl_dep_on_grouping_fields(st_select_lex *sel) override; @@ -3472,7 +3530,9 @@ public: void set_context_field(Item_field *ctx_field) { context_field= ctx_field; } void set_link_equal_fields(bool flag) { link_equal_fields= flag; } - Item* do_get_copy(THD *thd) const override { return 0; } +protected: + Item* shallow_copy(THD *thd) const override { return 0; } +public: /* This does not comply with the specification of the virtual method, but Item_equal items are processed distinguishly anyway @@ -3643,7 +3703,9 @@ public: table_map usable_tables, SARGABLE_PARAM **sargables) override; SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3671,7 +3733,8 @@ public: table_map not_null_tables() const override { return and_tables_cache; } Item *copy_andor_structure(THD *thd) override; Item *neg_transformer(THD *thd) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3686,7 +3749,8 @@ public: return name; } bool need_parentheses_in_default() override { return false; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3702,7 +3766,8 @@ public: return name; } bool need_parentheses_in_default() override { return false; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3735,7 +3800,8 @@ public: return name; } bool val_bool() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3754,7 +3820,8 @@ public: return name; } bool val_bool() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3773,7 +3840,8 @@ public: return name; } bool val_bool() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_func.h b/sql/item_func.h index 46c73c41dd9..67966af99dd 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1293,13 +1293,15 @@ public: bool fix_length_and_dec() override; const Type_handler *type_handler() const override { return &type_handler_slong; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("") }; return name; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class Item_func_hash_mariadb_100403: public Item_func_hash @@ -1309,13 +1311,15 @@ public: :Item_func_hash(thd, item) {} longlong val_int() override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("") }; return name; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class Item_longlong_func: public Item_int_func @@ -1375,7 +1379,9 @@ public: { return Cursor_ref::print_func(str, func_name_cstring()); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1400,7 +1406,9 @@ public: return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1472,7 +1480,9 @@ public: decimal_digits_t decimal_precision() const override { return args[0]->decimal_precision(); } bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1508,7 +1518,9 @@ public: decimal_digits_t decimal_precision() const override { return decimal_digits_t(max_length); } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1550,7 +1562,9 @@ public: } void print(String *str, enum_query_type query_type) override; bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1605,7 +1619,9 @@ public: nr.to_string(str, decimals); return str; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1627,7 +1643,9 @@ public: return name; } double val_real() override { return val_real_with_truncate(DBL_MAX); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1657,7 +1675,9 @@ public: longlong int_op() override; double real_op() override; my_decimal *decimal_op(my_decimal *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1696,7 +1716,9 @@ public: Item_func_additive_op::fix_length_and_dec_int(); fix_unsigned_flag(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1719,7 +1741,9 @@ public: bool fix_length_and_dec() override; bool check_partition_func_processor(void *int_arg) override {return FALSE;} bool check_vcol_func_processor(void *arg) override { return FALSE;} - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1742,7 +1766,9 @@ public: void fix_length_and_dec_double(); void fix_length_and_dec_int(); void result_precision() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1770,7 +1796,9 @@ public: bool check_partition_func_processor(void *int_arg) override {return FALSE;} bool check_vcol_func_processor(void *arg) override { return FALSE;} bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1808,7 +1836,9 @@ public: } bool check_partition_func_processor(void *int_arg) override {return FALSE;} bool check_vcol_func_processor(void *arg) override { return FALSE;} - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1839,7 +1869,9 @@ public: decimal_digits_t decimal_precision() const override { return args[0]->decimal_precision(); } bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1861,7 +1893,9 @@ public: void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1893,7 +1927,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("exp") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1908,7 +1944,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("ln") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1924,7 +1962,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("log") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1939,7 +1979,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("log2") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1954,7 +1996,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("log10") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1969,7 +2013,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sqrt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1984,7 +2030,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("pow") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1999,7 +2047,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("acos") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2013,7 +2063,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("asin") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2028,7 +2080,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("atan") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2042,7 +2096,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("cos") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2056,7 +2112,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sin") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2070,7 +2128,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("tan") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2084,7 +2144,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("cot") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2131,7 +2193,9 @@ public: my_decimal *decimal_op(my_decimal *) override; bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; bool time_op(THD *thd, MYSQL_TIME *ltime) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2151,7 +2215,9 @@ public: my_decimal *decimal_op(my_decimal *) override; bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; bool time_op(THD *thd, MYSQL_TIME *ltime) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2201,7 +2267,9 @@ public: */ return args[0]->real_type_handler()->Item_func_round_fix_length_and_dec(this); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2231,7 +2299,9 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2280,12 +2350,14 @@ public: return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override { return 0; } /* This function is used in insert, update and delete */ void store_pointer_to_row_counter(ha_rows *row_counter) { accepted_rows= row_counter; } + +protected: + Item *shallow_copy(THD *thd) const override { return 0; } }; void fix_rownum_pointers(THD *thd, SELECT_LEX *select_lex, ha_rows *ptr); @@ -2305,7 +2377,9 @@ public: decimal_digits_t decimal_precision() const override { return 1; } bool fix_length_and_dec() override { fix_char_length(2); return FALSE; } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2332,7 +2406,9 @@ public: max_length= float_length(decimals); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2439,7 +2515,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("least") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2452,7 +2530,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("greatest") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2492,7 +2572,9 @@ public: Type_std_attributes::set(*args[0]); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2518,7 +2600,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("octet_length") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2538,7 +2622,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("bit_length") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2553,7 +2639,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("char_length") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2585,9 +2673,11 @@ public: override { return this; } bool const_item() const override { return true; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } table_map used_tables() const override { return 0; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -2623,7 +2713,9 @@ public: return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2642,7 +2734,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2661,7 +2755,9 @@ public: return name; } bool fix_length_and_dec() override { max_length=3; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2679,7 +2775,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("ord") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2701,7 +2799,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2747,7 +2847,7 @@ public: return name; } enum precedence precedence() const override { return BITOR_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2763,7 +2863,8 @@ public: return name; } enum precedence precedence() const override { return BITAND_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2779,7 +2880,8 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2795,7 +2897,8 @@ public: return name; } enum precedence precedence() const override { return SHIFT_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2811,7 +2914,8 @@ public: return name; } enum precedence precedence() const override { return SHIFT_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2831,7 +2935,8 @@ public: str->append(func_name_cstring()); args[0]->print_parenthesised(str, query_type, precedence()); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2861,7 +2966,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2894,7 +3000,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2925,7 +3032,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3082,7 +3190,8 @@ class Item_func_udf_float :public Item_udf_func const Type_handler *type_handler() const override { return &type_handler_double; } bool fix_length_and_dec() override { fix_num_length_and_dec(); return FALSE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3109,7 +3218,8 @@ public: return &type_handler_slonglong; } bool fix_length_and_dec() override { decimals= 0; max_length= 21; return FALSE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3137,7 +3247,8 @@ public: const Type_handler *type_handler() const override { return &type_handler_newdecimal; } bool fix_length_and_dec() override { fix_num_length_and_dec(); return FALSE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3177,7 +3288,8 @@ public: const Type_handler *type_handler() const override { return string_type_handler(); } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3282,7 +3394,8 @@ class Item_func_get_lock final :public Item_func_lock set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override final +protected: + Item *shallow_copy(THD *thd) const override final { return get_item_copy(thd, this); } }; @@ -3298,7 +3411,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("release_all_locks") }; return name; } - Item *do_get_copy(THD *thd) const override final +protected: + Item *shallow_copy(THD *thd) const override final { return get_item_copy(thd, this); } }; @@ -3322,7 +3436,8 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override final +protected: + Item *shallow_copy(THD *thd) const override final { return get_item_copy(thd, this); } }; @@ -3363,7 +3478,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3392,7 +3508,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3513,8 +3630,10 @@ public: bool register_field_in_bitmap(void *arg) override; bool set_entry(THD *thd, bool create_if_not_exists); void cleanup() override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: bool excl_dep_on_table(table_map tab_map) override { return false; } }; @@ -3546,7 +3665,8 @@ public: table_map used_tables() const override { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } private: bool set_value(THD *thd, sp_rcontext *ctx, Item **it) override; @@ -3629,9 +3749,11 @@ public: void set_value(const char *str, uint length, CHARSET_INFO* cs); const Type_handler *type_handler() const override { return &type_handler_double; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -3693,7 +3815,8 @@ public: void cleanup() override; bool check_vcol_func_processor(void *arg) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3756,9 +3879,10 @@ public: { return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } private: /** Check whether storage engine for given table, @@ -3808,7 +3932,8 @@ public: return name; } enum precedence precedence() const override { return BITXOR_PRECEDENCE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3836,7 +3961,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3863,7 +3989,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3924,7 +4051,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4062,7 +4190,9 @@ public: { return TRUE; } - Item *do_get_copy(THD *thd) const override { return 0; } +protected: + Item *shallow_copy(THD *thd) const override { return 0; } +public: bool eval_not_null_tables(void *opt_arg) override { not_null_tables_cache= 0; @@ -4097,7 +4227,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4120,7 +4251,8 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4150,7 +4282,8 @@ public: max_length= 11; return FALSE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4177,7 +4310,8 @@ public: return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4218,7 +4352,8 @@ public: Item_func::update_used_tables(); copy_flags(last_value, item_base_t::MAYBE_NULL); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4272,8 +4407,10 @@ public: } } bool const_item() const override { return 0; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } +public: void print(String *str, enum_query_type query_type) override; bool check_vcol_func_processor(void *arg) override { @@ -4297,7 +4434,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("lastval") }; return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -4324,7 +4462,8 @@ public: return name; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 50938cc4913..4dbb75d774d 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -219,7 +219,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -241,7 +243,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -267,7 +271,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -284,7 +290,9 @@ public: } String *val_str_ascii(String *) override; bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -309,7 +317,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -336,7 +346,9 @@ public: } bool fix_length_and_dec() override; String *val_str_ascii(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -359,7 +371,9 @@ public: set_maybe_null(); return FALSE; }; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -398,7 +412,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -418,7 +434,9 @@ public: { return &type_handler_point; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -437,7 +455,9 @@ public: { return &type_handler_polygon; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -475,7 +495,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -498,7 +520,9 @@ public: { return &type_handler_point; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -527,7 +551,9 @@ public: } } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -564,7 +590,9 @@ public: } } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -624,7 +652,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("geometrycollection") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -644,7 +674,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("linestring") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -664,7 +696,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("polygon") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -686,7 +720,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("multilinestring") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -708,7 +744,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("multipoint") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -730,7 +768,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("multipolygon") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -782,7 +822,7 @@ public: usable_tables, sargables, false); } bool need_parentheses_in_default() override { return false; } - Item *do_build_clone(THD *thd) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -794,7 +834,9 @@ public: { } bool val_bool() override; LEX_CSTRING func_name_cstring() const override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -810,7 +852,9 @@ public: { } bool val_bool() override; LEX_CSTRING func_name_cstring() const override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -837,7 +881,9 @@ public: return name; } bool need_parentheses_in_default() override { return false; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -874,7 +920,9 @@ public: { Item_func::print(str, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -935,7 +983,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -954,7 +1004,9 @@ public: bool fix_length_and_dec() override { set_maybe_null(); return FALSE; } bool need_parentheses_in_default() override { return false; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -975,7 +1027,9 @@ public: } bool fix_length_and_dec() override { decimals=0; max_length=2; return FALSE; } decimal_digits_t decimal_precision() const override { return 1; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -992,7 +1046,9 @@ public: } bool fix_length_and_dec() override { decimals=0; max_length=2; return FALSE; } decimal_digits_t decimal_precision() const override { return 1; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1006,7 +1062,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("st_isring") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1023,7 +1081,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1045,7 +1105,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1067,7 +1129,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1085,7 +1149,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1103,7 +1169,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1121,7 +1189,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1143,7 +1213,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1167,7 +1239,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1185,7 +1259,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1206,7 +1282,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("st_distance") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1224,7 +1302,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("st_distance_sphere") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1248,7 +1328,9 @@ public: { return &type_handler_point; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1270,7 +1352,9 @@ class Item_func_gis_debug: public Item_long_func { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; #endif diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 58402376426..ef1b582c926 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -101,9 +101,11 @@ public: static const Lex_cstring fmt(STRING_WITH_LEN("json")); return to->set_format_name(fmt); } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } enum Functype functype() const override { return JSON_VALID_FUNC; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -122,9 +124,11 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } bool val_bool() override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -170,7 +174,9 @@ public: { return je->check_and_get_value_scalar(res, error); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -198,7 +204,9 @@ public: { return je->check_and_get_value_complex(res, error); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -217,7 +225,9 @@ public: } bool fix_length_and_dec() override; String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -236,7 +246,9 @@ public: } bool fix_length_and_dec() override; String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -291,7 +303,9 @@ public: double val_real() override; my_decimal *val_decimal(my_decimal *) override; uint get_n_paths() const override { return arg_count - 1; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -314,7 +328,9 @@ public: } bool fix_length_and_dec() override; bool val_bool() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -341,7 +357,9 @@ public: bool fix_fields(THD *thd, Item **ref) override; bool fix_length_and_dec() override; bool val_bool() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -363,7 +381,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_array") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -384,7 +404,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_array_append") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -400,7 +422,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_array_insert") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -418,7 +442,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_object") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -436,7 +462,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_merge_preserve") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -451,7 +479,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -482,7 +512,9 @@ public: } bool fix_length_and_dec() override; longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -502,7 +534,9 @@ public: } bool fix_length_and_dec() override { max_length= 10; return FALSE; } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -520,7 +554,9 @@ public: } bool fix_length_and_dec() override; String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -546,7 +582,9 @@ public: return (mode_insert ? (mode_replace ? json_set : json_insert) : json_replace); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -566,7 +604,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_remove") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -587,7 +627,9 @@ public: } bool fix_length_and_dec() override; String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -616,7 +658,9 @@ public: bool fix_length_and_dec() override; String *val_str(String *) override; uint get_n_paths() const override { return arg_count > 4 ? arg_count - 4 : 0; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -644,7 +688,9 @@ public: bool fix_length_and_dec() override; String *val_str(String *str) override; String *val_json(String *str) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -690,7 +736,9 @@ public: String* val_str(String *str) override; Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -739,7 +787,9 @@ public: String* val_str(String* str) override; Item *copy_or_same(THD* thd) override; void no_rows_in_result() override {} - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_row.cc b/sql/item_row.cc index d877bf605b9..a8e3ddadeb3 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -180,7 +180,7 @@ void Item_row::bring_value() } -Item* Item_row::do_build_clone(THD *thd) const +Item* Item_row::deep_copy(THD *thd) const { Item **copy_args= static_cast (alloc_root(thd->mem_root, sizeof(Item*) * arg_count)); @@ -188,12 +188,12 @@ Item* Item_row::do_build_clone(THD *thd) const return 0; for (uint i= 0; i < arg_count; i++) { - Item *arg_clone= args[i]->build_clone(thd); + Item *arg_clone= args[i]->deep_copy_with_checks(thd); if (!arg_clone) return 0; copy_args[i]= arg_clone; } - Item_row *copy= (Item_row *) get_copy(thd); + Item_row *copy= (Item_row *) shallow_copy_with_checks(thd); if (unlikely(!copy)) return 0; copy->args= copy_args; diff --git a/sql/item_row.h b/sql/item_row.h index 012bc0f29f0..9e3e87eeed2 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -148,9 +148,11 @@ public: } bool check_vcol_func_processor(void *arg) override {return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override; + Item *deep_copy(THD *thd) const override; }; #endif /* ITEM_ROW_INCLUDED */ diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 8bb8b3ddfe7..c05c5e3ad4f 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -155,7 +155,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("md5") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -171,7 +173,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sha") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -187,7 +191,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sha2") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -204,7 +210,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("to_base64") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -221,7 +229,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("from_base64") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -252,7 +262,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("aes_encrypt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -267,7 +279,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("aes_decrypt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -301,7 +315,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("concat") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -332,10 +348,10 @@ public: print_sql_mode_qualified_name(str, query_type); print_args_parenthesized(str, query_type); } - Item *do_get_copy(THD *thd) const override - { - return get_item_copy(thd, this); - } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -357,7 +373,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("decode_histogram") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -374,7 +392,9 @@ public: return name; } table_map not_null_tables() const override { return 0; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -390,7 +410,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("reverse") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -416,7 +438,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("replace") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -441,7 +465,9 @@ public: print_sql_mode_qualified_name(str, query_type); print_args_parenthesized(str, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -481,7 +507,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("regexp_replace") }; return name; } - Item *do_get_copy(THD *thd) const override { return 0;} +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; @@ -502,6 +529,8 @@ public: { return val_str_internal(str, true); } +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; @@ -526,7 +555,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("regexp_substr") }; return name; } - Item *do_get_copy(THD *thd) const override { return 0; } +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; @@ -544,7 +574,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("insert") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -571,7 +603,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -585,7 +619,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -603,7 +639,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("left") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -620,7 +658,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("right") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -649,7 +689,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("substr") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -685,7 +727,9 @@ public: print_sql_mode_qualified_name(str, query_type); print_args_parenthesized(str, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -702,9 +746,10 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("substring_index") }; return name; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -745,7 +790,9 @@ public: } void print(String *str, enum_query_type query_type) override; virtual LEX_CSTRING mode_name() const { return { "both", 4}; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -766,7 +813,9 @@ public: set_maybe_null(); return res; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -789,7 +838,9 @@ public: } LEX_CSTRING mode_name() const override { return { STRING_WITH_LEN("leading") }; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -810,7 +861,9 @@ public: set_maybe_null(); return res; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -829,7 +882,9 @@ public: } LEX_CSTRING mode_name() const override { return { STRING_WITH_LEN("trailing") }; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -850,7 +905,8 @@ public: set_maybe_null(); return res; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -893,7 +949,9 @@ public: } static char *alloc(THD *thd, const char *password, size_t pass_len, enum PW_Alg al); - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -920,7 +978,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("des_encrypt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -947,7 +1007,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("des_decrypt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -992,7 +1054,9 @@ public: { return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1016,9 +1080,10 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("encode") }; return name; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } + protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } virtual void crypto_transform(String *); private: /** Provide a seed for the PRNG sequence. */ @@ -1041,9 +1106,10 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("decode") }; return name; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } + protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } void crypto_transform(String *) override; }; @@ -1087,7 +1153,9 @@ public: } const char *fully_qualified_func_name() const override { return "database()"; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1115,7 +1183,9 @@ public: base_flags&= ~item_base_t::MAYBE_NULL; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1153,7 +1223,9 @@ public: { return save_str_value_in_field(field, &str_value); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1179,7 +1251,9 @@ public: return mark_unsupported_function(fully_qualified_func_name(), arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1217,7 +1291,9 @@ public: return mark_unsupported_function(fully_qualified_func_name(), arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1234,7 +1310,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("soundex") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1252,7 +1330,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("elt") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1270,7 +1350,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("make_set") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1291,7 +1373,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("format") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1320,9 +1404,12 @@ public: return name; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } -}; +} ; + class Item_func_chr :public Item_func_char { @@ -1340,7 +1427,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("chr") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1357,7 +1446,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("repeat") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1373,7 +1464,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("space") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1394,7 +1487,9 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1436,7 +1531,9 @@ public: return name; } Sql_mode_dependency value_depends_on_sql_mode() const override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1470,7 +1567,9 @@ public: print_sql_mode_qualified_name(str, query_type); print_args_parenthesized(str, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1496,7 +1595,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("lpad") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1530,7 +1631,9 @@ public: print_sql_mode_qualified_name(str, query_type); print_args_parenthesized(str, query_type); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1553,7 +1656,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1603,7 +1708,9 @@ public: fix_char_length(char_length); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1629,7 +1736,9 @@ public: max_length=(1+args[0]->max_length)/2; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1668,7 +1777,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("like_range_min") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1683,7 +1794,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("like_range_max") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; #endif @@ -1715,7 +1828,9 @@ public: return name; } bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1742,7 +1857,9 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1763,7 +1880,9 @@ class Item_func_export_set: public Item_str_func static LEX_CSTRING name= {STRING_WITH_LEN("export_set") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1790,7 +1909,9 @@ public: max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1886,9 +2007,11 @@ public: return name; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } int save_in_field(Field*, bool) override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class Item_func_set_collation :public Item_str_func @@ -1914,7 +2037,9 @@ public: return args[0]->field_for_view_update(); } bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1951,8 +2076,6 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("charset") }; return name; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } table_map used_tables() const override { return 0; } bool fix_length_and_dec() override { @@ -1970,6 +2093,10 @@ public: args[0]->charset_for_protocol()->cs_name.length; return false; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -1984,7 +2111,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("collation") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2024,7 +2153,9 @@ public: override { return this; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2043,7 +2174,9 @@ public: } bool fix_length_and_dec() override { max_length=10; return FALSE; } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2064,7 +2197,9 @@ public: set_maybe_null(); return FALSE; } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2091,7 +2226,9 @@ public: return name; } String *val_str(String *) override ZLIB_DEPENDED_FUNCTION - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2113,7 +2250,9 @@ public: return name; } String *val_str(String *) override ZLIB_DEPENDED_FUNCTION - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2147,7 +2286,9 @@ Item_func_uuid(THD *thd, bool without_separators_arg): Item_str_func(thd), return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2174,7 +2315,9 @@ public: String *val_str(String *) override; void print(String *str, enum_query_type query_type) override; enum Functype functype() const override { return DYNCOL_FUNC; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2192,7 +2335,9 @@ public: } String *val_str(String *) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2214,7 +2359,9 @@ public: decimals= 0; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2264,7 +2411,9 @@ public: bool get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, String *tmp); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2286,7 +2435,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2312,7 +2463,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; #ifdef WITH_WSREP @@ -2336,7 +2489,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2357,7 +2512,9 @@ public: set_maybe_null(); return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2375,7 +2532,9 @@ public: return name; } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; #endif /* WITH_WSREP */ diff --git a/sql/item_subselect.h b/sql/item_subselect.h index c26714b7e4c..c994d62cabb 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -278,11 +278,12 @@ public: void register_as_with_rec_ref(With_element *with_elem); void init_expr_cache_tracker(THD *thd); - Item* do_build_clone(THD *thd) const override { return nullptr; } - Item *do_get_copy(THD *thd) const override { return 0; } - st_select_lex *wrap_tvc_into_select(THD *thd, st_select_lex *tvc_sl); +protected: + Item* deep_copy(THD *thd) const override { return nullptr; } + Item *shallow_copy(THD *thd) const override { return nullptr; } + friend class select_result_interceptor; friend class Item_in_optimizer; friend bool Item_field::fix_fields(THD *, Item **); diff --git a/sql/item_sum.h b/sql/item_sum.h index 83c7d5cf9e0..dca9b882256 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -865,9 +865,6 @@ public: } Item *copy_or_same(THD* thd) override; void remove() override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - bool supports_removal() const override { return true; @@ -876,6 +873,10 @@ public: private: void add_helper(bool perform_removal); ulonglong count; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -940,13 +941,14 @@ public: return has_with_distinct() ? name_distinct : name_normal; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - bool supports_removal() const override { return true; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -998,13 +1000,14 @@ public: count= 0; Item_sum_sum::cleanup(); } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - bool supports_removal() const override { return true; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -1087,7 +1090,9 @@ public: m_stddev= Stddev(); Item_sum_double::cleanup(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1113,7 +1118,9 @@ class Item_sum_std final :public Item_sum_variance return sample ? stddev_samp_name : std_name; } Item *copy_or_same(THD* thd) override final; - Item *do_get_copy(THD *thd) const override final + +protected: + Item *shallow_copy(THD *thd) const override final { return get_item_copy(thd, this); } }; @@ -1216,7 +1223,9 @@ public: return sum_name; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1235,7 +1244,9 @@ public: return sum_name; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1328,11 +1339,13 @@ public: return sum_name; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } private: void set_bits_from_counters() override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; @@ -1349,11 +1362,13 @@ public: return sum_min_name; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } private: void set_bits_from_counters() override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class Item_sum_xor final :public Item_sum_bit @@ -1368,11 +1383,13 @@ public: return sum_min_name; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } private: void set_bits_from_counters() override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class sp_head; @@ -1512,9 +1529,11 @@ public: { return sp_result_field; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } Item *copy_or_same(THD *thd) override; + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; /* Items to get the value of a stored sum function */ @@ -1578,9 +1597,12 @@ public: String *val_str(String *str) override { return val_string_from_real(str); } double val_real() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -1609,9 +1631,12 @@ public: return VDec(this).to_string_round(str, decimals); } my_decimal *val_decimal(my_decimal *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -1632,9 +1657,12 @@ public: bool is_null() override { update_null_value(); return null_value; } const Type_handler *type_handler() const override { return &type_handler_double; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -1646,9 +1674,12 @@ public: { } enum Type type() const override { return FIELD_STD_ITEM; } double val_real() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; @@ -1746,7 +1777,9 @@ class Item_sum_udf_float :public Item_udf_sum bool fix_length_and_dec() override { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1773,7 +1806,9 @@ public: } bool fix_length_and_dec() override { decimals=0; max_length=21; return FALSE; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1815,7 +1850,9 @@ public: { return string_type_handler(); } bool fix_length_and_dec() override; Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1847,7 +1884,9 @@ public: bool fix_length_and_dec() override { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -2108,13 +2147,14 @@ public: void print(String *str, enum_query_type query_type) override; bool change_context_processor(void *cntx) override { context= (Name_resolution_context *)cntx; return FALSE; } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } qsort_cmp2 get_comparator_function_for_distinct(); qsort_cmp2 get_comparator_function_for_order_by(); uchar* get_record_pointer(); uint get_null_bytes(); +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; #endif /* ITEM_SUM_INCLUDED */ diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 395d383505b..431c23a5962 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -67,7 +67,9 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -90,7 +92,9 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; return FALSE; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -120,7 +124,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -153,7 +159,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -181,7 +189,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -210,7 +220,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -236,7 +248,9 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -264,7 +278,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -292,7 +308,9 @@ public: { return !has_time_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -320,7 +338,9 @@ public: { return !has_time_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -348,7 +368,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -376,7 +398,9 @@ public: { return !has_time_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -414,7 +438,9 @@ public: { return arg_count == 2; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -447,7 +473,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -477,7 +505,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -512,7 +542,9 @@ public: { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -539,7 +571,9 @@ class Item_func_dayname :public Item_str_func { return !has_date_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -608,7 +642,9 @@ public: } longlong int_op() override; my_decimal *decimal_op(my_decimal* buf) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -636,7 +672,9 @@ public: } longlong int_op() override; my_decimal *decimal_op(my_decimal* buf) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -756,7 +794,9 @@ public: return name; } void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -772,7 +812,9 @@ public: return name; } void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -804,7 +846,9 @@ public: return name; } void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -819,7 +863,9 @@ public: return name; } void store_now_in_TIME(THD* thd, MYSQL_TIME *now_time) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -864,7 +910,9 @@ public: int save_in_field(Field *field, bool no_conversions) override; void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; enum Functype functype() const override { return NOW_FUNC; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -885,7 +933,9 @@ public: return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -914,7 +964,9 @@ public: VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC); } enum Functype functype() const override { return SYSDATE_FUNC; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -937,7 +989,9 @@ public: { return has_date_args() || has_time_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -974,7 +1028,9 @@ public: return false; return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -989,7 +1045,9 @@ public: return name; } bool check_vcol_func_processor(void *arg) override { return false; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1043,7 +1101,8 @@ public: return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1066,7 +1125,9 @@ class Item_func_from_unixtime :public Item_datetimefunc { return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1116,7 +1177,9 @@ class Item_func_convert_tz :public Item_datetimefunc } bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; void cleanup() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1139,7 +1202,9 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sec_to_time") }; return name; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1163,7 +1228,9 @@ public: void print(String *str, enum_query_type query_type) override; enum precedence precedence() const override { return INTERVAL_PRECEDENCE; } bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1275,7 +1342,9 @@ class Item_extract :public Item_int_func, } return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1322,7 +1391,9 @@ public: } void print(String *str, enum_query_type query_type) override; bool need_parentheses_in_default() override { return true; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1363,7 +1434,9 @@ public: { return args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1389,7 +1462,9 @@ public: Item_time_typecast_fix_length_and_dec(this); } Sql_mode_dependency value_depends_on_sql_mode() const override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1415,7 +1490,9 @@ public: Item_datetime_typecast_fix_length_and_dec(this); } Sql_mode_dependency value_depends_on_sql_mode() const override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1433,7 +1510,9 @@ public: return name; } bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1475,7 +1554,9 @@ public: return (null_value= Sec6_add(dt.get_mysql_time(), it.get_mysql_time(), 1). to_datetime(ltime)); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1507,7 +1588,9 @@ public: static LEX_CSTRING subtime= { STRING_WITH_LEN("subtime") }; return sign > 0 ? addtime : subtime; } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1533,7 +1616,9 @@ public: return FALSE; } bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1560,7 +1645,9 @@ public: return name; } bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1588,7 +1675,9 @@ public: { return !has_time_args(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1617,7 +1706,9 @@ public: return FALSE; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1648,7 +1739,9 @@ public: return FALSE; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1672,7 +1765,9 @@ public: return name; } bool fix_length_and_dec() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -1689,7 +1784,9 @@ public: return name; } bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_vers.h b/sql/item_vers.h index 47df8a1f70d..cf27a218fb4 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -48,7 +48,9 @@ public: return name; } void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -64,10 +66,12 @@ public: return (trt_field == TR_table::FLD_BEGIN_TS) ? begin_name : commit_name; } bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } bool fix_length_and_dec() override { fix_attributes_datetime(decimals); return FALSE; } + +protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; class Item_func_trt_id : public Item_longlong_func @@ -109,7 +113,9 @@ public: } longlong val_int() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -126,7 +132,9 @@ public: return name; } bool val_bool() override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 89bfd844929..985d2dbf3bf 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -150,7 +150,8 @@ public: return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -225,7 +226,9 @@ public: } Item_sum_int::cleanup(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -298,7 +301,9 @@ class Item_sum_dense_rank: public Item_sum_int } Item_sum_int::cleanup(); } - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -362,7 +367,8 @@ class Item_sum_first_value : public Item_sum_hybrid_simple return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -389,7 +395,8 @@ class Item_sum_last_value : public Item_sum_hybrid_simple return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -411,7 +418,8 @@ class Item_sum_nth_value : public Item_sum_hybrid_simple return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -433,7 +441,8 @@ class Item_sum_lead : public Item_sum_hybrid_simple return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -455,7 +464,8 @@ class Item_sum_lag : public Item_sum_hybrid_simple return name; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -570,7 +580,8 @@ class Item_sum_percent_rank: public Item_sum_double, Partition_row_count::set_partition_row_count(count); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } private: @@ -658,9 +669,9 @@ class Item_sum_cume_dist: public Item_sum_double, Partition_row_count::set_partition_row_count(count); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - }; class Item_sum_ntile : public Item_sum_int, @@ -735,7 +746,8 @@ class Item_sum_ntile : public Item_sum_int, Partition_row_count::set_partition_row_count(count); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } private: @@ -899,8 +911,11 @@ public: Partition_row_count::set_partition_row_count(count); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } + +public: void setup_window_func(THD *thd, Window_spec *window_spec) override; void setup_hybrid(THD *thd, Item *item); bool fix_fields(THD *thd, Item **ref) override; @@ -1036,8 +1051,11 @@ public: Partition_row_count::set_partition_row_count(count); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } + +public: void setup_window_func(THD *thd, Window_spec *window_spec) override; void setup_hybrid(THD *thd, Item *item); bool fix_fields(THD *thd, Item **ref) override; @@ -1391,8 +1409,8 @@ public: void print(String *str, enum_query_type query_type) override; - Item *do_get_copy(THD *thd) const override { return 0; } - +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } }; #endif /* ITEM_WINDOWFUNC_INCLUDED */ diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 3f7ce4db569..7d4dc7e88b0 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -221,7 +221,8 @@ public: return { STRING_WITH_LEN("xpath_rootelement") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -237,7 +238,8 @@ public: return { STRING_WITH_LEN("xpath_union") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -277,7 +279,8 @@ public: return { STRING_WITH_LEN("xpath_selfbyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -294,7 +297,8 @@ public: return { STRING_WITH_LEN("xpath_childbyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -313,7 +317,8 @@ public: return { STRING_WITH_LEN("xpath_descendantbyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -332,7 +337,8 @@ public: return { STRING_WITH_LEN("xpath_ancestorbyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -350,7 +356,8 @@ public: return { STRING_WITH_LEN("xpath_parentbyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -367,7 +374,8 @@ public: return { STRING_WITH_LEN("xpath_attributebyname") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -387,7 +395,8 @@ public: return { STRING_WITH_LEN("xpath_predicate") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -403,7 +412,8 @@ public: return { STRING_WITH_LEN("xpath_elementbyindex") }; } bool val_native(THD *thd, Native *nodeset) override; - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -434,7 +444,8 @@ public: } return args[0]->val_real() ? 1 : 0; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -451,7 +462,8 @@ public: return { STRING_WITH_LEN("xpath_cast_number") }; } double val_real() override { return args[0]->val_real(); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -471,7 +483,8 @@ public: } bool fix_length_and_dec() override { max_length= MAX_BLOB_WIDTH; return FALSE; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -495,7 +508,8 @@ public: return tmp_native_value.element(0).pos + 1; return 0; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -521,7 +535,8 @@ public: return predicate_supplied_context_size; return tmp_native_value.elements(); } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -569,7 +584,8 @@ public: } return sum; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -654,7 +670,8 @@ public: } return 0; } - Item *do_get_copy(THD *thd) const override +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index e3ba3770807..136f995beb6 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -137,7 +137,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -158,7 +160,9 @@ public: return name; } String *val_str(String *) override; - Item *do_get_copy(THD *thd) const override + +protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 14606013881..a58dd26df33 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -602,8 +602,8 @@ void TABLE::add_splitting_info_for_key_field(KEY_FIELD *key_field) condition of the select that specifies this table. */ THD *thd= in_use; - Item *left_item= spl_field->producing_item->build_clone(thd); - Item *right_item= key_field->val->build_clone(thd); + Item *left_item= spl_field->producing_item->deep_copy_with_checks(thd); + Item *right_item= key_field->val->deep_copy_with_checks(thd); Item_func_eq *eq_item= 0; if (left_item && right_item) { diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 3381d84776f..6797aa09894 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -6996,7 +6996,7 @@ Item *Item_field::in_subq_field_transformer_for_where(THD *thd, uchar *arg) Item_in_subselect *subq_pred= ((Item *)arg)->get_IN_subquery(); Item *producing_item= get_corresponding_item(thd, this, subq_pred); if (producing_item) - return producing_item->build_clone(thd); + return producing_item->deep_copy_with_checks(thd); return this; } @@ -7009,7 +7009,7 @@ Item *Item_direct_view_ref::in_subq_field_transformer_for_where(THD *thd, Item_in_subselect *subq_pred= ((Item *)arg)->get_IN_subquery(); Item *producing_item= get_corresponding_item(thd, this, subq_pred); DBUG_ASSERT (producing_item != NULL); - return producing_item->build_clone(thd); + return producing_item->deep_copy_with_checks(thd); } return this; } diff --git a/sql/procedure.h b/sql/procedure.h index 5abe3ee454c..25ccfd56dbf 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -70,7 +70,9 @@ public: { return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate); } - Item* do_get_copy(THD *thd) const override { return 0; } + +protected: + Item* shallow_copy(THD *thd) const override { return nullptr; } }; class Item_proc_real :public Item_proc @@ -125,8 +127,10 @@ public: { s->set(value, default_charset()); return s; } my_decimal *val_decimal(my_decimal *) override; unsigned int size_of() { return sizeof(*this);} - Item *do_get_copy(THD *thd) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } + +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; @@ -167,8 +171,10 @@ public: my_decimal *val_decimal(my_decimal *) override; void cleanup() override { value.free(); } unsigned int size_of() { return sizeof(*this);} - Item *do_get_copy(THD *thd) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } + +protected: + Item *shallow_copy(THD *thd) const override { return nullptr; } + Item *deep_copy(THD *thd) const override { return nullptr; } }; /* The procedure class definitions */ diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 2eceba1d5b9..6b217cb760c 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1562,7 +1562,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) */ extracted_cond_copy= !sl->next_select() ? extracted_cond : - extracted_cond->build_clone(thd); + extracted_cond->deep_copy_with_checks(thd); if (!extracted_cond_copy) continue; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e595b4d7e08..3e6687d80a5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9018,7 +9018,7 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, if (no_top_clones) return cond; cond->clear_extraction_flag(); - return cond->build_clone(thd); + return cond->deep_copy_with_checks(thd); } if (cond->type() == Item::COND_ITEM) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a32bd87b223..549be4faf66 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8940,7 +8940,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (keep) { - Item *expr_copy= check->expr->get_copy(thd); + Item *expr_copy= check->expr->shallow_copy_with_checks(thd); check= new Virtual_column_info(); check->name= share->period.constr_name; check->automatic_name= true; diff --git a/sql/sql_type_fixedbin.h b/sql/sql_type_fixedbin.h index a8c3b729d21..4293c6418e1 100644 --- a/sql/sql_type_fixedbin.h +++ b/sql/sql_type_fixedbin.h @@ -294,15 +294,18 @@ public: str->append(tmp); str->append('\''); } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } // Non-overriding methods void set_value(const Fbt &value) { m_value= value; } + + protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; class Field_fbt: public Field @@ -872,9 +875,12 @@ public: { return Item::save_in_field(field, no_conversions); } - Item *do_get_copy(THD *thd) const override + + protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; class Item_char_typecast_func_handler_fbt_to_binary: @@ -974,7 +980,9 @@ public: Fbt_null tmp(args[0]); return null_value= tmp.is_null() || tmp.to_native(to); } - Item *do_get_copy(THD *thd) const override + + protected: + Item *shallow_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -984,9 +992,6 @@ public: public: Item_cache_fbt(THD *thd) :Item_cache(thd, singleton()) { } - Item *do_get_copy(THD *thd) const override - { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } bool cache_value() override { if (!example) @@ -1050,6 +1055,12 @@ public: return true; return to->copy(m_value.ptr(), m_value.length()); } + + protected: + Item *shallow_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *deep_copy(THD *thd) const override + { return shallow_copy_with_checks(thd); } }; /* =[ methods ]=============================================== */ diff --git a/sql/table.cc b/sql/table.cc index 49297b6076c..034215f9a06 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3673,7 +3673,7 @@ Virtual_column_info::is_equivalent(THD *thd, TABLE_SHARE *share, TABLE_SHARE *vc const Virtual_column_info* vcol, bool &error) const { error= true; - Item *cmp_expr= vcol->expr->build_clone(thd); + Item *cmp_expr= vcol->expr->deep_copy_with_checks(thd); if (!cmp_expr) return false; Item::func_processor_rename_table param; From cd02709a315c9f08965d6b8fb7e75baaae17a4f4 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Mon, 19 Jan 2026 17:47:06 +0700 Subject: [PATCH 099/152] MDEV-38574 Rename cloning functions of class Item and descendants Rename `Item::clone_item()` to `clone_constant()`, and do the same for any overloads in descendant items. The function returns non-NULL only for items that represent constant literals. --- sql/item.cc | 24 ++++++++++++------------ sql/item.h | 28 ++++++++++++++-------------- sql/sql_select.cc | 4 ++-- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 735f1cbd8c4..236a1b48b17 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3938,7 +3938,7 @@ void Item_decimal::set_decimal_value(my_decimal *value_par) } -Item *Item_decimal::clone_item(THD *thd) const +Item *Item_decimal::clone_constant(THD *thd) const { return new (thd->mem_root) Item_decimal(thd, name.str, &decimal_value, decimals, max_length); @@ -3959,7 +3959,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value) } -Item *Item_float::clone_item(THD *thd) const +Item *Item_float::clone_constant(THD *thd) const { return new (thd->mem_root) Item_float(thd, name.str, value, decimals, max_length); @@ -4131,7 +4131,7 @@ Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) return this; } -Item *Item_null::clone_item(THD *thd) const +Item *Item_null::clone_constant(THD *thd) const { return new (thd->mem_root) Item_null(thd, name.str); } @@ -4978,7 +4978,7 @@ Item *Item_param::value_clone_item(THD *thd) const /* see comments in the header file */ Item * -Item_param::clone_item(THD *thd) const +Item_param::clone_constant(THD *thd) const { // There's no "default". See comments in Item_param::save_in_field(). switch (state) { @@ -7109,7 +7109,7 @@ int Item_string::save_in_field(Field *field, bool no_conversions) } -Item *Item_string::clone_item(THD *thd) const +Item *Item_string::clone_constant(THD *thd) const { LEX_CSTRING val; str_value.get_value(&val); @@ -7173,7 +7173,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions) } -Item *Item_int::clone_item(THD *thd) const +Item *Item_int::clone_constant(THD *thd) const { return new (thd->mem_root) Item_int(thd, name.str, value, max_length, unsigned_flag); } @@ -7202,7 +7202,7 @@ int Item_decimal::save_in_field(Field *field, bool no_conversions) } -Item *Item_int_with_ref::clone_item(THD *thd) const +Item *Item_int_with_ref::clone_constant(THD *thd) const { DBUG_ASSERT(ref->const_item()); /* @@ -7298,7 +7298,7 @@ Item *Item_uint::neg(THD *thd) } -Item *Item_uint::clone_item(THD *thd) const +Item *Item_uint::clone_constant(THD *thd) const { return new (thd->mem_root) Item_uint(thd, name.str, value, max_length); } @@ -7536,7 +7536,7 @@ void Item_date_literal::print(String *str, enum_query_type query_type) } -Item *Item_date_literal::clone_item(THD *thd) const +Item *Item_date_literal::clone_constant(THD *thd) const { return new (thd->mem_root) Item_date_literal(thd, &cached_time); } @@ -7561,7 +7561,7 @@ void Item_datetime_literal::print(String *str, enum_query_type query_type) } -Item *Item_datetime_literal::clone_item(THD *thd) const +Item *Item_datetime_literal::clone_constant(THD *thd) const { return new (thd->mem_root) Item_datetime_literal(thd, &cached_time, decimals); } @@ -7586,7 +7586,7 @@ void Item_time_literal::print(String *str, enum_query_type query_type) } -Item *Item_time_literal::clone_item(THD *thd) const +Item *Item_time_literal::clone_constant(THD *thd) const { return new (thd->mem_root) Item_time_literal(thd, &cached_time, decimals); } @@ -10564,7 +10564,7 @@ void Item_cache_temporal::store_packed(longlong val_arg, Item *example_arg) } -Item *Item_cache_temporal::clone_item(THD *thd) const +Item *Item_cache_temporal::clone_constant(THD *thd) const { Item_cache *tmp= type_handler()->Item_get_cache(thd, this); Item_cache_temporal *item= static_cast(tmp); diff --git a/sql/item.h b/sql/item.h index 1cfef72b536..c74097739d3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1935,7 +1935,7 @@ public: For real clones look at deep_copy_with_checks()/shallow_copy_with_checks() methods */ - virtual Item *clone_item(THD *thd) const { return nullptr; } + virtual Item *clone_constant(THD *thd) const { return nullptr; } virtual cond_result eq_cmp_result() const { return COND_OK; } inline uint float_length(uint decimals_par) const @@ -4011,7 +4011,7 @@ public: const Type_handler *type_handler() const override { return &type_handler_null; } bool basic_const_item() const override { return true; } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; bool const_is_null() const override { return true; } bool is_null() override { return true; } @@ -4465,7 +4465,7 @@ public: basic_const_item returned TRUE. */ Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override; - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; void set_param_type_and_swap_value(Item_param *from); Rewritable_query_parameter *get_rewritable_query_parameter() override @@ -4575,7 +4575,7 @@ public: String *val_str(String*) override; int save_in_field(Field *field, bool no_conversions) override; bool is_order_clause_position() const override { return true; } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; void print(String *str, enum_query_type query_type) override; Item *neg(THD *thd) override; decimal_digits_t decimal_precision() const override @@ -4647,7 +4647,7 @@ public: Item_uint(THD *thd, ulonglong i): Item_int(thd, i, 10) {} Item_uint(THD *thd, const char *str_arg, longlong i, uint length); double val_real() override { return ulonglong2double((ulonglong)value); } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; Item *neg(THD *thd) override; decimal_digits_t decimal_precision() const override { return decimal_digits_t(max_length); } @@ -4709,7 +4709,7 @@ public: const my_decimal *const_ptr_my_decimal() const override { return &decimal_value; } int save_in_field(Field *field, bool no_conversions) override; - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; void print(String *str, enum_query_type query_type) override { decimal_value.to_string(&str_value); @@ -4768,7 +4768,7 @@ public: } String *val_str(String*) override; my_decimal *val_decimal(my_decimal *) override; - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; Item *neg(THD *thd) override; void print(String *str, enum_query_type query_type) override; @@ -4897,7 +4897,7 @@ public: int save_in_field(Field *field, bool no_conversions) override; const Type_handler *type_handler() const override { return &type_handler_varchar; } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override { return const_charset_converter(thd, tocs, true); @@ -5367,7 +5367,7 @@ public: { return cached_time.get_mysql_time(); } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; bool val_bool() override { return update_null() ? false : cached_time.to_bool(); @@ -5425,7 +5425,7 @@ public: { return cached_time.get_mysql_time(); } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; bool val_bool() override { return cached_time.to_bool(); @@ -5490,7 +5490,7 @@ public: { return cached_time.get_mysql_time(); } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; bool val_bool() override { return update_null() ? false : cached_time.to_bool(); @@ -6671,7 +6671,7 @@ public: { return ref->save_in_field(field, no_conversions); } - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; Item *real_item() override { return ref; } protected: Item *shallow_copy(THD *thd) const override @@ -7668,11 +7668,11 @@ public: } void store_packed(longlong val_arg, Item *example); /* - Having a clone_item method tells optimizer that this object + Having a clone_constant method tells optimizer that this object is a constant and need not be optimized further. Important when storing packed datetime values. */ - Item *clone_item(THD *thd) const override; + Item *clone_constant(THD *thd) const override; Item *convert_to_basic_const_item(THD *thd) override; virtual Item *make_literal(THD *) =0; }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f7c0b4cc884..9464ec3bb26 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17802,7 +17802,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, if (can_change_cond_ref_to_const(func, right_item, left_item, field_value_owner, field, value)) { - Item *tmp=value->clone_item(thd); + Item *tmp=value->clone_constant(thd); if (tmp) { tmp->collation.set(right_item->collation); @@ -17832,7 +17832,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, else if (can_change_cond_ref_to_const(func, left_item, right_item, field_value_owner, field, value)) { - Item *tmp= value->clone_item(thd); + Item *tmp= value->clone_constant(thd); if (tmp) { tmp->collation.set(left_item->collation); From be4e1ecdc2457b409715cc312957903c8e8c3fc9 Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Wed, 31 Dec 2025 10:12:11 +0530 Subject: [PATCH 100/152] MDEV-37510: crash when tracing with max_sel_arg_weight equal to 1 When the optimizer_max_sel_arg_weight is set to 1, a nested query crashed while tracing. SEL_ARG object has a field named 'field', that is not set when the type is other than KEY_RANGE. But, the field was accessed to store its name, and weight to the trace. This resulted in a crash due to NULL pointer. Added a check to access field if the type is KEY_RANGE, and if not, just trace the type. --- mysql-test/main/range_notembedded.result | 53 ++++++++++++++++++++++++ mysql-test/main/range_notembedded.test | 35 ++++++++++++++++ sql/opt_range.cc | 18 +++++--- 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/range_notembedded.result b/mysql-test/main/range_notembedded.result index 9cd93903184..0839430d559 100644 --- a/mysql-test/main/range_notembedded.result +++ b/mysql-test/main/range_notembedded.result @@ -308,3 +308,56 @@ json_pretty(json_search(@trace, 'all', 'key1')) "$[0].analyzing_range_alternatives.range_scan_alternatives[0].index" ] drop table t1; +# +# MDEV-37510: Crash in sel_arg_and_weight_heuristic +# +SET @save_optimizer_trace=@@optimizer_trace; +SET @save_optimizer_max_sel_arg_weight=@@optimizer_max_sel_arg_weight; +SET optimizer_trace= 'enabled=on'; +SET optimizer_max_sel_arg_weight=1; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +CREATE TABLE t2 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +INSERT INTO t1 values (2, 'two', 'prime'), (3, 'three', 'prime'); +INSERT INTO t2 values (2, 'two', '2_table'), (4, 'four', '2_table'); +select * from +t1 +JOIN +( +SELECT c1, c2, c3 FROM t2 +UNION +SELECT c1, c2, c3 FROM t2 +) dt1 +ON ((t1.c1 = dt1.c1 OR dt1.c1 IS NULL) AND +(t1.c2 = dt1.c2 OR dt1.c3 IS NULL)); +c1 c2 c3 c1 c2 c3 +2 two prime 2 two 2_table +set @trace= (select trace from information_schema.optimizer_trace); +set @json= json_detailed(json_extract(@trace, '$**.setup_range_conditions')); +select left(@json, 2500); +left(@json, 2500) +[ + [ + { + "sel_arg_weight_heuristic": + { + "key1_type": 2, + "key2_type": 2, + "key1_weight": 1, + "key2_weight": 1 + } + }, + { + "sel_arg_weight_heuristic": + { + "key1_type": 2, + "key2_field": "c3", + "key1_weight": 1, + "key2_weight": 1 + } + } + ] +] +DROP TABLE t1, t2; +SET optimizer_trace=@save_optimizer_trace; +SET optimizer_max_sel_arg_weight=@save_optimizer_max_sel_arg_weight; +# end of 11.4 tests diff --git a/mysql-test/main/range_notembedded.test b/mysql-test/main/range_notembedded.test index a13bb1d95c7..6729b39293e 100644 --- a/mysql-test/main/range_notembedded.test +++ b/mysql-test/main/range_notembedded.test @@ -211,3 +211,38 @@ set @trace=json_extract((select trace from information_schema.optimizer_trace), select json_pretty(json_search(@trace, 'all', 'key1')); drop table t1; +--echo # +--echo # MDEV-37510: Crash in sel_arg_and_weight_heuristic +--echo # +SET @save_optimizer_trace=@@optimizer_trace; +SET @save_optimizer_max_sel_arg_weight=@@optimizer_max_sel_arg_weight; + +SET optimizer_trace= 'enabled=on'; +SET optimizer_max_sel_arg_weight=1; + +CREATE TABLE t1 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +CREATE TABLE t2 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); + +INSERT INTO t1 values (2, 'two', 'prime'), (3, 'three', 'prime'); +INSERT INTO t2 values (2, 'two', '2_table'), (4, 'four', '2_table'); + +select * from +t1 +JOIN +( + SELECT c1, c2, c3 FROM t2 + UNION + SELECT c1, c2, c3 FROM t2 +) dt1 +ON ((t1.c1 = dt1.c1 OR dt1.c1 IS NULL) AND + (t1.c2 = dt1.c2 OR dt1.c3 IS NULL)); + +set @trace= (select trace from information_schema.optimizer_trace); +set @json= json_detailed(json_extract(@trace, '$**.setup_range_conditions')); +select left(@json, 2500); + +DROP TABLE t1, t2; + +SET optimizer_trace=@save_optimizer_trace; +SET optimizer_max_sel_arg_weight=@save_optimizer_max_sel_arg_weight; +--echo # end of 11.4 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 15035f94e4d..edf13457a90 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11528,11 +11528,19 @@ bool sel_arg_and_weight_heuristic(RANGE_OPT_PARAM *param, SEL_ARG *key1, { Json_writer_object wrapper(param->thd); Json_writer_object obj(param->thd, "sel_arg_weight_heuristic"); - obj. - add("key1_field", key1->field->field_name). - add("key2_field", key2->field->field_name). - add("key1_weight", (longlong)key1->weight). - add("key2_weight", (longlong)key2->weight); + + if (key1->type == SEL_ARG::KEY_RANGE) + obj.add("key1_field", key1->field->field_name); + else + obj.add("key1_type", (uint) key1->type); + + if (key2->type == SEL_ARG::KEY_RANGE) + obj.add("key2_field", key2->field->field_name); + else + obj.add("key2_type", (uint) key2->type); + + obj.add("key1_weight", (longlong) key1->weight); + obj.add("key2_weight", (longlong) key2->weight); } return true; // Discard key2 } From b061b5ab1f2cd2a6993e53dc24a865304ced14cd Mon Sep 17 00:00:00 2001 From: Rex Johnston Date: Fri, 23 Jan 2026 07:22:03 +1300 Subject: [PATCH 101/152] MDEV-31632 Unresolvable outer reference causes null pointer exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SELECT 1 union select 2 UNION SELECT 1 from a JOIN a b ON (SELECT 1 FROM dual WHERE AAA) Crashes during fix_outer_field while resolving field item AAA In our resolver, once we have determined that a field item isn't local to our select, we call Item::fix_outer_field(), which iterates outwards towards the top level select, looking for where our Item_field might be resolvable. In our example here, the item isn't resolvable and we expose fragility in the loop, which i will detail here. After we initialize the variable 'outer_context' (to a context containing /* select#3 */ select 1 AS `1` from (a join a b on ((subquery#4))) ) we enter a loop │ 5927 for (; │ 5928 outer_context; │ 5929 outer_context= outer_context->outer_context) │ 5930 { │ 5931 select= outer_context->select_lex; │ 5932 Item_subselect *prev_subselect_item= │ 5933 last_checked_context->select_lex->master_unit()->item; │ 5934 last_checked_context= outer_context; here 'last_checked_context' is the context inner to the current 'outer_context', and we initialize prev_subselect_item to the Item enclosing the unit containing this inner select. So for the first iteration of the loop, select: select #3 last_checked_context: from select #4 to select #3. prev_subselect_item: item enclosing select #4 (where field item AAA is defined) The rest of the loop calls find_field_in_tables() / resolve_ref_in_select_and_group() in an attempt to resolve this item with this 'outer_context'. After the item fails resolution, we move to an outer context select: select #4294967295 (fake_select_lex) last_checked_context: from select #3 to the fake select lex containing the union (i.e. outermost) prev_subselect_item: null, there is no Item that contains this, it is the outermost select. We still need to execute the rest of the loop to determine whether AAA is resolvable here, but executing │ 5937 place= prev_subselect_item->parsing_place; We are now following a null pointer. We introduce a test for this null pointer, indicating that we are now evaluating the outermost select and we are not to try accessing the enclosing subselect item. Approved by: Oleksandr "Sanja" Byelkin (sanja@mariadb.com) --- mysql-test/main/subselect4.result | 6 ++++++ mysql-test/main/subselect4.test | 9 +++++++++ sql/item.cc | 30 +++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index 696ba7de592..b347101e25f 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -3372,6 +3372,12 @@ drop table t1,t2,t3; CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; (SELECT 0 GROUP BY c HAVING (SELECT c)) +# +# MDEV-31632 Unresolvable outer reference causes null pointer exception +# +SELECT 1 union select 2 UNION SELECT 1 from t JOIN t b ON +(SELECT 1 FROM dual WHERE AAA); +ERROR 42S22: Unknown column 'AAA' in 'WHERE' DROP TABLE t; # # MDEV-38476 Wrong Result (Empty Set) with derived_merge=on using AVG() on text column in HAVING clause diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 303d39c93f3..1ccfb2bbdab 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2693,6 +2693,15 @@ drop table t1,t2,t3; CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; + +--echo # +--echo # MDEV-31632 Unresolvable outer reference causes null pointer exception +--echo # + +--error ER_BAD_FIELD_ERROR +SELECT 1 union select 2 UNION SELECT 1 from t JOIN t b ON + (SELECT 1 FROM dual WHERE AAA); + DROP TABLE t; --echo # diff --git a/sql/item.cc b/sql/item.cc index d745b3cd36f..a003f9075ec 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5920,10 +5920,19 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) select= outer_context->select_lex; Item_subselect *prev_subselect_item= last_checked_context->select_lex->master_unit()->item; + /* + We have merged to the top select and this field is no longer outer, + or we have reached the outermost select without resolution + */ + bool at_top= !prev_subselect_item; last_checked_context= outer_context; upward_lookup= TRUE; - place= prev_subselect_item->parsing_place; + if (!at_top) + place= prev_subselect_item->parsing_place; + else + place= NO_MATTER; + /* If outer_field is set, field was already found by first call to find_field_in_tables(). Only need to find appropriate context. @@ -5978,8 +5987,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) } if (*from_field != view_ref_found) { - prev_subselect_item->used_tables_cache|= (*from_field)->table->map; - prev_subselect_item->const_item_cache= 0; + if (!at_top) + { + prev_subselect_item->used_tables_cache|= (*from_field)->table->map; + prev_subselect_item->const_item_cache= 0; + } set_field(*from_field); if (!last_checked_context->select_lex->having_fix_field && select->group_list.elements && @@ -6028,7 +6040,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) else { Item::Type ref_type= (*reference)->type(); - prev_subselect_item->used_tables_and_const_cache_join(*reference); + if (!at_top) + prev_subselect_item->used_tables_and_const_cache_join(*reference); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, this, ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? @@ -6076,7 +6089,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) if (refref->fixed()) (*ref)->fix_fields_if_needed( thd, reference); } - if ((*ref)->fixed()) + if (!at_top && (*ref)->fixed()) prev_subselect_item->used_tables_and_const_cache_join(*ref); break; @@ -6088,8 +6101,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) outer select (or we just trying to find wrong identifier, in this case it does not matter which used tables bits we set) */ - prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; - prev_subselect_item->const_item_cache= 0; + if (!at_top) + { + prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; + prev_subselect_item->const_item_cache= 0; + } } DBUG_ASSERT(ref != 0); From 929bb98595abeb5bd2e2f490c95186acfd7b629e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 13 Jan 2026 00:56:33 +0100 Subject: [PATCH 102/152] MDEV-38532 Debian packages are missing many server include headers, such as handler.h include headers needed to build plugins, same as in RPMs --- debian/libmariadb-dev.install | 1 + debian/rules | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/debian/libmariadb-dev.install b/debian/libmariadb-dev.install index 48120822f81..6afae738943 100644 --- a/debian/libmariadb-dev.install +++ b/debian/libmariadb-dev.install @@ -23,6 +23,7 @@ usr/include/mariadb/mysql/plugin_auth.h usr/include/mariadb/mysql_com.h usr/include/mariadb/mysql_version.h usr/include/mariadb/mysqld_error.h +usr/include/mariadb/server/* usr/lib/*/libmariadb.a usr/lib/*/libmariadb.so usr/lib/*/libmariadbclient.a diff --git a/debian/rules b/debian/rules index e358134f299..116270cf74f 100644 --- a/debian/rules +++ b/debian/rules @@ -146,9 +146,6 @@ override_dh_auto_install: # If mariadb-test package is removed, also remove most of it's files grep --quiet "Package: mariadb-test" debian/control || rm -rf $(TMP)/usr/share/mariadb/mariadb-test - # Delete private files from libraries so they don't get shipped in the -dev packages - rm -r $(TMP)/usr/include/mariadb/server/private - # Don't ship sql-bench at all, just delete it completely even though it builds rm -r $(TMP)/usr/sql-bench From 0fc66b6ff0d452388e1c0d2ae12ced10fe15672c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 22 Dec 2025 13:13:50 +0100 Subject: [PATCH 103/152] MDEV-35541 UBSAN: runtime error: addition of unsigned offset to X overflowed to Y in my_b_flush_io_cache /home/buildbot/server/mysys/mf_iocache.c:1793:39: runtime error: addition of unsigned offset to 0x7e1586a239fb overflowed to 0x7e1586a239fa SUMMARY: UndefinedBehaviorSanitizer: pointer-overflow /home/buildbot/server/mysys/mf_iocache.c:1793:39 --- mysys/mf_iocache.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 8b35ec953dc..5797b18ac1d 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -212,7 +212,7 @@ int init_io_cache_ext(IO_CACHE *info, File file, size_t cachesize, { size_t min_cache; my_off_t pos; - my_off_t end_of_file= ~(my_off_t) 0; + my_off_t end_of_file= MY_FILEPOS_ERROR; DBUG_ENTER("init_io_cache_ext"); DBUG_PRINT("enter",("cache:%p type: %d pos: %llu", info, (int) type, (ulonglong) seek_offset)); @@ -515,7 +515,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, info->write_end=info->write_buffer+info->buffer_length; info->seek_not_done=1; } - info->end_of_file = ~(my_off_t) 0; + info->end_of_file= MY_FILE_ERROR; } pos=info->request_pos+(seek_offset-info->pos_in_file); if (type == WRITE_CACHE) @@ -586,7 +586,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, info->write_end=(info->buffer + info->buffer_length - (seek_offset & (IO_SIZE-1))); } - info->end_of_file= ~(my_off_t) 0; + info->end_of_file= MY_FILEPOS_ERROR; } } info->type=type; @@ -1792,7 +1792,10 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) if ((length=(size_t) (info->write_pos - info->write_buffer))) { - my_off_t eof= info->end_of_file + info->write_pos - info->append_read_pos; + my_off_t eof= info->end_of_file; + if (eof != MY_FILE_ERROR) + eof+= info->write_pos - info->append_read_pos; + if (append_cache) { if (tmp_file_track(info, eof) || From 3b7e35a3fab0393db6c344eb58d30f1f903b2f44 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 12 Dec 2025 16:49:09 +0100 Subject: [PATCH 104/152] MDEV-38283 Incorrect results for NULLIF function narrow a historical hack in convert_const_compared_to_int_field() to apply only to bigint-vs-string comparison as it was supposed to. --- mysql-test/main/type_int.result | 6 ++++++ mysql-test/main/type_uint.result | 32 ++++++++++++++++++++++++++------ mysql-test/main/type_uint.test | 25 ++++++++++++++----------- sql/item_cmpfunc.cc | 4 ++-- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/mysql-test/main/type_int.result b/mysql-test/main/type_int.result index 44e14163955..405263b70eb 100644 --- a/mysql-test/main/type_int.result +++ b/mysql-test/main/type_int.result @@ -2007,10 +2007,16 @@ Warnings: Warning 1292 Truncated incorrect DECIMAL value: '2001-01-01 10:20:30' SELECT * FROM t1 WHERE indexed_col=DATE'2001-01-01'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint` = "DATE'2001-01-01'" of type `date` SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint` = "TIME'10:20:30'" of type `time` SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint` = "TIMESTAMP'2001-01-01 10:20:30'" of type `datetime` SELECT * FROM t1 WHERE indexed_col=0x00; indexed_col SELECT * FROM t1 WHERE indexed_col=_utf8mb3'0' COLLATE utf8mb3_bin; diff --git a/mysql-test/main/type_uint.result b/mysql-test/main/type_uint.result index 57a0987eba3..95ebad9b1e6 100644 --- a/mysql-test/main/type_uint.result +++ b/mysql-test/main/type_uint.result @@ -1,4 +1,3 @@ -drop table if exists t1; SET SQL_WARNINGS=1; create table t1 (this int unsigned); insert into t1 values (1); @@ -14,6 +13,7 @@ this 0 4294967295 drop table t1; +# End of 4.1 tests create table t1 (a bigint unsigned, b mediumint unsigned); insert t1 values (1,2),(0xffffffffffffffff,0xffffff); select coalesce(a,b), coalesce(b,a) from t1; @@ -34,9 +34,6 @@ a 16777215 drop table t1, t2; # -# Start of 10.0 tests -# -# # MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns # CREATE TABLE t1 (a DATE PRIMARY KEY); @@ -69,10 +66,8 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1105 Cannot use key `PRIMARY` part[0] for lookup: `test`.`t2`.`a` of type `int unsigned` = "`t1`.`a`" of type `date` DROP TABLE t1,t2; -# # End of 10.0 tests # -# # MDEV-32203 Raise notes when an index cannot be used on data type mismatch # SET note_verbosity=unusable_keys; @@ -230,10 +225,16 @@ Warnings: Warning 1292 Truncated incorrect DECIMAL value: '2001-01-01 10:20:30' SELECT * FROM t1 WHERE indexed_col=DATE'2001-01-01'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint unsigned` = "DATE'2001-01-01'" of type `date` SELECT * FROM t1 WHERE indexed_col=TIME'10:20:30'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint unsigned` = "TIME'10:20:30'" of type `time` SELECT * FROM t1 WHERE indexed_col=TIMESTAMP'2001-01-01 10:20:30'; indexed_col +Warnings: +Note 1105 Cannot use key `indexed_col` part[0] for lookup: `test`.`t1`.`indexed_col` of type `bigint unsigned` = "TIMESTAMP'2001-01-01 10:20:30'" of type `datetime` SELECT * FROM t1 WHERE indexed_col=0x00; indexed_col SELECT * FROM t1 WHERE indexed_col=_utf8mb3'0' COLLATE utf8mb3_bin; @@ -325,3 +326,22 @@ Warning 1292 Truncated incorrect INTEGER value: '2001-01-02' DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-38283 Incorrect results for NULLIF function +# +create table t1 (c1 int unsigned); +insert t1 values (18); +select nullif(cast(0 as datetime), c1) from t1; +nullif(cast(0 as datetime), c1) +NULL +Warnings: +Warning 1292 Incorrect datetime value: '18' for column `test`.`t1`.`c1` at row 1 +create table t2 (c2 bigint unsigned); +insert t2 values (18); +select nullif(cast(0 as datetime), c2) from t2; +nullif(cast(0 as datetime), c2) +NULL +Warnings: +Warning 1292 Incorrect datetime value: '18' for column `test`.`t2`.`c2` at row 1 +drop table t1, t2; +# End of 10.11 tests diff --git a/mysql-test/main/type_uint.test b/mysql-test/main/type_uint.test index 72f32de848b..dffb927b71c 100644 --- a/mysql-test/main/type_uint.test +++ b/mysql-test/main/type_uint.test @@ -2,9 +2,6 @@ # test of unsigned int # ---disable_warnings -drop table if exists t1; ---enable_warnings SET SQL_WARNINGS=1; create table t1 (this int unsigned); @@ -14,7 +11,7 @@ insert ignore into t1 values ('5000000000'); select * from t1; drop table t1; -# End of 4.1 tests +--echo # End of 4.1 tests create table t1 (a bigint unsigned, b mediumint unsigned); insert t1 values (1,2),(0xffffffffffffffff,0xffffff); @@ -24,10 +21,6 @@ show create table t2; select * from t2; drop table t1, t2; ---echo # ---echo # Start of 10.0 tests ---echo # - --echo # --echo # MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns --echo # @@ -45,10 +38,7 @@ SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a=t2.a; EXPLAIN SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a=t2.a; DROP TABLE t1,t2; ---echo # --echo # End of 10.0 tests ---echo # - --echo # --echo # MDEV-32203 Raise notes when an index cannot be used on data type mismatch @@ -81,3 +71,16 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + +--echo # +--echo # MDEV-38283 Incorrect results for NULLIF function +--echo # +create table t1 (c1 int unsigned); +insert t1 values (18); +select nullif(cast(0 as datetime), c1) from t1; +create table t2 (c2 bigint unsigned); +insert t2 values (18); +select nullif(cast(0 as datetime), c2) from t2; +drop table t1, t2; + +--echo # End of 10.11 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 73a3780e459..99bc84ec53d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -403,6 +403,7 @@ void Item_func::convert_const_compared_to_int_field(THD *thd) { Item_field *field_item= (Item_field*) (args[field]->real_item()); if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && + args[!field]->cmp_type() == STRING_RESULT && field_item->type_handler() != &type_handler_vers_trx_id) || field_item->field_type() == MYSQL_TYPE_YEAR)) convert_const_to_int(thd, field_item, &args[!field]); @@ -411,8 +412,7 @@ void Item_func::convert_const_compared_to_int_field(THD *thd) } -bool Item_func::aggregate_args2_for_comparison_with_conversion( - THD *thd, +bool Item_func::aggregate_args2_for_comparison_with_conversion(THD *thd, Type_handler_hybrid_field_type *th) { DBUG_ASSERT(arg_count >= 2); From 07331813d8d6a3f2681679aa6c1244c899fdb949 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 26 Dec 2025 12:14:58 +0100 Subject: [PATCH 105/152] MDEV-27277 update test results --- .../rocksdb/mysql-test/rocksdb/r/type_blob_indexes.result | 6 ++++++ .../rocksdb/mysql-test/rocksdb/r/type_text_indexes.result | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_blob_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_blob_indexes.result index 40e31e9fe6d..109728d96ac 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_blob_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_blob_indexes.result @@ -25,6 +25,8 @@ INSERT INTO t1 (b,t,m,l) VALUES ('test3','test4','test5','test6'), (REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)), (REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128)); +Warnings: +Warning 4202 3 values were longer than max_sort_length. Sorting used only the first 1024 bytes EXPLAIN SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f; id select_type table type possible_keys key key_len ref rows Extra # # # # # PRIMARY # # # # @@ -39,6 +41,8 @@ SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') OR f +Warnings: +Warning 4202 3 values were longer than max_sort_length. Sorting used only the first 1024 bytes DROP TABLE t1; CREATE TABLE t1 ( b BLOB, @@ -65,6 +69,8 @@ INSERT INTO t1 (b,t,m,l) VALUES ('test3','test4','test5','test6'), (REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)), (REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128)); +Warnings: +Warning 4202 6 values were longer than max_sort_length. Sorting used only the first 1024 bytes EXPLAIN SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range l_t l_t 259 NULL # Using where; Using filesort diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_text_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_text_indexes.result index 6ae8779d5d9..79f732f971a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_text_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_text_indexes.result @@ -24,6 +24,8 @@ INSERT INTO t1 (t,tt,m,l) VALUES ('test3','test4','test5','test6'), (REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)), (REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128)); +Warnings: +Warning 4202 3 values were longer than max_sort_length. Sorting used only the first 1024 bytes EXPLAIN SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 34 NULL # Using where; Using filesort @@ -38,6 +40,8 @@ SELECT SUBSTRING(t,16) AS f FROM t1 IGNORE INDEX (PRIMARY) WHERE t IN ('test1',' f +Warnings: +Warning 4202 3 values were longer than max_sort_length. Sorting used only the first 1024 bytes DROP TABLE t1; CREATE TABLE t1 ( t TEXT, From 9710638367425e4c78fd96de039cf23aaeba5931 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 23 Jan 2026 09:28:24 +0100 Subject: [PATCH 106/152] update C/C --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 47171e34c7a..7bb4e6cdf78 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 47171e34c7acec6d7ccf92c44bdcf06483a7c2b2 +Subproject commit 7bb4e6cdf787b32907429287a636857e3b31e6a1 From cb31d7536beb62e66048125b56506974a0ae51f0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 22 Jan 2026 23:19:52 +0100 Subject: [PATCH 107/152] 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 --- .../query_response_time/query_cache.result | 16 ++++++++++++++++ .../query_response_time/query_cache.test | 16 ++++++++++++++++ plugin/query_response_time/plugin.cc | 5 ++++- sql/sql_prepare.cc | 2 +- 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 plugin/query_response_time/mysql-test/query_response_time/query_cache.result create mode 100644 plugin/query_response_time/mysql-test/query_response_time/query_cache.test diff --git a/plugin/query_response_time/mysql-test/query_response_time/query_cache.result b/plugin/query_response_time/mysql-test/query_response_time/query_cache.result new file mode 100644 index 00000000000..742bfa9e8cc --- /dev/null +++ b/plugin/query_response_time/mysql-test/query_response_time/query_cache.result @@ -0,0 +1,16 @@ +# +# 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 +# +set global query_response_time_stats=on; +set global query_cache_type=on; +set query_cache_type=on; +create table t (a int); +create procedure sp() execute immediate 'select * from t'; +call sp; +a +call sp; +a +drop table t; +drop procedure sp; +set global query_cache_type= default; +set global query_response_time_stats=default; diff --git a/plugin/query_response_time/mysql-test/query_response_time/query_cache.test b/plugin/query_response_time/mysql-test/query_response_time/query_cache.test new file mode 100644 index 00000000000..383c0c337df --- /dev/null +++ b/plugin/query_response_time/mysql-test/query_response_time/query_cache.test @@ -0,0 +1,16 @@ +--echo # +--echo # 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 +--echo # +set global query_response_time_stats=on; +set global query_cache_type=on; +set query_cache_type=on; + +create table t (a int); +create procedure sp() execute immediate 'select * from t'; +call sp; +call sp; +drop table t; +drop procedure sp; + +set global query_cache_type= default; +set global query_response_time_stats=default; diff --git a/plugin/query_response_time/plugin.cc b/plugin/query_response_time/plugin.cc index 0362c6e2792..cbbff67c186 100644 --- a/plugin/query_response_time/plugin.cc +++ b/plugin/query_response_time/plugin.cc @@ -122,7 +122,10 @@ static void query_response_time_audit_notify(MYSQL_THD thd, THDVAR(thd, exec_time_debug) : 0); else #endif - query_response_time_collect(thd->utime_after_query - thd->utime_after_lock); + { + DBUG_ASSERT(thd->utime_after_query >= thd->utime_after_lock); + query_response_time_collect(thd->utime_after_query - thd->utime_after_lock); + } } } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9a666b4754c..68a835c4d70 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -5284,7 +5284,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) (char *) thd->security_ctx->host_or_ip, 1); error= mysql_execute_command(thd, true); MYSQL_QUERY_EXEC_DONE(error); - thd->update_server_status(); } else { @@ -5293,6 +5292,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->update_stats(); qc_executed= TRUE; } + thd->update_server_status(); } /* From 7a88776dc1eb8edd43eb093be49325250df3fa95 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 22 Dec 2025 18:45:32 +0300 Subject: [PATCH 108/152] MDEV-28650 Server crashes in Item_func_nextval::val_int after select from view default_used was missing as view is parsed on its own lex. extend_table_list() decides maybe_need_prelocking based on default_used and prelocking_strategy->handle_table() was skipped for view, so internal_tables was not updated (they could be stale from previous statement). --- mysql-test/suite/sql_sequence/next.result | 53 +++++++++++++++++++++++ mysql-test/suite/sql_sequence/next.test | 30 +++++++++++++ sql/sql_view.cc | 2 + 3 files changed, 85 insertions(+) diff --git a/mysql-test/suite/sql_sequence/next.result b/mysql-test/suite/sql_sequence/next.result index c20b4a9a1e2..08b3d208dee 100644 --- a/mysql-test/suite/sql_sequence/next.result +++ b/mysql-test/suite/sql_sequence/next.result @@ -548,3 +548,56 @@ SELECT SETVAL (v,0); ERROR 42S02: 'test.v' is not a SEQUENCE UNLOCK TABLES; DROP VIEW v; +# +# MDEV-28650 Server crashes in Item_func_nextval::val_int after select from view +# +create sequence s; +create table t1 (a int not null default nextval(s)); +insert into t1 values(),(); +flush tables; +select default(a) from t1; +default(a) +1001 +1002 +create algorithm=merge view v1 as select default(a) from t1; +select * from v1; +default(a) +1003 +1004 +Select * from v1; +default(a) +1005 +1006 +prepare ps from 'SELECT * from v1'; +execute ps; +default(a) +1007 +1008 +Execute ps; +default(a) +1009 +1010 +drop prepare ps; +create or replace algorithm=temptable view v1 as select default(a) from t1; +select * from v1; +default(a) +1011 +1012 +Select * from v1; +default(a) +1013 +1014 +prepare ps from 'SELECT * from v1'; +execute ps; +default(a) +1015 +1016 +Execute ps; +default(a) +1017 +1018 +drop prepare ps; +drop view v1; +drop table t1; +drop sequence s; +# End of 10.11 tests diff --git a/mysql-test/suite/sql_sequence/next.test b/mysql-test/suite/sql_sequence/next.test index 18b52961a54..9cdec110597 100644 --- a/mysql-test/suite/sql_sequence/next.test +++ b/mysql-test/suite/sql_sequence/next.test @@ -299,3 +299,33 @@ SELECT SETVAL (v,0); UNLOCK TABLES; DROP VIEW v; --disable_ps2_protocol + +--echo # +--echo # MDEV-28650 Server crashes in Item_func_nextval::val_int after select from view +--echo # +create sequence s; +create table t1 (a int not null default nextval(s)); +insert into t1 values(),(); +flush tables; +select default(a) from t1; + +create algorithm=merge view v1 as select default(a) from t1; +select * from v1; +Select * from v1; +prepare ps from 'SELECT * from v1'; +execute ps; Execute ps; +drop prepare ps; + +create or replace algorithm=temptable view v1 as select default(a) from t1; +select * from v1; +Select * from v1; +prepare ps from 'SELECT * from v1'; +execute ps; Execute ps; +drop prepare ps; + +# cleanup +drop view v1; +drop table t1; +drop sequence s; + +--echo # End of 10.11 tests diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 1c67331ce49..b88d47a4e73 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1720,6 +1720,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, if (lex->first_select_lex()->options & OPTION_TO_QUERY_CACHE) old_lex->first_select_lex()->options|= OPTION_TO_QUERY_CACHE; + old_lex->default_used= lex->default_used; + #ifndef NO_EMBEDDED_ACCESS_CHECKS if (table->view_suid) { From 3b07a44a23a83f41366cd1fb2b7356a02618f002 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sat, 10 Jan 2026 16:25:15 +0300 Subject: [PATCH 109/152] MDEV-32724 Segmentation fault due to Deep Recursion in table.cc and sql_lex.cc Recursive CTE wrongly detected anchor because inner non-recursive CTE wrongly assigned with-element table to itself due to inner-outer name clash. --- mysql-test/main/cte_recursive.result | 71 ++++++++++++++++++++++++++++ mysql-test/main/cte_recursive.test | 57 ++++++++++++++++++++++ sql/sql_cte.cc | 3 +- 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index e35d26f170c..a9dc688035e 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -6083,3 +6083,74 @@ select 1 as f1 (select f1 from r); ERROR 42S22: Unknown column 'f2' in 'SELECT' # End of 10.6 tests +# +# MDEV-32724 Segmentation fault due to Deep Recursion in table.cc and sql_lex.cc +# +with recursive r (y) as ( +with r (z) as (select 1 from r) select 1 from r +union all +select y from r) +select y from r; +ERROR HY000: No anchors for recursive WITH element 'r' +# r2 CTE is the anchor for r (original behavior): +with recursive r (y) as ( +with recursive r2 (z) as ( +select z + 1 from r2 where z < 2 +union all +select 1) +select z from r2 +union all +select y * 2 from r where y < 10) +select y from r; +y +1 +2 +2 +4 +4 +8 +8 +16 +16 +# It is different with the name clash, +# select y * 2 from r is attached to inner r: +with recursive r (y) as ( +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select y * 2 from r where y < 10) +select y from r; +ERROR 42S22: Unknown column 'y' in 'SELECT' +# The whole set of SELECTs is attached to CTE: +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select z * 2 from r where z < 10; +z +1 +2 +2 +4 +# In this case no outer recursion can occur as every r +# is taken by the inner recursive CTE: +with recursive r (y) as ( +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select z * 2 from r where z < 10) +select y from r; +y +1 +2 +2 +4 +# End of 10.11 tests diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test index 3447ced1a1c..d6fb2a47884 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -4184,3 +4184,60 @@ with recursive r as ( --echo # End of 10.6 tests + +--echo # +--echo # MDEV-32724 Segmentation fault due to Deep Recursion in table.cc and sql_lex.cc +--echo # +--error ER_RECURSIVE_WITHOUT_ANCHORS +with recursive r (y) as ( + with r (z) as (select 1 from r) select 1 from r + union all + select y from r) +select y from r; + +--echo # r2 CTE is the anchor for r (original behavior): +with recursive r (y) as ( + with recursive r2 (z) as ( + select z + 1 from r2 where z < 2 + union all + select 1) + select z from r2 + union all + select y * 2 from r where y < 10) +select y from r; + +--echo # It is different with the name clash, +--echo # select y * 2 from r is attached to inner r: +--error ER_BAD_FIELD_ERROR +with recursive r (y) as ( + with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) + select z from r + union all + select y * 2 from r where y < 10) +select y from r; + +--echo # The whole set of SELECTs is attached to CTE: +with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) +select z from r +union all +select z * 2 from r where z < 10; + +--echo # In this case no outer recursion can occur as every r +--echo # is taken by the inner recursive CTE: +with recursive r (y) as ( + with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) + select z from r + union all + select z * 2 from r where z < 10) +select y from r; + +--echo # End of 10.11 tests diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 92bb1dc596a..8f819a7a944 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -540,7 +540,8 @@ void With_element::check_dependencies_in_select(st_select_lex *sl, if (is_spec_select) { With_clause *with_clause= sl->master_unit()->with_clause; - if (with_clause) + /* Non-recursive CTE cannot SELECT from itself */ + if (with_clause && with_clause->with_recursive) tbl->with= with_clause->find_table_def(tbl, NULL, NULL); if (!tbl->with) tbl->with= owner->find_table_def(tbl, From 5597f877fecc6d033337efd5c6ad10afb7e8e753 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sun, 4 Jan 2026 12:03:44 +0300 Subject: [PATCH 110/152] MDEV-33289 INTERVAL partitioning by system time does not work close to the end of timestamp range 1. Fix empty part_elem->id in prep_alter_part_table(). On auto-create newly added partition has id 0. It came from set_up_default_partitions() for new part_info (thd->work_part_info). vers_update_el_ids() can work only with unassigned ids (UINT_MAX32), so we assign it explicitly on pushing into tab_part_info. 2. If range value is out of TIMESTAMP_MAX_VALUE set it to TIMESTAMP_MAX_VALUE, but only if the history partition is the last one, otherwise push ER_DATA_OUT_OF_RANGE. Error is to create multiple out-of-range partitions (e.g. with PARTITIONS clause in CREATE TABLE). --- .../suite/versioning/r/partition.result | 36 +++++++++++++++++-- mysql-test/suite/versioning/t/partition.test | 32 +++++++++++++++-- sql/sql_partition.cc | 17 ++++++++- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 6f690f21675..d828e775c3d 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -314,7 +314,7 @@ create table t1 (i int) with system versioning partition by system_time interval 6 day limit 98; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'limit 98' at line 2 create or replace table t1 (pk int) with system versioning -partition by system_time interval 10 year partitions 3; +partition by system_time interval 10 year partitions 4; ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL' # INTERVAL and ALTER TABLE create or replace table t1 (i int) with system versioning @@ -3521,7 +3521,6 @@ partition ver_p1 history, partition ver_p2 history, partition ver_pn current); alter table `t1` partition by system_time interval 7 year ; -ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL' drop table t1; # # MDEV-29114 ALTER puts row into different partition for system_time @@ -3587,6 +3586,39 @@ x 1 drop table t1; # +# MDEV-33289 INTERVAL partitioning by system time does not work close to +# the end of timestamp range +# +set timestamp= unix_timestamp('2024-01-21 00:00:00'); +create or replace table t (a int) with system versioning +partition by system_time interval 10 year auto; +insert into t values (0); +set timestamp= unix_timestamp('2034-01-20 23:59:59'); +update t set a= 1; +set timestamp= unix_timestamp('2034-01-20 00:00:00'); +update t set a= 2; +set timestamp= unix_timestamp('2035-01-21 00:00:00'); +update t set a= 3; +select * from t partition (p0); +a +0 +select * from t partition (p1); +a +2 +select * from t partition (pn); +a +3 +select * from t for system_time as of '2035-01-20 00:00:00'; +a +2 +drop tables t; +create or replace table t (a int) with system versioning +partition by system_time interval 10 year partitions 10; +ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL' +create or replace table t (a int) with system versioning +partition by system_time interval 10 year; +drop table t; +# # End of 10.11 tests # set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 7acc4c22f8d..634ec009597 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -278,7 +278,7 @@ partition by system_time interval 6 day limit 98; --error ER_DATA_OUT_OF_RANGE create or replace table t1 (pk int) with system versioning -partition by system_time interval 10 year partitions 3; +partition by system_time interval 10 year partitions 4; --echo # INTERVAL and ALTER TABLE create or replace table t1 (i int) with system versioning @@ -2764,7 +2764,6 @@ partition by system_time interval 1 month ( partition ver_p2 history, partition ver_pn current); ---error ER_DATA_OUT_OF_RANGE alter table `t1` partition by system_time interval 7 year ; drop table t1; @@ -2814,6 +2813,35 @@ Select * from t1 for system_time as of '2000-01-01 00:59:59'; drop table t1; +--echo # +--echo # MDEV-33289 INTERVAL partitioning by system time does not work close to +--echo # the end of timestamp range +--echo # +set timestamp= unix_timestamp('2024-01-21 00:00:00'); +create or replace table t (a int) with system versioning +partition by system_time interval 10 year auto; +insert into t values (0); +set timestamp= unix_timestamp('2034-01-20 23:59:59'); +update t set a= 1; +set timestamp= unix_timestamp('2034-01-20 00:00:00'); +update t set a= 2; +set timestamp= unix_timestamp('2035-01-21 00:00:00'); +update t set a= 3; + +select * from t partition (p0); +select * from t partition (p1); +select * from t partition (pn); +select * from t for system_time as of '2035-01-20 00:00:00'; +drop tables t; + +--error ER_DATA_OUT_OF_RANGE +create or replace table t (a int) with system versioning +partition by system_time interval 10 year partitions 10; + +create or replace table t (a int) with system versioning +partition by system_time interval 10 year; +drop table t; + --echo # --echo # End of 10.11 tests --echo # diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5dac3292eba..bd8df5757e9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1572,7 +1572,21 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) part_info->range_int_array[el->id]= el->range_value= my_tz_OFFSET0->TIME_to_gmt_sec(<ime, &error); if (error) - goto err; + { + if (error == ER_WARN_DATA_OUT_OF_RANGE) + { + /* Partial interval partition must be last history partition */ + if (el->id < hist_parts - 1) + goto err; + /* range_value is open endpoint (less than TIMESTAMP_MAX_VALUE) */ + part_info->range_int_array[el->id]= el->range_value= TIMESTAMP_MAX_VALUE; + vers_info->hist_part= el; + el= it++; + break; + } + else + goto err; + } if (vers_info->hist_part->range_value <= thd->query_start()) vers_info->hist_part= el; } @@ -5467,6 +5481,7 @@ that are reorganised. partition_element *part_elem= alt_it++; if (*fast_alter_table) part_elem->part_state= PART_TO_BE_ADDED; + part_elem->id= tab_part_info->partitions.elements; if (unlikely(tab_part_info->partitions.push_back(part_elem, thd->mem_root))) goto err; From 6fcd87ba4d37560fe63e2901315ed2983723ccb6 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sat, 20 Dec 2025 19:56:08 +0300 Subject: [PATCH 111/152] MDEV-33985 Server crashes at Item_func_nextval::val_int Pure aliases are not handled properly by Item_func_nextval::val_int(). add_table_to_list() does not create MDL request for pure aliases, i.e. when there is no table_list->db set or TL_OPTION_ALIAS was set. When the expression is not inside CTE the case with empty db is handled by: else if (!lex->with_cte_resolution && lex->copy_db_to(&db)) DBUG_RETURN(0); So, table_list gets current database name and the query is failed with ER_NO_SUCH_TABLE error. The fix adds the case of is_pure_alias() for Item_func_nextval::val_int() and fails it with ER_NOT_SEQUENCE2 error. Note: semantics for TL_OPTION_ALIAS cannot be based on empty db, only parser can set TL_OPTION_ALIAS as resolve_references_to_cte() relies on TL_OPTION_ALIAS after copy_db_to(). --- mysql-test/suite/sql_sequence/next.result | 11 +++++++++++ mysql-test/suite/sql_sequence/next.test | 12 ++++++++++++ sql/item_func.cc | 7 ++++++- sql/sql_lex.h | 7 +++++++ sql/sql_parse.cc | 2 +- sql/table.h | 1 + 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/sql_sequence/next.result b/mysql-test/suite/sql_sequence/next.result index 08b3d208dee..bf1f24db375 100644 --- a/mysql-test/suite/sql_sequence/next.result +++ b/mysql-test/suite/sql_sequence/next.result @@ -600,4 +600,15 @@ drop prepare ps; drop view v1; drop table t1; drop sequence s; +# +# MDEV-33985 Server crashes at Item_func_nextval::val_int +# +select * from (select 1 as a) x where (nextval(x)); +ERROR 42S02: Table 'test.x' doesn't exist +select (with x(x) as (select 1) select * from x where (nextval(x))); +ERROR 42S02: 'x' is not a SEQUENCE +create sequence s; +select next value for s1 from s as s1; +ERROR 42S02: Table 'test.s1' doesn't exist +drop sequence s; # End of 10.11 tests diff --git a/mysql-test/suite/sql_sequence/next.test b/mysql-test/suite/sql_sequence/next.test index 9cdec110597..88b21cc2d76 100644 --- a/mysql-test/suite/sql_sequence/next.test +++ b/mysql-test/suite/sql_sequence/next.test @@ -328,4 +328,16 @@ drop view v1; drop table t1; drop sequence s; +--echo # +--echo # MDEV-33985 Server crashes at Item_func_nextval::val_int +--echo # +--error ER_NO_SUCH_TABLE +select * from (select 1 as a) x where (nextval(x)); +--error ER_NOT_SEQUENCE2 +select (with x(x) as (select 1) select * from x where (nextval(x))); +create sequence s; +--error ER_NO_SUCH_TABLE +select next value for s1 from s as s1; +drop sequence s; + --echo # End of 10.11 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 19cd1e38730..37d63d984f3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -7135,12 +7135,17 @@ longlong Item_func_nextval::val_int() longlong value; int error; const char *key; + DBUG_ENTER("Item_func_nextval::val_int"); + if (table_list->is_pure_alias()) + { + my_error(ER_NOT_SEQUENCE2, MYF(0), table_list->alias.str); + DBUG_RETURN(0); + } uint length= get_table_def_key(table_list, &key); THD *thd; SEQUENCE_LAST_VALUE *entry; char buff[80]; String key_buff(buff,sizeof(buff), &my_charset_bin); - DBUG_ENTER("Item_func_nextval::val_int"); update_table(); DBUG_ASSERT(table); DBUG_ASSERT(table->s->sequence); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 700cd18ae2b..85f355aa953 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -5317,5 +5317,12 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead, void mark_or_conds_to_avoid_pushdown(Item *cond); + +inline +bool TABLE_LIST::is_pure_alias() const +{ + return !db.length || (table_options & TL_OPTION_ALIAS); +} + #endif /* MYSQL_SERVER */ #endif /* SQL_LEX_INCLUDED */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0523fc492e6..d89a4d4d4ca 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8501,7 +8501,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, lex->add_to_query_tables(ptr); // Pure table aliases do not need to be locked: - if (ptr->db.str && !(table_options & TL_OPTION_ALIAS)) + if (!ptr->is_pure_alias()) { MDL_REQUEST_INIT(&ptr->mdl_request, MDL_key::TABLE, ptr->db.str, ptr->table_name.str, mdl_type, MDL_TRANSACTION); diff --git a/sql/table.h b/sql/table.h index 341532b6345..79ace8dcec7 100644 --- a/sql/table.h +++ b/sql/table.h @@ -3045,6 +3045,7 @@ struct TABLE_LIST bool is_active_sjm(); bool is_sjm_scan_table(); bool is_jtbm() { return MY_TEST(jtbm_subselect != NULL); } + bool is_pure_alias() const; st_select_lex_unit *get_unit(); st_select_lex *get_single_select(); void wrap_into_nested_join(List &join_list); From b68f878fdc0e67c58b8e59334ac3157612e6dda3 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 20 Jan 2026 13:36:42 +0300 Subject: [PATCH 112/152] MDEV-36876 Crash during the Item_subselect::init - outer_select is NULL Comparison between vector and scalar is invalid (ER_OPERAND_COLUMNS) and handled by the parser. The problem is outer_context is missing because relink_hack() cannot recover it due to !builtin_select.first_inner_unit() condition. This condition was set by previous relink hack called for previous expression some(select 1). Since there can be arbitrary number of such expressions there seems to be no point in such a limitation. MTR test do not fail without that condition, so the fix proposes to remove it. --- mysql-test/main/sp-bugs.result | 24 ++++++++++++++++++++++++ mysql-test/main/sp-bugs.test | 29 +++++++++++++++++++++++++++++ sql/sql_lex.cc | 3 +-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/sp-bugs.result b/mysql-test/main/sp-bugs.result index b172c3bc21c..b435ba4a91a 100644 --- a/mysql-test/main/sp-bugs.result +++ b/mysql-test/main/sp-bugs.result @@ -399,3 +399,27 @@ DROP FUNCTION f; # # End of 10.5 tests # +# +# MDEV-36876 Crash during the Item_subselect::init - outer_select is NULL +# +# Vectors are not allowed for SOME/ANY +select row(1, 2) = some(select row(1, 2)); +ERROR 21000: Operand should contain 1 column(s) +# Fine +select 1 = some(select 1) = all(select 1); +1 = some(select 1) = all(select 1) +1 +# Comparison between vector and scalar +select row(1, 2) = some(select 1) = all(select 1); +ERROR 21000: Operand should contain 2 column(s) +# Same +create table t1 (dt datetime(6) default row(1, 2) = some(select 1) = all(select 1)); +ERROR 21000: Operand should contain 1 column(s) +create procedure test_proc (id varchar(255)) +begin +declare dt datetime(6) default row(1, 2) = some(select 1) = all(select 1); +end$$ +drop procedure test_proc; +# +# End of 11.8 tests +# diff --git a/mysql-test/main/sp-bugs.test b/mysql-test/main/sp-bugs.test index 9a4b867a92b..067ca9b6ae8 100644 --- a/mysql-test/main/sp-bugs.test +++ b/mysql-test/main/sp-bugs.test @@ -437,3 +437,32 @@ DROP FUNCTION f; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # MDEV-36876 Crash during the Item_subselect::init - outer_select is NULL +--echo # +--echo # Vectors are not allowed for SOME/ANY +--error ER_OPERAND_COLUMNS +select row(1, 2) = some(select row(1, 2)); +--echo # Fine +select 1 = some(select 1) = all(select 1); +--echo # Comparison between vector and scalar +--error ER_OPERAND_COLUMNS +select row(1, 2) = some(select 1) = all(select 1); + +--echo # Same +--error ER_OPERAND_COLUMNS +create table t1 (dt datetime(6) default row(1, 2) = some(select 1) = all(select 1)); + +delimiter $$; +create procedure test_proc (id varchar(255)) +begin + declare dt datetime(6) default row(1, 2) = some(select 1) = all(select 1); +end$$ +delimiter ;$$ + +drop procedure test_proc; + +--echo # +--echo # End of 11.8 tests +--echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d31620324a6..28b191490e2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -10817,8 +10817,7 @@ void LEX::relink_hack(st_select_lex *select_lex) { if (!select_stack_top) // Statements of the second type { - if (!select_lex->outer_select() && - !builtin_select.first_inner_unit()) + if (!select_lex->outer_select()) { builtin_select.register_unit(select_lex->master_unit(), &builtin_select.context); From 4ff94f212dc4010a49940f892e826dd085dd19b5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 23 Jan 2026 14:29:35 +0100 Subject: [PATCH 113/152] MDEV-38532 followup include private server headers into libmariadbd-dev, where plugin server headers already were. Not in libmariadb-dev. It's different from RPMs, but RPMs don't have a dedicated embedded devel package. --- debian/libmariadb-dev.install | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/libmariadb-dev.install b/debian/libmariadb-dev.install index 6afae738943..48120822f81 100644 --- a/debian/libmariadb-dev.install +++ b/debian/libmariadb-dev.install @@ -23,7 +23,6 @@ usr/include/mariadb/mysql/plugin_auth.h usr/include/mariadb/mysql_com.h usr/include/mariadb/mysql_version.h usr/include/mariadb/mysqld_error.h -usr/include/mariadb/server/* usr/lib/*/libmariadb.a usr/lib/*/libmariadb.so usr/lib/*/libmariadbclient.a From b6d0e23d76fe5936b6a29379ab494852e4d493b1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 17 Dec 2025 22:58:23 +0100 Subject: [PATCH 114/152] MDEV-38365 SHA2 auth plugin crash on large packets use my_safe_alloca() as the key_len comes directly from the client Reported by Pavel Kohout, Aisle Research, www.aisle.com --- plugin/auth_mysql_sha2/sha256crypt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugin/auth_mysql_sha2/sha256crypt.c b/plugin/auth_mysql_sha2/sha256crypt.c index 672a0afb9d6..d11cfc6c2f8 100644 --- a/plugin/auth_mysql_sha2/sha256crypt.c +++ b/plugin/auth_mysql_sha2/sha256crypt.c @@ -17,6 +17,10 @@ #include #include "mysql_sha2.h" +#define MAX_ALLOCA_SZ 4096 +#define my_safe_alloca(size) (((size) > MAX_ALLOCA_SZ) ? malloc(size) : alloca(size)) +#define my_safe_afree(ptr, size) do { if ((size) > MAX_ALLOCA_SZ) free(ptr); } while(0) + /* based on https://www.akkadia.org/drepper/SHA-crypt.txt */ /* SHA256-based Unix crypt implementation. @@ -38,7 +42,7 @@ void sha256_crypt_r(const unsigned char *key, size_t key_len, #endif = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; void *ctx = alloca(my_sha256_context_size()); - unsigned char *p_bytes = alloca(key_len); + unsigned char *p_bytes = my_safe_alloca(key_len); unsigned char *s_bytes = alloca(salt_len); my_sha256_multi(alt, key, key_len, salt, salt_len, key, key_len, NULL); @@ -123,4 +127,6 @@ void sha256_crypt_r(const unsigned char *key, size_t key_len, b64_from_24bit (tmp[18], tmp[28], tmp[8], 4); b64_from_24bit (tmp[9], tmp[19], tmp[29], 4); b64_from_24bit (0, tmp[31], tmp[30], 3); /* == 43 bytes in total */ + + my_safe_afree(p_bytes, key_len); } From 76fc1861ca4b8074357227e6ce4dd627c8b6c67a Mon Sep 17 00:00:00 2001 From: gkodinov Date: Fri, 23 Jan 2026 14:45:19 +0200 Subject: [PATCH 115/152] MDEV-38642: Missing Null terminator in the definition of mysqldump's --system typelib There was a missing NULL element terminator for --system's type library definition. This was causing a crash in find_type_eol when e.g. an incomplete value was passed to --system where it keeps iterating until it finds the NULL as a typelib element. Fixed by appending a NullS to the definition. Test case added. --- client/mysqldump.c | 4 ++-- mysql-test/main/mysqldump-system-incomplete.result | 6 ++++++ mysql-test/main/mysqldump-system-incomplete.test | 11 +++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 mysql-test/main/mysqldump-system-incomplete.result create mode 100644 mysql-test/main/mysqldump-system-incomplete.test diff --git a/client/mysqldump.c b/client/mysqldump.c index 7372498ffeb..2499bc0b1e1 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -138,10 +138,10 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m #define OPT_SYSTEM_STATS 32 #define OPT_SYSTEM_TIMEZONES 64 static const char *opt_system_type_values[]= - {"all", "users", "plugins", "udfs", "servers", "stats", "timezones"}; + {"all", "users", "plugins", "udfs", "servers", "stats", "timezones", NullS}; static TYPELIB opt_system_types= { - array_elements(opt_system_type_values), "system dump options", + array_elements(opt_system_type_values) - 1, "system dump options", opt_system_type_values, NULL }; static ulonglong opt_system= 0ULL; diff --git a/mysql-test/main/mysqldump-system-incomplete.result b/mysql-test/main/mysqldump-system-incomplete.result new file mode 100644 index 00000000000..bd96c02eb32 --- /dev/null +++ b/mysql-test/main/mysqldump-system-incomplete.result @@ -0,0 +1,6 @@ +# +# MDEV-38642 Missing Null terminator in the definition of mysqldump's +# --system typelib +# +# Should not crash +# End of 10.6 tests diff --git a/mysql-test/main/mysqldump-system-incomplete.test b/mysql-test/main/mysqldump-system-incomplete.test new file mode 100644 index 00000000000..e3fd64dee7c --- /dev/null +++ b/mysql-test/main/mysqldump-system-incomplete.test @@ -0,0 +1,11 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-38642 Missing Null terminator in the definition of mysqldump's +--echo # --system typelib +--echo # + +--echo # Should not crash +--exec $MYSQL_DUMP --system=user > /dev/null + +--echo # End of 10.6 tests From b5dbf22657b6998017e89e81c7a7585268f9a6c0 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 29 Dec 2025 00:43:28 +0400 Subject: [PATCH 116/152] MDEV-38471 - funcs_1.processlist_val_no_prot fails sporadically Test output was affected by incompletely closed preceding connections. Wait for connections to leave I_S.PROCESSLIST before issuing SHOW PROCESSLIST. Also fixes similar failures in funcs_1.processlist_val_ps. --- mysql-test/suite/funcs_1/datadict/processlist_val.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc index fa6ed4049d6..80bd3928683 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc @@ -54,6 +54,8 @@ ################################################################################ # Basic preparations +let $count_sessions= 1; +source include/wait_until_count_sessions.inc; --error 0, ER_CANNOT_USER DROP USER test_user@'localhost'; CREATE USER test_user@'localhost'; From 4b8118058981c9db647d83d5dff3288d0c39cbf8 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 4 Nov 2025 14:33:33 +0400 Subject: [PATCH 117/152] MDEV-38076 - main.mdev375 fails sporadically Test was affected by incompletely closed preceding connections. Wait for preceding connections to decrement Threads_connected before testing ER_CON_COUNT_ERROR condition. --- mysql-test/main/mdev375.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/main/mdev375.test b/mysql-test/main/mdev375.test index f489d232be8..b20e161f4c0 100644 --- a/mysql-test/main/mdev375.test +++ b/mysql-test/main/mdev375.test @@ -4,6 +4,8 @@ --source include/not_embedded.inc --disable_service_connection +let $count_sessions=1; +--source include/wait_until_count_sessions.inc set @save_log_warnings=@@log_warnings, @save_max_connections=@@max_connections; SET GLOBAL log_warnings=4; SET GLOBAL max_connections=10; From 5688678ff46dc6353b014b16f48cdcaf3e97b37b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 10 Sep 2025 15:59:02 +1000 Subject: [PATCH 118/152] MDEV-37615: Clang based static analysis false postive reports on UNINIT_VAR Clang upstream bug https://github.com/llvm/llvm-project/issues/173210 shows that a "int x=x" construct will in the intermediate representation have code to read from x. With this generated sanitizer=undefined and static analyzers will all see the uninitialized read and write. Because clang has a stronger implementation of following paths to uninitialized variables, "#define UNINIT_VAR(x) x" is the which is what our release binaries use is the ideal path for this compiler. Clang based compilers with error during compilation if any uninitialized behaviour is detected at compile time because of 0c80ddb519bd06efbd7ccf2a2487b2503cd16db5. Corrects MDEV-36542 - 6fd57f478f585249bdca242b1576ac0a7bd7aacf. --- include/my_global.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index fe970ad1304..16360581f74 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -444,11 +444,10 @@ extern "C" int madvise(void *addr, size_t len, int behav); /* Suppress uninitialized variable warning without generating code. */ -#if defined(__GNUC__) && !defined(WITH_UBSAN) +#if defined(__GNUC__) && !defined(__clang__) /* GCC specific self-initialization which inhibits the warning. - clang and static analysis will complain loudly about this - so compile those under WITH_UBSAN. + clang and static analysis will complain loudly about this. */ #define UNINIT_VAR(x) x= x #elif defined(FORCE_INIT_OF_VARS) From 28b09e353734d9d2fe20da3b279c9a5b0b476658 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 18:18:51 +0100 Subject: [PATCH 119/152] MDEV-34984 rr_from_cache does not update generated columns handler read methods only update generated columns when they read into record[0]. As rr_from_cache() reads into the cache, it has to update them explicitly. --- mysql-test/main/olap.result | 16 +++++++++++++++- mysql-test/main/olap.test | 12 +++++++++++- sql/records.cc | 11 ++++++----- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result index 4c81f76432f..b8aea1c7c2b 100644 --- a/mysql-test/main/olap.result +++ b/mysql-test/main/olap.result @@ -905,5 +905,19 @@ f NULL NULL DROP TABLE t1; -# End of 10.3 Tests +# End of 10.3 tests +# +# MDEV-34984 rr_from_cache does not update generated columns +# +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048) GENERATED ALWAYS AS (i)); +INSERT INTO t1 (i) SELECT seq FROM seq_1_to_6000; +SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP limit 5; +MAX(c) +1 +10 +100 +1000 +1001 +DROP TABLE t1; +# End of 10.11 tests ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test index 4daae933e51..265303b452b 100644 --- a/mysql-test/main/olap.test +++ b/mysql-test/main/olap.test @@ -1,3 +1,4 @@ +--source include/have_sequence.inc --source include/test_db_charset_latin1.inc set @sav_dpi= @@div_precision_increment; @@ -534,6 +535,15 @@ SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WIT --enable_warnings DROP TABLE t1; ---echo # End of 10.3 Tests +--echo # End of 10.3 tests + +--echo # +--echo # MDEV-34984 rr_from_cache does not update generated columns +--echo # +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048) GENERATED ALWAYS AS (i)); +INSERT INTO t1 (i) SELECT seq FROM seq_1_to_6000; +SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP limit 5; +DROP TABLE t1; +--echo # End of 10.11 tests --source include/test_db_charset_restore.inc diff --git a/sql/records.cc b/sql/records.cc index 612d0eb248e..33d1213401e 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -696,6 +696,7 @@ static int rr_from_cache(READ_RECORD *info) int16 error; uchar *position,*ref_position,*record_pos; ulong record; + TABLE *table= info->table; for (;;) { @@ -705,13 +706,14 @@ static int rr_from_cache(READ_RECORD *info) { shortget(error,info->cache_pos); if (info->print_error) - info->table->file->print_error(error,MYF(0)); + table->file->print_error(error,MYF(0)); } else { error=0; - memcpy(info->record(), info->cache_pos, - (size_t) info->table->s->reclength); + memcpy(info->record(), info->cache_pos, table->s->reclength); + if (table->vfield) + table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); } info->cache_pos+=info->reclength; return ((int) error); @@ -746,8 +748,7 @@ static int rr_from_cache(READ_RECORD *info) record=uint3korr(position); position+=3; record_pos=info->cache+record*info->reclength; - if (unlikely((error= (int16) info->table->file-> - ha_rnd_pos(record_pos,info->ref_pos)))) + if ((error= (int16) table->file->ha_rnd_pos(record_pos,info->ref_pos))) { record_pos[info->error_offset]=1; shortstore(record_pos,error); From 4f9a13e9ecf2f99c323964bcec893a6556d66619 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 18:26:49 +0100 Subject: [PATCH 120/152] cleanup: don't allocate memory for virtual columns in rr cache as rr_from_cache() does not store virtual columns, it doesn't need to allocate memory for them either --- sql/records.cc | 14 +++++++------- sql/sql_const.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sql/records.cc b/sql/records.cc index 33d1213401e..5a7f5385f06 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -251,10 +251,10 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, !(table->file->ha_table_flags() & HA_FAST_KEY_READ) && (table->db_stat & HA_READ_ONLY || table->reginfo.lock_type < TL_FIRST_WRITE) && - (ulonglong) table->s->reclength* (table->file->stats.records+ - table->file->stats.deleted) > - (ulonglong) MIN_FILE_LENGTH_TO_USE_ROW_CACHE && - info->io_cache->end_of_file/info->ref_length * table->s->reclength > + (ulonglong) table->s->stored_rec_length * + (table->file->stats.records + table->file->stats.deleted) > + MIN_FILE_LENGTH_TO_USE_ROW_CACHE && + info->io_cache->end_of_file/info->ref_length * table->s->stored_rec_length > (my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE && !table->s->blob_fields && info->ref_length <= MAX_REFLENGTH) @@ -661,11 +661,11 @@ static int init_rr_cache(THD *thd, READ_RECORD *info) uint rec_cache_size, cache_records; DBUG_ENTER("init_rr_cache"); - info->reclength= ALIGN_SIZE(info->table->s->reclength+1); + info->reclength= ALIGN_SIZE(info->table->s->stored_rec_length + 1); if (info->reclength < STRUCT_LENGTH) info->reclength= ALIGN_SIZE(STRUCT_LENGTH); - info->error_offset= info->table->s->reclength; + info->error_offset= info->table->s->stored_rec_length; cache_records= thd->variables.read_rnd_buff_size / (info->reclength + STRUCT_LENGTH); rec_cache_size= cache_records * info->reclength; @@ -711,7 +711,7 @@ static int rr_from_cache(READ_RECORD *info) else { error=0; - memcpy(info->record(), info->cache_pos, table->s->reclength); + memcpy(info->record(), info->cache_pos, table->s->stored_rec_length); if (table->vfield) table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); } diff --git a/sql/sql_const.h b/sql/sql_const.h index a142eb0f041..bd0a0d89268 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -212,7 +212,7 @@ The following parameters is to decide when to use an extra cache to optimise seeks when reading a big table in sorted order */ -#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (10L*1024*1024) +#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (10ULL*1024*1024) #define MIN_ROWS_TO_USE_TABLE_CACHE 100 #define MIN_ROWS_TO_USE_BULK_INSERT 100 From 8a0f327675e9b4a1e0ae2e3a97fe001122a9db03 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 19:21:53 +0100 Subject: [PATCH 121/152] MDEV-32263 Increase mysqldump default max_allowed_packet variable --- client/mysqldump.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqldump.cc b/client/mysqldump.cc index a9c8aa59449..2cdcea3bdba 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -492,7 +492,7 @@ static struct my_option my_long_options[] = {"max_allowed_packet", 0, "The maximum packet length to send to or receive from server.", &opt_max_allowed_packet, &opt_max_allowed_packet, 0, - GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, + GET_ULONG, REQUIRED_ARG, 1024LL*1024*1024, 4096, (longlong) 2L*1024L*1024L*1024L, 0, 1024, 0}, {"max-statement-time", 0, "Max statement execution time. If unset, overrides server default with 0.", From d08fd6343eee502cdcdba6c98c1042a4bf6d34a1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 26 Jan 2026 10:01:05 +0100 Subject: [PATCH 122/152] MDEV-38506 fix the test followup for 11f228cbb2b3 --- .../suite/engines/funcs/r/rpl_do_grant.result | 68 +------------------ 1 file changed, 3 insertions(+), 65 deletions(-) diff --git a/mysql-test/suite/engines/funcs/r/rpl_do_grant.result b/mysql-test/suite/engines/funcs/r/rpl_do_grant.result index 0d2908809b9..0e3b578adda 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_do_grant.result +++ b/mysql-test/suite/engines/funcs/r/rpl_do_grant.result @@ -211,71 +211,9 @@ connection master; DROP TABLE t1; DROP PROCEDURE p1; connection slave; -### ii) Test case in which REVOKE partially succeeds -connection master; -include/rpl_reset.inc -connection master; -CREATE TABLE t1(c1 INT); -CREATE PROCEDURE p1() SELECT * FROM t1 | -CREATE USER 'user49119'@'localhost'; -GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost'; -############################################################## -### Showing grants for both users: root and user49119 (master) -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -GRANT EXECUTE ON PROCEDURE `test`.`p1` TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection slave; -############################################################## -### Showing grants for both users: root and user49119 (master) -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -GRANT EXECUTE ON PROCEDURE `test`.`p1` TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection master; -## This statement will make the revoke fail because root has no -## execute grant. However, it will still revoke the grant for -## user49119. -REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost'; -ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1' -############################################################## -### Showing grants for both users: root and user49119 (master) -### after revoke statement failure -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection slave; -############################################################# -### Showing grants for both users: root and user49119 (slave) -### after revoke statement failure (should match -SHOW GRANTS FOR 'user49119'@'localhost'; -Grants for user49119@localhost -GRANT USAGE ON *.* TO `user49119`@`localhost` -SHOW GRANTS FOR CURRENT_USER; -Grants for root@localhost -GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION -GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION -############################################################## -connection master; -DROP TABLE t1; -DROP PROCEDURE p1; -DROP USER 'user49119'@'localhost'; -connection slave; +# +# TODO: Re-enable test-case after fixing MDEV-29848 +# include/rpl_reset.inc connection master; grant all on *.* to foo@"1.2.3.4"; From 387fe5ecc3a697dd0e59fb4e4ff02fcc0385c467 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 13:20:51 +0100 Subject: [PATCH 123/152] MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure 1. InnoDB should return HA_ERR_ROLLBACK if it aborts a transaction internally 2. the server should recognize it and perform an automatic rollback --- .../r/binlog_row_mix_innodb_myisam.result | 2 -- .../r/binlog_stm_mix_innodb_myisam.result | 2 -- .../suite/innodb/r/alter_copy_bulk.result | 23 +++++++++++++++++-- .../suite/innodb/t/alter_copy_bulk.test | 20 ++++++++++++++-- sql/sql_insert.cc | 3 ++- storage/innobase/handler/ha_innodb.cc | 1 + 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index ce6847d59d3..ed4a7cb4698 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -363,8 +363,6 @@ INSERT INTO t1 values (3,3); CREATE TEMPORARY TABLE t2 (primary key (a)) engine=innodb select * from t1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back DROP TABLE IF EXISTS t2; Warnings: Note 1051 Unknown table 'test.t2' diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index 30dd08e33eb..d27f8bf705d 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -329,8 +329,6 @@ INSERT INTO t1 values (3,3); CREATE TEMPORARY TABLE t2 (primary key (a)) engine=innodb select * from t1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back DROP TABLE IF EXISTS t2; Warnings: Note 1051 Unknown table 'test.t2' diff --git a/mysql-test/suite/innodb/r/alter_copy_bulk.result b/mysql-test/suite/innodb/r/alter_copy_bulk.result index 9be8e98539e..e2bbb2c46cc 100644 --- a/mysql-test/suite/innodb/r/alter_copy_bulk.result +++ b/mysql-test/suite/innodb/r/alter_copy_bulk.result @@ -113,8 +113,7 @@ DROP TABLE t1; DROP TABLE IF EXISTS t2; # restart # -# MDEV-37296 ALTER TABLE allows adding unique hash key -# with duplicate values +# MDEV-37296 ALTER TABLE allows adding unique hash key with duplicate values # CREATE TABLE t (pk INT PRIMARY KEY, a INT, b TEXT) ENGINE=InnoDB; INSERT INTO t VALUES (5,3,'foo'), (1,NULL,'bar'), (3,3,'foo'); @@ -134,3 +133,23 @@ pk a b 3 3 foo 5 3 foo DROP TABLE t; +# +# MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure +# +CREATE TABLE t (a INT) ENGINE=InnoDB; +START TRANSACTION; +SELECT * FROM t; +a +SAVEPOINT A; +select @@in_transaction; +@@in_transaction +1 +CREATE TEMPORARY TABLE tmp (a TINYINT) ENGINE=InnoDB AS SELECT 256 AS a; +ERROR 22003: Out of range value for column 'a' at row 1 +select @@in_transaction; +@@in_transaction +0 +ROLLBACK TO SAVEPOINT A; +ERROR 42000: SAVEPOINT A does not exist +DROP TABLE t; +# End of 10.11 tests diff --git a/mysql-test/suite/innodb/t/alter_copy_bulk.test b/mysql-test/suite/innodb/t/alter_copy_bulk.test index ffa8e70f77e..fb95cfda908 100644 --- a/mysql-test/suite/innodb/t/alter_copy_bulk.test +++ b/mysql-test/suite/innodb/t/alter_copy_bulk.test @@ -132,8 +132,7 @@ DROP TABLE IF EXISTS t2; --source include/restart_mysqld.inc --echo # ---echo # MDEV-37296 ALTER TABLE allows adding unique hash key ---echo # with duplicate values +--echo # MDEV-37296 ALTER TABLE allows adding unique hash key with duplicate values --echo # CREATE TABLE t (pk INT PRIMARY KEY, a INT, b TEXT) ENGINE=InnoDB; INSERT INTO t VALUES (5,3,'foo'), (1,NULL,'bar'), (3,3,'foo'); @@ -142,3 +141,20 @@ ALTER TABLE t ADD UNIQUE (a,b); SHOW CREATE TABLE t; SELECT * FROM t; DROP TABLE t; + +--echo # +--echo # MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure +--echo # +CREATE TABLE t (a INT) ENGINE=InnoDB; +START TRANSACTION; +SELECT * FROM t; +SAVEPOINT A; +select @@in_transaction; +--error ER_WARN_DATA_OUT_OF_RANGE +CREATE TEMPORARY TABLE tmp (a TINYINT) ENGINE=InnoDB AS SELECT 256 AS a; +select @@in_transaction; +--error ER_SP_DOES_NOT_EXIST +ROLLBACK TO SAVEPOINT A; +DROP TABLE t; + +--echo # End of 10.11 tests diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e59f5ba596f..9f8366dc0d6 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4685,7 +4685,8 @@ void select_insert::abort_result_set() finalize_replace(table, info.handle_duplicates, info.ignore); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - table->file->extra(HA_EXTRA_ABORT_ALTER_COPY); + if (table->file->extra(HA_EXTRA_ABORT_ALTER_COPY) == HA_ERR_ROLLBACK) + thd->transaction_rollback_request= true; /* If at least one row has been inserted/modified and will stay in the table (the table doesn't have transactions) we must write to diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ecd98ebc631..e93d3d3f58d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15938,6 +15938,7 @@ ha_innobase::extra( trx = check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 0; trx->rollback(); + return(HA_ERR_ROLLBACK); } break; default:/* Do nothing */ From b930eef317878d82640668b627ba2d0116abd631 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 13:54:38 +0100 Subject: [PATCH 124/152] MDEV-37326 Assertion failure upon update on versioned partitioned table with long unique under READ COMMITTED if ha_partition::position() is asked for a position of a closed partition, don't ask the underlying engine, just set the partition number. in fact, the partition is open and can be perfectly used, the assert is over-zealous. but in the future it might be actually closed. --- mysql-test/main/partition_innodb.result | 11 ++++++++++- mysql-test/main/partition_innodb.test | 15 +++++++++++++-- sql/ha_partition.cc | 12 ++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/partition_innodb.result b/mysql-test/main/partition_innodb.result index cbaec5504cb..0ce7bf6b140 100644 --- a/mysql-test/main/partition_innodb.result +++ b/mysql-test/main/partition_innodb.result @@ -1091,6 +1091,15 @@ a 6 7 DROP TABLE t1; -# # End of 10.3 tests # +# MDEV-37326 Assertion failure upon update on versioned partitioned table with long unique under READ COMMITTED +# +set session transaction isolation level read committed; +create table t (c text, unique(c)) engine=innodb with system versioning partition by system_time; +insert into t values ('foo'); +flush tables; +update t set c = 'bar'; +drop table t; +set session transaction isolation level repeatable read; +# End of 10.11 tests diff --git a/mysql-test/main/partition_innodb.test b/mysql-test/main/partition_innodb.test index e9771811534..c62defdaa30 100644 --- a/mysql-test/main/partition_innodb.test +++ b/mysql-test/main/partition_innodb.test @@ -1149,7 +1149,18 @@ INSERT INTO t1 VALUES (); SELECT * FROM t1; DROP TABLE t1; ---echo # --echo # End of 10.3 tests ---echo # --enable_service_connection + +--echo # +--echo # MDEV-37326 Assertion failure upon update on versioned partitioned table with long unique under READ COMMITTED +--echo # +set session transaction isolation level read committed; +create table t (c text, unique(c)) engine=innodb with system versioning partition by system_time; +insert into t values ('foo'); +flush tables; +update t set c = 'bar'; +drop table t; +set session transaction isolation level repeatable read; + +--echo # End of 10.11 tests diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index f3b2bf194c6..dfb4b0e1804 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5508,13 +5508,17 @@ void ha_partition::position(const uchar *record) { handler *file= m_file[m_last_part]; size_t pad_length; - DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part)); DBUG_ENTER("ha_partition::position"); - file->position(record); int2store(ref, m_last_part); - memcpy((ref + PARTITION_BYTES_IN_POS), file->ref, file->ref_length); - pad_length= m_ref_length - PARTITION_BYTES_IN_POS - file->ref_length; + if (bitmap_is_set(&(m_part_info->read_partitions), m_last_part)) + { + file->position(record); + memcpy((ref + PARTITION_BYTES_IN_POS), file->ref, file->ref_length); + pad_length= m_ref_length - PARTITION_BYTES_IN_POS - file->ref_length; + } + else + pad_length= m_ref_length - PARTITION_BYTES_IN_POS; if (pad_length) memset((ref + PARTITION_BYTES_IN_POS + file->ref_length), 0, pad_length); From 7e14749d968ee27dfb65ea1a0e005ee7aa58bfa5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 14:31:01 +0100 Subject: [PATCH 125/152] MDEV-37341 Assertion failures `null_ptr < ptr' and `ptr - null_ptr <= (int)table->s->rec_buff_length' with BEFORE trigger and UPDATE in SIMULTANEOUS_ASSIGNMENT there is no need to switch value items to new nullable copies of table Field's - they must refer to old values in the row, which can never be null anyway. skipping this redundant step simplifies moving field to record[1] and back in fill_record() --- mysql-test/main/simultaneous_assignment.result | 13 +++++++++++++ mysql-test/main/simultaneous_assignment.test | 13 +++++++++++++ sql/sql_base.cc | 8 ++++---- sql/sql_update.cc | 6 ++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/simultaneous_assignment.result b/mysql-test/main/simultaneous_assignment.result index 041d7bf0f5c..251a41ff768 100644 --- a/mysql-test/main/simultaneous_assignment.result +++ b/mysql-test/main/simultaneous_assignment.result @@ -232,3 +232,16 @@ UPDATE t SET t = '', s = 0; ERROR HY000: Cannot cast 'int' as 'geometry' in assignment of `test`.`t`.`s` ALTER TABLE t force; DROP TABLE t; +# +# MDEV-37341 Assertion failures `null_ptr < ptr' and `ptr - null_ptr <= (int)table->s->rec_buff_length' with BEFORE trigger and UPDATE +# +create table t (a int primary key, b int not null); +insert into t values (1, 1); +create trigger tr before update on t for each row set new.b=10; +set sql_mode= simultaneous_assignment; +update t set b=null, a=b; +select * from t; +a b +1 10 +drop table t; +# End of 10.11 tests diff --git a/mysql-test/main/simultaneous_assignment.test b/mysql-test/main/simultaneous_assignment.test index cfc802d9caf..3c03048be26 100644 --- a/mysql-test/main/simultaneous_assignment.test +++ b/mysql-test/main/simultaneous_assignment.test @@ -221,3 +221,16 @@ UPDATE t SET t = '', s = 0; ALTER TABLE t force; DROP TABLE t; + +--echo # +--echo # MDEV-37341 Assertion failures `null_ptr < ptr' and `ptr - null_ptr <= (int)table->s->rec_buff_length' with BEFORE trigger and UPDATE +--echo # +create table t (a int primary key, b int not null); +insert into t values (1, 1); +create trigger tr before update on t for each row set new.b=10; +set sql_mode= simultaneous_assignment; +update t set b=null, a=b; +select * from t; +drop table t; + +--echo # End of 10.11 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c13f2850a90..2014bbae7bc 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9063,8 +9063,8 @@ static void unwind_stored_field_offsets(const List &fields, Item_field *en if (f->stored_in_db()) { TABLE *table= f->table; - f->move_field_offset((my_ptrdiff_t) (table->record[0] - - table->record[1])); + table->field[f->field_index]->move_field_offset( + (my_ptrdiff_t) (table->record[0] - table->record[1])); } } } @@ -9163,8 +9163,8 @@ fill_record(THD *thd, TABLE *table_arg, List &fields, List &values, which contains row before update (see MDEV-13417) */ if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT) - rfield->move_field_offset((my_ptrdiff_t) (table->record[1] - - table->record[0])); + table->field[rfield->field_index]->move_field_offset( + (my_ptrdiff_t) (table->record[1] - table->record[0])); } } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index eeec277c527..d176eca4165 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -538,7 +538,8 @@ int mysql_update(THD *thd, DBUG_RETURN(TRUE); switch_to_nullable_trigger_fields(fields, table); - switch_to_nullable_trigger_fields(values, table); + if (!(thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)) + switch_to_nullable_trigger_fields(values, table); /* Apply the IN=>EXISTS transformation to all subqueries and optimize them */ if (select_lex->optimize_unflattened_subqueries(false)) @@ -2233,7 +2234,8 @@ int multi_update::prepare(List ¬_used_values, { TABLE *table= ((Item_field*)(fields_for_table[i]->head()))->field->table; switch_to_nullable_trigger_fields(*fields_for_table[i], table); - switch_to_nullable_trigger_fields(*values_for_table[i], table); + if (!(thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)) + switch_to_nullable_trigger_fields(*values_for_table[i], table); } } copy_field= new (thd->mem_root) Copy_field[max_fields]; From 71d4cae8668d5ec1b23a28866e6673c82788d042 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 16:03:37 +0100 Subject: [PATCH 126/152] 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. --- sql/sql_prepare.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index eead163d7ed..737183edd8b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1511,7 +1511,18 @@ static int mysql_test_update(Prepared_statement *stmt, { List_iterator_fast fs(select->item_list), vs(stmt->lex->value_list); while (Item *f= fs++) - vs++->associate_with_target_field(thd, static_cast(f)); + { + /* + note that if `f` is a non-updatable view field, it may be not + inherited from Item_field, and the cast below will essentially + produce garbage. But ER_NONUPDATEABLE_COLUMN will happen before it's + ever dereferenced. + */ +#ifndef DBUG_OFF + if (!dynamic_cast(f)) f= (Item_field*)0x01; // let it crash +#endif + vs++->associate_with_target_field(thd, reinterpret_cast(f)); + } } /* TODO: here we should send types of placeholders to the client. */ DBUG_RETURN(0); From ac493871999e45cd3ab5f6989955b59c736595b2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 16:31:47 +0100 Subject: [PATCH 127/152] MDEV-37506 Assertion if FLUSH PRIVILEGES is interrupted in --skip-grant-tables * fail acl_load() if it was killed, this will cause all privileges to be reset to their original pre-load values. * only increment grant_version if privileges were, in fact, updated --- sql/sql_acl.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1ad90da04f1..81e3812069e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2656,8 +2656,6 @@ static bool acl_load(THD *thd, const Grant_tables& tables) SCOPE_CLEAR(thd->variables.sql_mode, MODE_PAD_CHAR_TO_FULL_LENGTH); - grant_version++; /* Privileges updated */ - const Host_table& host_table= tables.host_table(); init_sql_alloc(key_memory_acl_mem, &acl_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (host_table.table_exists()) // "host" table may not exist (e.g. in MySQL 5.6.7+) @@ -2940,6 +2938,10 @@ static bool acl_load(THD *thd, const Grant_tables& tables) init_check_host(); + if (thd->killed) + DBUG_RETURN(TRUE); + + grant_version++; // Privileges updated thd->bootstrap= !initialized; // keep FLUSH PRIVILEGES connection special initialized=1; DBUG_RETURN(FALSE); From 387de3d5b83deff2fad356dd67492baf79d8fe2d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 21:07:23 +0100 Subject: [PATCH 128/152] cleanup: remove unused argument --- sql/field.h | 10 +++++----- sql/unireg.cc | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/field.h b/sql/field.h index 0c8af45e435..c31b38d78e6 100644 --- a/sql/field.h +++ b/sql/field.h @@ -948,7 +948,7 @@ public: */ virtual bool memcpy_field_possible(const Field *from) const= 0; virtual bool make_empty_rec_store_default_value(THD *thd, Item *item); - virtual void make_empty_rec_reset(THD *thd) + virtual void make_empty_rec_reset() { reset(); } @@ -4838,12 +4838,12 @@ public: } bool memcpy_field_possible(const Field *from) const override { return false; } - void make_empty_rec_reset(THD *) override + void make_empty_rec_reset() override { if (flags & NOT_NULL_FLAG) { set_notnull(); - store((longlong) 1, true); + store(1LL, true); } else reset(); @@ -4918,9 +4918,9 @@ public: { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } - void make_empty_rec_reset(THD *thd) override + void make_empty_rec_reset() override { - Field::make_empty_rec_reset(thd); + Field::make_empty_rec_reset(); } int store_field(Field *from) override { return from->save_in_field(this); } diff --git a/sql/unireg.cc b/sql/unireg.cc index 28a7deb4da3..e6a33bb3b19 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1176,7 +1176,7 @@ static bool make_empty_rec_store_default(THD *thd, Field *regfield, } return false; } - regfield->make_empty_rec_reset(thd); + regfield->make_empty_rec_reset(); return false; } From d7702e0b0f23960dae50153e197b6be18c862219 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 21:16:25 +0100 Subject: [PATCH 129/152] MDEV-37481 empty value inserted if BEFORE trigger and ENUM NOT NULL field must use field->make_empty_rec_reset() for resetting a field to its type default value. ENUM is historically weird. --- mysql-test/main/type_enum.result | 18 +++++++++++++++++- mysql-test/main/type_enum.test | 18 ++++++++++++++---- sql/field_conv.cc | 2 +- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/type_enum.result b/mysql-test/main/type_enum.result index f5c6dbae2ad..3a3a8bc2a17 100644 --- a/mysql-test/main/type_enum.result +++ b/mysql-test/main/type_enum.result @@ -1,4 +1,3 @@ -DROP TABLE if exists t1; CREATE TABLE t1 ( field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL, KEY field (field) @@ -2601,3 +2600,20 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def COALESCE(c_int, c_enum) 253 11 0 Y 0 39 8 COALESCE(c_int, c_enum) DROP TABLE t1; +# +# MDEV-37481 empty value inserted if BEFORE trigger and ENUM NOT NULL field +# +set sql_mode=''; +create table t1 (a int not null, b enum('N','Y') not null); +insert into t1 (a) values (1); +create trigger test_trigger before update on t1 for each row begin end; +insert into t1 (a) values (2); +Warnings: +Warning 1364 Field 'b' doesn't have a default value +select * from t1; +a b +1 N +2 N +drop table t1; +set sql_mode=default; +# End of 10.11 tests diff --git a/mysql-test/main/type_enum.test b/mysql-test/main/type_enum.test index a79547b2d10..e43a7109c0f 100644 --- a/mysql-test/main/type_enum.test +++ b/mysql-test/main/type_enum.test @@ -2,10 +2,6 @@ # Problem with many enums # ---disable_warnings -DROP TABLE if exists t1; ---enable_warnings - CREATE TABLE t1 ( field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL, KEY field (field) @@ -608,3 +604,17 @@ SELECT COALESCE(c_int, c_enum) FROM t1; --enable_view_protocol DROP TABLE t1; + +--echo # +--echo # MDEV-37481 empty value inserted if BEFORE trigger and ENUM NOT NULL field +--echo # +set sql_mode=''; +create table t1 (a int not null, b enum('N','Y') not null); +insert into t1 (a) values (1); +create trigger test_trigger before update on t1 for each row begin end; +insert into t1 (a) values (2); +select * from t1; +drop table t1; +set sql_mode=default; + +--echo # End of 10.11 tests diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 6e90d92fcf8..b4e2c03013c 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -173,7 +173,7 @@ int convert_null_to_field_value_or_error(Field *field, uint err) } MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table, &field->table->write_set); - field->reset(); // Note: we ignore any potential failure of reset() here. + field->make_empty_rec_reset(); dbug_tmp_restore_column_map(&field->table->write_set, old_map); if (field == field->table->next_number_field) From 7b9d3a4df6c925b5f195df493580cc2bb51c11d8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 26 Jan 2026 00:29:30 +0100 Subject: [PATCH 130/152] MDEV-38654 Assertion `str[strlen(str)-1] != '\n'' failed upon federated discovery error relax the assert, allowing '\n' at the end if the string is exactly MYSQL_ERRMSG_SIZE-1 bytes long. It likely doesn't end with '\n' but was truncated at the middle. also, use MYSQL_ERRMSG_SIZE in my_error.c not a separate define that must be "kept in sync" --- mysys/my_error.c | 9 +++------ sql/mysqld.cc | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/mysys/my_error.c b/mysys/my_error.c index 106e51de581..a23ca7040c2 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -19,9 +19,6 @@ #include #include -/* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */ -#define ERRMSGSIZE (512) - /* Define some external variables for error handling */ /* @@ -109,7 +106,7 @@ void my_error(uint nr, myf MyFlags, ...) { const char *format; va_list args; - char ebuff[ERRMSGSIZE]; + char ebuff[MYSQL_ERRMSG_SIZE]; DBUG_ENTER("my_error"); DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d", nr, MyFlags, errno)); if (!(format = my_get_err_msg(nr))) @@ -141,7 +138,7 @@ void my_error(uint nr, myf MyFlags, ...) void my_printf_error(uint error, const char *format, myf MyFlags, ...) { va_list args; - char ebuff[ERRMSGSIZE]; + char ebuff[MYSQL_ERRMSG_SIZE]; DBUG_ENTER("my_printf_error"); DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); @@ -168,7 +165,7 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...) void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap) { - char ebuff[ERRMSGSIZE]; + char ebuff[MYSQL_ERRMSG_SIZE]; DBUG_ENTER("my_printv_error"); DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0d8008d2df5..c02c4e9debe 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3349,7 +3349,7 @@ void my_message_sql(uint error, const char *str, myf MyFlags) DBUG_ASSERT((MyFlags & ~(ME_BELL | ME_ERROR_LOG | ME_ERROR_LOG_ONLY | ME_NOTE | ME_WARNING | ME_FATAL)) == 0); - DBUG_ASSERT(str[strlen(str)-1] != '\n'); + DBUG_ASSERT(str[strlen(str)-1] != '\n' || strlen(str) == MYSQL_ERRMSG_SIZE-1); if (MyFlags & ME_NOTE) { From c0acc3cc8f1ec24e96b1ee192fdf6e4b6ccf4e0a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 29 Dec 2025 20:35:09 +0100 Subject: [PATCH 131/152] MDEV-38209 REFERENCES permission on particular schema is sometimes ignored some I_S tables require "any non-SELECT privilege on the table". If only SELECT was granted on the global level and something non-SELECT on the schema level, then we need to check schema level privileges explicitly, because check_grant() doesn't do that and get_all_tables() doesn't look deeper if SELECT is present on the global level. --- mysql-test/main/information_schema_db.result | 40 +++++++++++++++++++- mysql-test/main/information_schema_db.test | 38 ++++++++++++++++++- sql/sql_show.cc | 20 ++++++---- 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/mysql-test/main/information_schema_db.result b/mysql-test/main/information_schema_db.result index 376656a5727..977634db92a 100644 --- a/mysql-test/main/information_schema_db.result +++ b/mysql-test/main/information_schema_db.result @@ -378,6 +378,44 @@ disconnect con1; connection default; drop user u@localhost; drop database db; -# # End of 10.4 tests # +# MDEV-38209 REFERENCES permission on particular schema is sometimes ignored +# +create database db1; +CREATE TABLE db1.author ( +id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +name VARCHAR(100) NOT NULL +) ENGINE = InnoDB; +CREATE TABLE db1.book ( +id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +title VARCHAR(200) NOT NULL, +author_id SMALLINT UNSIGNED NOT NULL, +CONSTRAINT `fk_book_author` + FOREIGN KEY (author_id) REFERENCES db1.author (id) +ON DELETE CASCADE +ON UPDATE RESTRICT +) ENGINE = InnoDB; +grant select on *.* to u@localhost; +grant select, references on db1.* to u@localhost; +connect u,localhost,u,,db1; +select user(); +user() +u@localhost +show grants; +Grants for u@localhost +GRANT SELECT ON *.* TO `u`@`localhost` +GRANT SELECT, REFERENCES ON `db1`.* TO `u`@`localhost` +select table_name,constraint_name from information_schema.referential_constraints; +table_name constraint_name +book fk_book_author +select table_name,constraint_name from information_schema.table_constraints; +table_name constraint_name +author PRIMARY +book PRIMARY +book fk_book_author +disconnect u; +connection default; +drop user u@localhost; +drop database db1; +# End of 10.11 tests diff --git a/mysql-test/main/information_schema_db.test b/mysql-test/main/information_schema_db.test index 4bd8bb46d08..1593e9b91d6 100644 --- a/mysql-test/main/information_schema_db.test +++ b/mysql-test/main/information_schema_db.test @@ -324,6 +324,42 @@ show index in t3; drop user u@localhost; drop database db; ---echo # --echo # End of 10.4 tests + --echo # +--echo # MDEV-38209 REFERENCES permission on particular schema is sometimes ignored +--echo # + +create database db1; +CREATE TABLE db1.author ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE db1.book ( + id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + title VARCHAR(200) NOT NULL, + author_id SMALLINT UNSIGNED NOT NULL, + CONSTRAINT `fk_book_author` + FOREIGN KEY (author_id) REFERENCES db1.author (id) + ON DELETE CASCADE + ON UPDATE RESTRICT +) ENGINE = InnoDB; + +grant select on *.* to u@localhost; +grant select, references on db1.* to u@localhost; + +--connect u,localhost,u,,db1 +select user(); +show grants; +--sorted_result +select table_name,constraint_name from information_schema.referential_constraints; +--sorted_result +select table_name,constraint_name from information_schema.table_constraints; +--disconnect u + +--connection default +drop user u@localhost; +drop database db1; + +--echo # End of 10.11 tests diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 390b74463ac..6c845bcabe2 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7334,10 +7334,12 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, /* we know that the table or at least some of the columns have necessary privileges, but the caller didn't pass down the GRANT_INFO object, so we have to rediscover everything again :( */ - check_grant(thd, SELECT_ACL, tables, 0, 1, 1); - - if (!(tables->grant.all_privilege() & need)) - DBUG_RETURN(0); + if (!(acl_get_all3(thd->security_ctx, db_name->str, 0) & need)) + { + check_grant(thd, need, tables, 1, 1, true); + if (!(tables->grant.all_privilege() & need)) + DBUG_RETURN(0); + } } #endif @@ -8452,10 +8454,12 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, /* we know that the table or at least some of the columns have necessary privileges, but the caller didn't pass down the GRANT_INFO object, so we have to rediscover everything again :( */ - check_grant(thd, SELECT_ACL, tables, 0, 1, 1); - - if (!(tables->grant.all_privilege() & need)) - DBUG_RETURN(0); + if (!(acl_get_all3(thd->security_ctx, db_name->str, 0) & need)) + { + check_grant(thd, need, tables, 1, 1, true); + if (!(tables->grant.all_privilege() & need)) + DBUG_RETURN(0); + } } #endif From 9f28e7be59de58b92573351cd69978d7602feb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 26 Jan 2026 12:23:49 +0200 Subject: [PATCH 132/152] MDEV-23298 fixup: have_perfschema.inc --- mysql-test/main/create_or_replace.result | 29 -------------------- mysql-test/main/create_or_replace.test | 26 ------------------ mysql-test/main/create_or_replace_pfs.result | 27 ++++++++++++++++++ mysql-test/main/create_or_replace_pfs.test | 28 +++++++++++++++++++ 4 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 mysql-test/main/create_or_replace_pfs.result create mode 100644 mysql-test/main/create_or_replace_pfs.test diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 42eae555ab4..692c9d3e322 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -582,32 +582,3 @@ DROP TABLE IF EXISTS tm, t; # # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_persistent; -# -# MDEV-23298 Assertion `table_list->prelocking_placeholder == -# TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on -# CREATE OR REPLACE TABLE -# -create table t2 (a int); -insert into t2 values(1),(2); -CREATE TABLE t1 (a INT); -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; -drop table t1; -CREATE TABLE t1 (a INT); -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; -SELECT * from t1; -q a -SELECT 1 1 -SELECT 1 2 -drop table t1; -CREATE TABLE t1 (a INT); -lock table t1 write,t2 read, sys.sys_config read; -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; -unlock tables; -select * from t1; -q a -SELECT 1 1 -SELECT 1 2 -drop table t1,t2; -# -# End of 10.6 tests -# diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 30c709f53f2..5758620de71 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -532,29 +532,3 @@ DROP TABLE IF EXISTS tm, t; --echo # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_persistent; - ---echo # ---echo # MDEV-23298 Assertion `table_list->prelocking_placeholder == ---echo # TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on ---echo # CREATE OR REPLACE TABLE ---echo # - -create table t2 (a int); -insert into t2 values(1),(2); -CREATE TABLE t1 (a INT); -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; -drop table t1; -CREATE TABLE t1 (a INT); -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; -SELECT * from t1; -drop table t1; -CREATE TABLE t1 (a INT); -lock table t1 write,t2 read, sys.sys_config read; -CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; -unlock tables; -select * from t1; -drop table t1,t2; - ---echo # ---echo # End of 10.6 tests ---echo # diff --git a/mysql-test/main/create_or_replace_pfs.result b/mysql-test/main/create_or_replace_pfs.result new file mode 100644 index 00000000000..24e40ea3b31 --- /dev/null +++ b/mysql-test/main/create_or_replace_pfs.result @@ -0,0 +1,27 @@ +# +# MDEV-23298 Assertion `table_list->prelocking_placeholder == +# TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +# CREATE OR REPLACE TABLE +# +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1,t2; +# End of 10.6 tests diff --git a/mysql-test/main/create_or_replace_pfs.test b/mysql-test/main/create_or_replace_pfs.test new file mode 100644 index 00000000000..d7ad6d32336 --- /dev/null +++ b/mysql-test/main/create_or_replace_pfs.test @@ -0,0 +1,28 @@ +# +# Check CREATE OR REPLACE TABLE +# +--source include/have_perfschema.inc + +--echo # +--echo # MDEV-23298 Assertion `table_list->prelocking_placeholder == +--echo # TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +--echo # CREATE OR REPLACE TABLE +--echo # + +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +drop table t1,t2; + +--echo # End of 10.6 tests From 308ed52fb08d65f349a3949c253fd55043c859f3 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 26 Jan 2026 09:09:16 +0100 Subject: [PATCH 133/152] columnstore 25.10.3 --- storage/columnstore/columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index e3a2563b588..df0dc363078 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit e3a2563b58898de8117199eddfd7845c5a24886d +Subproject commit df0dc363078a2016b256cef2ba8145ce267dc2d1 From 6229192647ddd71b5942f985358377fd47d61d80 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 19 Jan 2026 15:04:53 +1100 Subject: [PATCH 134/152] MDEV-38327 Minor optimizer comment cleanups and refactoring factor out common index merge checks of quick select types --- sql/opt_range.h | 13 +++++++++++++ sql/rowid_filter.h | 2 +- sql/sql_delete.cc | 6 +----- sql/sql_select.cc | 29 ++++++++--------------------- storage/innobase/row/row0sel.cc | 2 +- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/sql/opt_range.h b/sql/opt_range.h index fae6bdc1afc..9fdafed160a 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1307,6 +1307,13 @@ public: virtual void add_used_key_part_to_set()=0; }; +inline bool is_index_merge(int qtype) +{ + return qtype == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || + qtype == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + qtype == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || + qtype == QUICK_SELECT_I::QS_TYPE_ROR_UNION; +} struct st_qsel_param; class PARAM; @@ -1576,6 +1583,7 @@ public: +/* Index merge sort union */ class QUICK_INDEX_MERGE_SELECT : public QUICK_INDEX_SORT_SELECT { private: @@ -1593,6 +1601,7 @@ public: void add_keys_and_lengths(String *key_names, String *used_lengths) override; }; +/* Index merge sort intersection */ class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT { protected: @@ -1611,6 +1620,8 @@ public: /* + Index merge intersection + Rowid-Ordered Retrieval (ROR) index intersection quick select. This quick select produces intersection of row sequences returned by several QUICK_RANGE_SELECTs it "merges". @@ -1698,6 +1709,8 @@ public: /* + Index merge union + Rowid-Ordered Retrieval index union select. This quick select produces union of row sequences returned by several quick select it "merges". diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h index 3f18c2edb60..0b041e7aeab 100644 --- a/sql/rowid_filter.h +++ b/sql/rowid_filter.h @@ -129,7 +129,7 @@ 5. At the execution stage In the function sub_select() just before the first access of a join table s employing a range filter - The method JOIN_TAB::build_range_rowid_filter_if_needed() is called + The method JOIN_TAB::build_range_rowid_filter() is called The method fills the filter using the quick select created by JOIN::make_range_rowid_filters(). diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index c6d6916e0a0..45d194cbee7 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -159,11 +159,7 @@ bool Update_plan::save_explain_data_intern(THD *thd, /* Set jtype */ if (select && select->quick) { - int quick_type= select->quick->get_type(); - if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) || - (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) || - (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || - (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)) + if (is_index_merge(select->quick->get_type())) explain->jtype= JT_INDEX_MERGE; else explain->jtype= JT_RANGE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b986e59656e..a228c6d6843 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -27404,17 +27404,13 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } else if (select && select->quick) // Range found by opt_range { - int quick_type= select->quick->get_type(); - /* - assume results are not ordered when index merge is used - TODO: sergeyp: Results of all index merge selects actually are ordered + /* + assume results are not ordered when index merge is used + TODO: sergeyp: Results of all index merge selects actually are ordered by clustered PK values. */ - - if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || - quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) + + if (is_index_merge(select->quick->get_type())) { /* we set ref_key=MAX_KEY instead of -1, because test_if_cheaper_ordering() @@ -27654,10 +27650,7 @@ check_reverse_order: goto skipped_filesort; quick_type= select->quick->get_type(); - if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || - quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || + if (is_index_merge(quick_type) || quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) { tab->limit= 0; @@ -30850,10 +30843,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, { cur_quick= tab_select->quick; quick_type= cur_quick->get_type(); - if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) || - (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) || - (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || - (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)) + if (is_index_merge(quick_type)) tab_type= type == JT_HASH ? JT_HASH_INDEX_MERGE : JT_INDEX_MERGE; else tab_type= type == JT_HASH ? JT_HASH_RANGE : JT_RANGE; @@ -31055,10 +31045,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, eta->pushed_index_cond= cache_idx_cond; } - if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) + if (is_index_merge(quick_type)) { eta->push_extra(ET_USING); } diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 98ed2b6d7a4..fcbc9e95559 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4034,7 +4034,7 @@ row_search_idx_cond_check( byte* mysql_rec, /*!< out: record in MySQL format (invalid unless prebuilt->idx_cond!=NULL and - we return ICP_MATCH) */ + we return CHECK_POS) */ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct for the table handle */ const rec_t* rec, /*!< in: InnoDB record */ From 2c2a418591b4112a4dd57f59907ab8de45e5776a Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 21 Jan 2026 11:47:43 +1100 Subject: [PATCH 135/152] MDEV-38327 Do not use rowid filter in ref_to_range when the range method is index merge Index merge and rowid filter should not be used together, however, even if index merge is not chosen earlier in best_access_path, it may be chosen again in make_join_select, inside ref_to_range. Therefore this patch ensures that rowid filter is not used when index merge is chosen there. --- mysql-test/main/index_intersect.result | 66 +++++++++++++++++++ mysql-test/main/index_intersect.test | 49 ++++++++++++++ mysql-test/main/index_intersect_innodb.result | 66 +++++++++++++++++++ sql/sql_select.cc | 2 + 4 files changed, 183 insertions(+) diff --git a/mysql-test/main/index_intersect.result b/mysql-test/main/index_intersect.result index c6332591ff5..a6cf0dccd50 100644 --- a/mysql-test/main/index_intersect.result +++ b/mysql-test/main/index_intersect.result @@ -973,3 +973,69 @@ f1 f4 f5 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; +# +# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +# +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 +SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +set optimizer_switch='index_merge_sort_intersection=on'; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +drop table t1; +## MDEV-28878 case +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES +(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), +(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), +(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +SET optimizer_switch='rowid_filter=on'; +SET optimizer_switch='index_merge_sort_intersection=off'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +DROP TABLE t1, t2; diff --git a/mysql-test/main/index_intersect.test b/mysql-test/main/index_intersect.test index d6208f67a92..60bcb135dcf 100644 --- a/mysql-test/main/index_intersect.test +++ b/mysql-test/main/index_intersect.test @@ -476,3 +476,52 @@ DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; + +--echo # +--echo # MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +--echo # +--source include/have_sequence.inc +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 + SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; + +let $query= +select a, b, c from t1 where a=1000 and b=1001000; + +eval explain $query; +eval $query; + +set optimizer_switch='index_merge_sort_intersection=on'; + +eval explain $query; +eval $query; + +analyze table t1; + +eval explain $query; +eval $query; + +drop table t1; + +--echo ## MDEV-28878 case + +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); + +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES + (1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), + (6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), + (11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); + +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; + +SET optimizer_switch='rowid_filter=on'; # Default + +SET optimizer_switch='index_merge_sort_intersection=off'; # Default +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; + +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; + +DROP TABLE t1, t2; diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result index 2aba9dc6fcf..727a79ad09a 100644 --- a/mysql-test/main/index_intersect_innodb.result +++ b/mysql-test/main/index_intersect_innodb.result @@ -979,6 +979,72 @@ f1 f4 f5 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; +# +# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +# +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 +SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +set optimizer_switch='index_merge_sort_intersection=on'; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +drop table t1; +## MDEV-28878 case +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES +(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), +(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), +(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +SET optimizer_switch='rowid_filter=on'; +SET optimizer_switch='index_merge_sort_intersection=off'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +DROP TABLE t1, t2; set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a228c6d6843..ada98c1ea4f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14456,6 +14456,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } tab->type= JT_RANGE; tab->use_quick=1; + if (is_index_merge(tab->quick->get_type())) + tab->clear_range_rowid_filter(); tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. join->best_positions[i].records_read= rows2double(tab->quick->records); From ca39e66060d4735f91fd46d9784b4c91ed6746aa Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Fri, 23 Jan 2026 17:41:24 +0530 Subject: [PATCH 136/152] MDEV-38620: Server crashes in setup_returning_fields upon 2nd execution of multi-table-styled DELETE from a view Analysis: The item_list of builtin_select stores the fields that are there in the RETURNING clause. During the "EXECUTE" command, a "dummy item" is added into the item_list of the select_lex(builtin_select) representing DELETE during Sql_cmd_delete::precheck(). This snippet that adds a dummy item is added because columnstore needs for temporary table. Results are put into a temporary table and to create a temporary table we need to know what columns are there which we get from the select_lex->item_list. As a result, the item_list now has an item even when there is not really RETURNING clause, resulting in execution of the setup_returning_fields() when it should have exited already. Fix: Instead of checking whether builint_select's item_list is empty to determine whether there is RETURNING clause, use a flag. --- mysql-test/main/ps.result | 11 +++++++++++ mysql-test/main/ps.test | 14 ++++++++++++++ sql/sql_lex.cc | 2 ++ sql/sql_lex.h | 5 ++++- sql/sql_yacc.yy | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index 5e0a0e5fd23..7ad4f8c74e5 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -6138,4 +6138,15 @@ a ? ? 1 700 900 DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# MDEV-38620: Server crashes in setup_returning_fields upon 2nd +# execution of multi-table-styled DELETE from a view +# +CREATE TABLE t (a INT); +CREATE VIEW v AS SELECT * FROM t; +PREPARE stmt FROM "DELETE v FROM v"; +EXECUTE stmt; +EXECUTE stmt; +DROP VIEW v; +DROP TABLE t; # End of 11.4 tests diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index c53f9e0030f..3db856dddac 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -5592,4 +5592,18 @@ EXECUTE stmt USING 700, 900; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # MDEV-38620: Server crashes in setup_returning_fields upon 2nd +--echo # execution of multi-table-styled DELETE from a view +--echo # + +CREATE TABLE t (a INT); +CREATE VIEW v AS SELECT * FROM t; +PREPARE stmt FROM "DELETE v FROM v"; +EXECUTE stmt; +EXECUTE stmt; + +DROP VIEW v; +DROP TABLE t; + --echo # End of 11.4 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a05b47ebc1a..46a1f1d4b97 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1337,6 +1337,8 @@ void LEX::start(THD *thd_arg) table_count_update= 0; + has_returning_list= false; + memset(&trg_chistics, 0, sizeof(trg_chistics)); DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 470590b9e90..12fd51805e6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3667,6 +3667,9 @@ public: Activates enforcement of the LIMIT ROWS EXAMINED clause, if present in the query. */ + + bool has_returning_list; + void set_limit_rows_examined() { if (limit_rows_examined) @@ -4946,7 +4949,7 @@ public: SELECT_LEX *returning() { return &builtin_select; } bool has_returning() - { return !builtin_select.item_list.is_empty(); } + { return has_returning_list; } private: bool stmt_create_routine_start(const DDL_options_st &options) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index daf7afa8a6d..db97abff5bc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -13730,6 +13730,7 @@ opt_returning: thd->lex->current_select->parsing_place= IN_RETURNING; thd->lex->push_context(&thd->lex->returning()->context); + thd->lex->has_returning_list= true; } select_item_list { From 12578d8a69c9529b080c5e910d53920a8b4f758d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 26 Jan 2026 23:14:58 +0100 Subject: [PATCH 137/152] MDEV-38604 fix SP execution too --- .../mysql-test/query_response_time/query_cache.result | 6 ++++++ .../mysql-test/query_response_time/query_cache.test | 9 ++++++++- sql/sp_head.cc | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/plugin/query_response_time/mysql-test/query_response_time/query_cache.result b/plugin/query_response_time/mysql-test/query_response_time/query_cache.result index 742bfa9e8cc..79a4689a72b 100644 --- a/plugin/query_response_time/mysql-test/query_response_time/query_cache.result +++ b/plugin/query_response_time/mysql-test/query_response_time/query_cache.result @@ -13,4 +13,10 @@ a drop table t; drop procedure sp; set global query_cache_type= default; +create procedure p1() begin end; +create procedure p2() call p1(); +call p2(); +call p2(); +drop procedure p2; +drop procedure p1; set global query_response_time_stats=default; diff --git a/plugin/query_response_time/mysql-test/query_response_time/query_cache.test b/plugin/query_response_time/mysql-test/query_response_time/query_cache.test index 383c0c337df..89c2bac50d4 100644 --- a/plugin/query_response_time/mysql-test/query_response_time/query_cache.test +++ b/plugin/query_response_time/mysql-test/query_response_time/query_cache.test @@ -11,6 +11,13 @@ call sp; call sp; drop table t; drop procedure sp; - set global query_cache_type= default; + +create procedure p1() begin end; +create procedure p2() call p1(); +call p2(); +call p2(); +drop procedure p2; +drop procedure p1; + set global query_response_time_stats=default; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 926da91ae0b..93d0e4e1587 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3799,7 +3799,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) bool log_slow= !res && thd->enable_slow_log; /* Finalize server status flags after executing a statement. */ - if (log_slow || thd->get_stmt_da()->is_eof()) + if (log_slow || thd->get_stmt_da()->is_eof() || mysql_audit_general_enabled()) thd->update_server_status(); if (thd->get_stmt_da()->is_eof()) From 5b6ad325d2e523b95ab7463f093bd8c0d9529edd Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 27 Jan 2026 13:16:34 +0530 Subject: [PATCH 138/152] MDEV-38667 Assertion in diagnostics area on DDL stats timeout Reason: ====== During InnoDB DDL, statistics updation fails due to lock wait timeout and calls push_warning_printf() to generate warnings but then returns success, causing the SQL layer to attempt calling set_ok_status() when the diagnostics area is already set. Solution: ========= By temporarily setting abort_on_warning to false around operations that prevents warning to error escalation and restore the original setting after calling HA_EXTRA_END_ALTER_COPY for alter operation. --- mysql-test/suite/innodb/r/alter_copy_stats.result | 10 ++++++++++ mysql-test/suite/innodb/t/alter_copy_stats.test | 9 +++++++++ sql/sql_insert.cc | 7 +++++++ 3 files changed, 26 insertions(+) diff --git a/mysql-test/suite/innodb/r/alter_copy_stats.result b/mysql-test/suite/innodb/r/alter_copy_stats.result index 15913a44f55..b6a04cfa01c 100644 --- a/mysql-test/suite/innodb/r/alter_copy_stats.result +++ b/mysql-test/suite/innodb/r/alter_copy_stats.result @@ -103,3 +103,13 @@ n_rows database_name lower(table_name) # Test Cleanup. DROP TABLE t1; DROP TABLE t2; +# +# MDEV-38667 Assertion in diagnostics area on DDL stats timeout +# +set @lock_wait_timeout= @@global.innodb_lock_wait_timeout; +SET innodb_lock_wait_timeout = 1; +CREATE TABLE t ENGINE=InnoDB AS SELECT * FROM mysql.innodb_table_stats; +Warnings: +Warning 1088 Error updating stats for table after table rebuild: Lock wait timeout +SET innodb_lock_wait_timeout = @lock_wait_timeout; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/alter_copy_stats.test b/mysql-test/suite/innodb/t/alter_copy_stats.test index 3b0c59d5726..4a0b905e8e4 100644 --- a/mysql-test/suite/innodb/t/alter_copy_stats.test +++ b/mysql-test/suite/innodb/t/alter_copy_stats.test @@ -88,3 +88,12 @@ FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; --echo # Test Cleanup. DROP TABLE t1; DROP TABLE t2; + +--echo # +--echo # MDEV-38667 Assertion in diagnostics area on DDL stats timeout +--echo # +set @lock_wait_timeout= @@global.innodb_lock_wait_timeout; +SET innodb_lock_wait_timeout = 1; +CREATE TABLE t ENGINE=InnoDB AS SELECT * FROM mysql.innodb_table_stats; +SET innodb_lock_wait_timeout = @lock_wait_timeout; +DROP TABLE t; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index fa52164445f..2362ff59a99 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4382,7 +4382,14 @@ bool select_insert::prepare_eof() if (info.ignore || info.handle_duplicates != DUP_ERROR) if (table->file->ha_table_flags() & HA_DUPLICATE_POS) table->file->ha_rnd_end(); + + /* Don't convert the warning to error in case + statistics updation fails */ + bool save_abort_on_warning= thd->abort_on_warning; + thd->abort_on_warning= false; table->file->extra(HA_EXTRA_END_ALTER_COPY); + thd->abort_on_warning= save_abort_on_warning; + table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); From dc28140c89f6a64a055ef52deed420c53f4a9bea Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Fri, 9 Jan 2026 15:23:41 +0530 Subject: [PATCH 139/152] MDEV-31255: Crash with fulltext search subquery in explain delete/update ft_handler isn't getting initialized for subqueries inside explain delete/update queries. However, ft_handler is accessed inside ha_ft_read(), and is the reason for NULL pointer exception. This is not the case with non-explain delete/update queries, as well as explain/non-explain select queries. Follow the approach the SELECT statements are using in JOIN::optimize_constant_subqueries(): remove SELECT_DESCRIBE flag when invoking optimization of constant subqueries. Single-table UPDATE/DELETEs have SELECT_LEX but don't have JOIN. So, we make optimize_constant_subqueries() not to be a member of JOIN class, and instead move it to SELECT_LEX, and then invoke it from single-table UPDATE/DELETE as well as for SELECT queries. --- .../main/myisam_explain_non_select_all.result | 4 +-- mysql-test/main/ps.result | 8 ++--- mysql-test/suite/innodb_fts/r/fulltext.result | 27 ++++++++++++++++ mysql-test/suite/innodb_fts/t/fulltext.test | 32 +++++++++++++++++++ sql/opt_subselect.cc | 12 +++---- sql/sql_delete.cc | 12 ++++++- sql/sql_lex.h | 1 + sql/sql_select.cc | 2 +- sql/sql_select.h | 1 - sql/sql_update.cc | 12 ++++++- 10 files changed, 95 insertions(+), 16 deletions(-) diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index 193c58a9787..bc6152b8f0a 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -3471,9 +3471,9 @@ JOIN t1 AS a12 ON a12.c1 = a11.c1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: -Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where 0) +Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where multiple equal(NULL, NULL, `test`.`a21`.`c2`)) DROP TABLE t1, t2, t3; #73 CREATE TABLE t1 (id INT); diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index 7c425718af9..cd4b708a96c 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5562,16 +5562,16 @@ CREATE TABLE t3 (c3 INT) ENGINE=MyISAM; EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: -Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where 0) +Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where multiple equal(NULL, NULL, `test`.`a21`.`c2`)) PREPARE stmt FROM "EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 )"; EXECUTE stmt; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: -Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where 0) +Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where multiple equal(NULL, NULL, `test`.`a21`.`c2`)) DEALLOCATE PREPARE stmt; DROP TABLE t1, t2, t3; # diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index d3e6a61a43e..fae2299e590 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -810,3 +810,30 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1, t2; # End of 10.5 tests +# +# MDEV-31255 Crash with Explain DELETE/UPDATE on fulltext search query +# +CREATE TABLE t1 (a INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b CHAR(255), FULLTEXT(b)) ENGINE = InnoDB; +INSERT INTO t2 VALUES ('foo'),('bar'); +EXPLAIN +DELETE +FROM t1 +WHERE EXISTS ( +SELECT * FROM t2 WHERE MATCH (b) AGAINST ('qux' IN NATURAL LANGUAGE MODE) +); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +EXPLAIN +UPDATE t1 +SET t1.a = 3 +WHERE EXISTS ( +SELECT * FROM t2 WHERE MATCH (b) AGAINST ('qux' IN NATURAL LANGUAGE MODE) +); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +DROP TABLE t1, t2; +# +# End of 10.11 tests +# diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 4c7b69d8ee3..3afd0f7f861 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -821,3 +821,35 @@ SHOW CREATE TABLE t1; DROP TABLE t1, t2; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-31255 Crash with Explain DELETE/UPDATE on fulltext search query +--echo # + +CREATE TABLE t1 (a INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b CHAR(255), FULLTEXT(b)) ENGINE = InnoDB; +INSERT INTO t2 VALUES ('foo'),('bar'); + +EXPLAIN +DELETE +FROM t1 +WHERE EXISTS ( + SELECT * FROM t2 WHERE MATCH (b) AGAINST ('qux' IN NATURAL LANGUAGE MODE) +); + +EXPLAIN +UPDATE t1 +SET t1.a = 3 +WHERE EXISTS ( + SELECT * FROM t2 WHERE MATCH (b) AGAINST ('qux' IN NATURAL LANGUAGE MODE) +); + +# Cleanup +DROP TABLE t1, t2; + +--echo # +--echo # End of 10.11 tests +--echo # + diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 63309acbf89..e83225d523d 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -5704,10 +5704,10 @@ bool JOIN::optimize_unflattened_subqueries() @retval FALSE success. @retval TRUE error occurred. */ - -bool JOIN::optimize_constant_subqueries() + +bool SELECT_LEX::optimize_constant_subqueries() { - ulonglong save_options= select_lex->options; + ulonglong save_options= options; bool res; /* Constant subqueries may be executed during the optimization phase. @@ -5716,9 +5716,9 @@ bool JOIN::optimize_constant_subqueries() during optimization, constant subqueries must be optimized for execution, not for EXPLAIN. */ - select_lex->options&= ~SELECT_DESCRIBE; - res= select_lex->optimize_unflattened_subqueries(true); - select_lex->options= save_options; + options&= ~SELECT_DESCRIBE; + res= optimize_unflattened_subqueries(true); + options= save_options; return res; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ed02b77d3b1..c63125249d3 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -491,7 +491,17 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } } - /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */ + /* + Apply the IN=>EXISTS and other transformations to all subqueries and + optimize them. + + Constant subqueries are treated in a special way here: they can be + evaluated even in EXPLAIN statement, so their query plan must be + fully initialized for computation. + */ + if (select_lex->optimize_constant_subqueries()) + DBUG_RETURN(TRUE); + if (select_lex->optimize_unflattened_subqueries(false)) DBUG_RETURN(TRUE); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 85f355aa953..0df986dcd56 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1714,6 +1714,7 @@ public: TABLE_LIST *find_table(THD *thd, const LEX_CSTRING *db_name, const LEX_CSTRING *table_name); + bool optimize_constant_subqueries(); }; typedef class st_select_lex SELECT_LEX; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5371a9fecad..3def5217451 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2325,7 +2325,7 @@ JOIN::optimize_inner() if (!allowed_top_level_tables) calc_allowed_top_level_tables(select_lex); - if (optimize_constant_subqueries()) + if (select_lex->optimize_constant_subqueries()) DBUG_RETURN(1); if (conds && conds->with_subquery()) diff --git a/sql/sql_select.h b/sql/sql_select.h index 212f40b7d43..1c607883be9 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1689,7 +1689,6 @@ public: bool alloc_func_list(); bool flatten_subqueries(); bool optimize_unflattened_subqueries(); - bool optimize_constant_subqueries(); bool make_range_rowid_filters(); bool init_range_rowid_filters(); bool make_sum_func_list(List &all_fields, List &send_fields, diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d176eca4165..11a27fc1908 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -541,7 +541,17 @@ int mysql_update(THD *thd, if (!(thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)) switch_to_nullable_trigger_fields(values, table); - /* Apply the IN=>EXISTS transformation to all subqueries and optimize them */ + /* + Apply the IN=>EXISTS and other transformations to all subqueries and + optimize them. + + Constant subqueries are treated in a special way here: they can be + evaluated even in EXPLAIN statement, so their query plan must be + fully initialized for computation. + */ + if (select_lex->optimize_constant_subqueries()) + DBUG_RETURN(TRUE); + if (select_lex->optimize_unflattened_subqueries(false)) DBUG_RETURN(TRUE); From 8906e6a214ab7d151e44c994cd9149fe3d45d114 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 26 Jan 2026 01:18:40 +0300 Subject: [PATCH 140/152] MDEV-32317 ref_ptrs exhaust on multiple ORDER by func from winfunc Each ORDER and WHERE slot may generate split, see code like this: if ((item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM) || item->with_window_func()) item->split_sum_func(thd, ref_ptrs, all_fields, SPLIT_SUM_SELECT); Such kind of code is done in JOIN::prepare(), setup_order(), setup_fields(), setup_group() and split_sum_func2() itself. Since we are at the phase of ref_ptrs allocation, items are not fixed yet and we cannot calculate precisely how much ref_ptrs is needed. We can estimate at most how much is needed. In the worst case each window function generates split on each ORDER BY field, GROUP BY field and WHERE field, so the counts of these should be multiplied by window funcs count. As the split can be done in both setup_without_group() and JOIN::prepare() simultaneously, the factor of window funcs should be multiplied by 2. The similar case may be with inner sumfunc items as of the condition item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM but factor of these is harder to predict at the stage of unfixed items. --- mysql-test/main/win_orderby.result | 108 +++++++++++++++++++++++++++++ mysql-test/main/win_orderby.test | 67 ++++++++++++++++++ sql/sql_lex.cc | 6 +- 3 files changed, 179 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/win_orderby.result b/mysql-test/main/win_orderby.result index f38bdd77992..916907db6b9 100644 --- a/mysql-test/main/win_orderby.result +++ b/mysql-test/main/win_orderby.result @@ -75,3 +75,111 @@ DROP TABLE t1; # # End of 10.3 tests # +# +# MDEV-32317 ref_ptrs exhaust on multiple ORDER by func from winfunc +# +select row_number() over () x; +x +1 +select row_number() over (order by 1) x; +x +1 +select row_number() over (order by 1, 1) x; +x +1 +select row_number() over (partition by 1) x; +x +1 +select row_number() over (partition by 1, 1) x; +x +1 +select row_number() over (partition by 1 order by 1) x; +x +1 +select row_number() over (partition by 1, 2) x; +x +1 +select row_number() over (partition by 1, 2 order by 1, 1) x; +x +1 +select row_number() over () x order by x; +x +1 +select row_number() over () order by 1; +row_number() over () +1 +select row_number() over (order by 1) order by 1; +row_number() over (order by 1) +1 +select row_number() over (order by 1, 1) order by 1; +row_number() over (order by 1, 1) +1 +select row_number() over (order by 1) order by 1, 1; +row_number() over (order by 1) +1 +select row_number() over (order by 1, 1) order by 1, 1; +row_number() over (order by 1, 1) +1 +select row_number() over (partition by 1, 2 order by 1, 1) order by 1; +row_number() over (partition by 1, 2 order by 1, 1) +1 +select row_number() over (partition by 1, 2 order by 1, 1) order by 1, 1; +row_number() over (partition by 1, 2 order by 1, 1) +1 +select nullif(1, 0) order by 1; +nullif(1, 0) +1 +select nullif(1, 0) order by 1, 1; +nullif(1, 0) +1 +select nullif(avg(1) over (), 0) order by 1; +nullif(avg(1) over (), 0) +1.0000 +select nullif(avg(1) over (order by 1), 0) order by 1; +nullif(avg(1) over (order by 1), 0) +1.0000 +select nullif(avg(1) over (order by 1, 1), 0) order by 1; +nullif(avg(1) over (order by 1, 1), 0) +1.0000 +select nullif(avg(1) over (partition by 1), 0) order by 1; +nullif(avg(1) over (partition by 1), 0) +1.0000 +select nullif(avg(1) over (partition by 1, 2), 0) order by 1; +nullif(avg(1) over (partition by 1, 2), 0) +1.0000 +select nullif(avg(1) over (), 0) order by 1, 1; +nullif(avg(1) over (), 0) +1.0000 +select nullif(avg(1) over (partition by 1, 2), 0) order by 1, 1; +nullif(avg(1) over (partition by 1, 2), 0) +1.0000 +select nullif(avg(1) over (partition by 1, 2), 0) order by 1, 1, 1; +nullif(avg(1) over (partition by 1, 2), 0) +1.0000 +select nullif(avg(1) over (partition by 1, 2), avg(1) over ()) order by 1, 1, 1; +nullif(avg(1) over (partition by 1, 2), avg(1) over ()) +NULL +select avg ( 'x' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; +x +0 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1365 Division by 0 +select row_number() over () x order by x between 1 and (( x = x ) / x) or x = x = 1 ; +x +1 +select nullif(avg(1) over (order by 1), 0) order by 1, 1, 1; +nullif(avg(1) over (order by 1), 0) +1.0000 +select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) +1.0000 +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) +1.0000 +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1, x between 1 and (( x = x ) / x) or x = x = 1 ; +x +1.0000 +# +# End of 10.11 tests +# diff --git a/mysql-test/main/win_orderby.test b/mysql-test/main/win_orderby.test index d0bcddfece1..f8a31555a32 100644 --- a/mysql-test/main/win_orderby.test +++ b/mysql-test/main/win_orderby.test @@ -85,3 +85,70 @@ DROP TABLE t1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-32317 ref_ptrs exhaust on multiple ORDER by func from winfunc +--echo # +# Primitive tests, just know how reserve/occupation works +# 2 elements +select row_number() over () x; +select row_number() over (order by 1) x; +select row_number() over (order by 1, 1) x; +select row_number() over (partition by 1) x; +select row_number() over (partition by 1, 1) x; +select row_number() over (partition by 1 order by 1) x; +# 3 elements +select row_number() over (partition by 1, 2) x; +select row_number() over (partition by 1, 2 order by 1, 1) x; +# 1 element +select row_number() over () x order by x; +select row_number() over () order by 1; +# 2 elements +select row_number() over (order by 1) order by 1; +select row_number() over (order by 1, 1) order by 1; +select row_number() over (order by 1) order by 1, 1; +select row_number() over (order by 1, 1) order by 1, 1; +# 3 elements +select row_number() over (partition by 1, 2 order by 1, 1) order by 1; +select row_number() over (partition by 1, 2 order by 1, 1) order by 1, 1; +# 1 element +select nullif(1, 0) order by 1; +select nullif(1, 0) order by 1, 1; + +# Now interesting, winfunc inside func +# 7 elements (reserves 11) +select nullif(avg(1) over (), 0) order by 1; +# 8 elements (reserves 12) +select nullif(avg(1) over (order by 1), 0) order by 1; +# 8 elements (reserves 13) +select nullif(avg(1) over (order by 1, 1), 0) order by 1; +# 8 elements (reserves 12) +select nullif(avg(1) over (partition by 1), 0) order by 1; +# 9 elements (reserves 13) +select nullif(avg(1) over (partition by 1, 2), 0) order by 1; +# 11 elements (reserves 15) +select nullif(avg(1) over (), 0) order by 1, 1; +# 13 elements (reserves 17) +select nullif(avg(1) over (partition by 1, 2), 0) order by 1, 1; +# 17 elements (reserves 21) +select nullif(avg(1) over (partition by 1, 2), 0) order by 1, 1, 1; +# 24 elements (reserves 36) +select nullif(avg(1) over (partition by 1, 2), avg(1) over ()) order by 1, 1, 1; + +# Extinguishing tests, let's break the code +# 17 elements (reserves 25) +select avg ( 'x' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; +# 14 elements (reserves 20) +select row_number() over () x order by x between 1 and (( x = x ) / x) or x = x = 1 ; +# 16 elements (reserves 20) +select nullif(avg(1) over (order by 1), 0) order by 1, 1, 1; +# 41 elements (reserves 72) +select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +# 50 elements (reserves 92) +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +# 63 elements (reserves 124) +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1, x between 1 and (( x = x ) / x) or x = x = 1 ; + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3e6687d80a5..48351863d75 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3646,6 +3646,8 @@ uint st_select_lex::get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg) if (!order_group_num) order_group_num= order_group_num_arg; + const uint winfunc_factor= window_funcs.elements ? 2 * window_funcs.elements : 1; + /* find_order_in_list() may need some extra space, so multiply order_group_num by 2 @@ -3655,8 +3657,8 @@ uint st_select_lex::get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg) item_list.elements + select_n_reserved + select_n_having_items + - select_n_where_fields + - order_group_num * 2 + + select_n_where_fields * winfunc_factor + + order_group_num * 2 * winfunc_factor + hidden_bit_fields + fields_in_window_functions; return n; From eba938f9eb615ba1d2c1277e7cbebe0079582083 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 17 Dec 2025 17:39:28 +0300 Subject: [PATCH 141/152] MDEV-37275 Cannot remove default value of NOT NULL column Run-time has semantics duplication in unireg_check, default_value and flags, so all three must be in sync before FRM creation. Special unireg_check values for temporal field types was introduced by 32b28f92980 WL#1266 "Separate auto-set logic from TIMESTAMP type." --- mysql-test/main/alter_table.result | 28 ++++++++++++++++++++++++++++ mysql-test/main/alter_table.test | 22 ++++++++++++++++++++++ sql/sql_table.cc | 3 +++ 3 files changed, 53 insertions(+) diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 0dda2d8b5b4..37485af2508 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3184,3 +3184,31 @@ DROP TABLE t; # # End of 10.7 tests # +# +# MDEV-37275 Cannot remove default value of NOT NULL column +# +create table t1 (d time default '00:00:00'); +alter table t1 alter column d drop default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` time DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +create table t2 (d datetime not null default current_timestamp()); +alter table t2 alter column d drop default; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `d` datetime NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +create table t3 (d datetime not null); +alter table t3 alter column d set default current_timestamp(); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `d` datetime NOT NULL DEFAULT current_timestamp() +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop tables t1, t2, t3; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index 5165d034da8..776e5a04879 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2462,3 +2462,25 @@ DROP TABLE t; --echo # --echo # End of 10.7 tests --echo # + +--echo # +--echo # MDEV-37275 Cannot remove default value of NOT NULL column +--echo # +create table t1 (d time default '00:00:00'); +alter table t1 alter column d drop default; +show create table t1; + +create table t2 (d datetime not null default current_timestamp()); +alter table t2 alter column d drop default; +show create table t2; + +create table t3 (d datetime not null); +alter table t3 alter column d set default current_timestamp(); +show create table t3; + +drop tables t1, t2, t3; + +--echo # +--echo # End of 10.11 tests +--echo # + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b9e24cb6a36..659199058d4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8711,6 +8711,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } else { + if (def->default_value != alter->default_value && + def->has_default_now_unireg_check()) + def->unireg_check= Field::NONE; if ((def->default_value= alter->default_value) || !(def->flags & NOT_NULL_FLAG)) def->flags&= ~NO_DEFAULT_VALUE_FLAG; From 6f2a99589b28ae53fa5562864fe38f372f4b1c67 Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Fri, 26 Sep 2025 11:45:54 +0530 Subject: [PATCH 142/152] MDEV-35815: use-after-poison_in_get_hash_symbol In find_field_in_view(), we call field_it.create_item() which creates item on a statement mem_root. Then we set its name. Make sure the name is allocated on a statement mem_root, too. --- mysql-test/main/having.result | 19 +++++++++++++++++++ mysql-test/main/having.test | 22 ++++++++++++++++++++++ sql/sql_base.cc | 6 ++++++ 3 files changed, 47 insertions(+) diff --git a/mysql-test/main/having.result b/mysql-test/main/having.result index f1f3190a08e..7783b525b82 100644 --- a/mysql-test/main/having.result +++ b/mysql-test/main/having.result @@ -1001,3 +1001,22 @@ DROP TABLE t1,t2; # # End of 10.5 tests # +# +# MDEV-35815: Crash in ASAN build due to accessing use-after-poison memory error +# +SET @save_optimizer_trace=@@optimizer_trace; +SET optimizer_trace= 'enabled=on'; +CREATE TABLE t1 (col1 varchar(10)); +INSERT INTO t1 VALUES ('a'), ('b'); +CREATE VIEW v1 AS SELECT concat(col1,'boo') AS view_col FROM t1; +PREPARE stmt FROM 'SELECT view_col AS fld FROM v1 GROUP BY fld HAVING 0 AND fld != 1'; +EXECUTE stmt; +fld +EXECUTE stmt; +fld +DROP TABLE t1; +DROP VIEW v1; +SET optimizer_trace= @save_optimizer_trace; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/having.test b/mysql-test/main/having.test index f33b3a7855e..a168f8dbf23 100644 --- a/mysql-test/main/having.test +++ b/mysql-test/main/having.test @@ -1056,3 +1056,25 @@ DROP TABLE t1,t2; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # MDEV-35815: Crash in ASAN build due to accessing use-after-poison memory error +--echo # +SET @save_optimizer_trace=@@optimizer_trace; +SET optimizer_trace= 'enabled=on'; + +CREATE TABLE t1 (col1 varchar(10)); +INSERT INTO t1 VALUES ('a'), ('b'); +CREATE VIEW v1 AS SELECT concat(col1,'boo') AS view_col FROM t1; + +PREPARE stmt FROM 'SELECT view_col AS fld FROM v1 GROUP BY fld HAVING 0 AND fld != 1'; + +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1; +DROP VIEW v1; +SET optimizer_trace= @save_optimizer_trace; +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2014bbae7bc..f54239bffe7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6334,7 +6334,13 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, the replacing item. */ if (*ref && (*ref)->is_explicit_name()) + { + if (arena) // We've activated and deactivated stmt arena above + arena= thd->activate_stmt_arena_if_needed(&backup); item->set_name(thd, (*ref)->name); + if (arena) + thd->restore_active_arena(arena, &backup); + } if (register_tree_change) thd->change_item_tree(ref, item); else From 05e6c9d42d2f49ada1a0c49a4e0d7fc3ce420e4e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 27 Jan 2026 22:41:09 +0100 Subject: [PATCH 143/152] MDEV-32317 fix the test for --view --- mysql-test/main/win_orderby.result | 21 +++++++-------------- mysql-test/main/win_orderby.test | 12 ++++-------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/mysql-test/main/win_orderby.result b/mysql-test/main/win_orderby.result index 916907db6b9..35fb3475d8a 100644 --- a/mysql-test/main/win_orderby.result +++ b/mysql-test/main/win_orderby.result @@ -72,10 +72,8 @@ exp 1 1 DROP TABLE t1; -# # End of 10.3 tests # -# # MDEV-32317 ref_ptrs exhaust on multiple ORDER by func from winfunc # select row_number() over () x; @@ -159,27 +157,22 @@ nullif(avg(1) over (partition by 1, 2), 0) select nullif(avg(1) over (partition by 1, 2), avg(1) over ()) order by 1, 1, 1; nullif(avg(1) over (partition by 1, 2), avg(1) over ()) NULL -select avg ( 'x' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; +select avg ( '1' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; x -0 -Warnings: -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1365 Division by 0 +1 select row_number() over () x order by x between 1 and (( x = x ) / x) or x = x = 1 ; x 1 select nullif(avg(1) over (order by 1), 0) order by 1, 1, 1; nullif(avg(1) over (order by 1), 0) 1.0000 -select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; -nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) +select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1; +x 1.0000 -select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; -nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1; +x 1.0000 select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1, x between 1 and (( x = x ) / x) or x = x = 1 ; x 1.0000 -# -# End of 10.11 tests -# +# End of 10.6 tests diff --git a/mysql-test/main/win_orderby.test b/mysql-test/main/win_orderby.test index f8a31555a32..08e349d2b59 100644 --- a/mysql-test/main/win_orderby.test +++ b/mysql-test/main/win_orderby.test @@ -82,9 +82,7 @@ FROM t1; DROP TABLE t1; ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-32317 ref_ptrs exhaust on multiple ORDER by func from winfunc @@ -137,18 +135,16 @@ select nullif(avg(1) over (partition by 1, 2), avg(1) over ()) order by 1, 1, 1; # Extinguishing tests, let's break the code # 17 elements (reserves 25) -select avg ( 'x' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; +select avg ( '1' ) over ( ) x where ( 1 , 1 , ( 1 , null ) ) in ( ( 1 , 1 , ( 1 , 1 ) ) ) order by x between 25 and ( ( x = x ) / x ) or x = x = avg ( null ) or x = 94 ; # 14 elements (reserves 20) select row_number() over () x order by x between 1 and (( x = x ) / x) or x = x = 1 ; # 16 elements (reserves 20) select nullif(avg(1) over (order by 1), 0) order by 1, 1, 1; # 41 elements (reserves 72) -select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +select nullif(avg(1) over (order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1; # 50 elements (reserves 92) -select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) order by 1, 1, 1, 1, 1, 1; +select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1; # 63 elements (reserves 124) select nullif(avg(1) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1), avg(2) over (partition by -1,1,0,2,3,4,5,6,7,8 order by 1, 1, 1, 1, 1, 1, 1)) x order by 1, 1, 1, 1, 1, 1, x between 1 and (( x = x ) / x) or x = x = 1 ; ---echo # ---echo # End of 10.11 tests ---echo # +--echo # End of 10.6 tests From 8070033e475d34b0ba311c5e522b438849a10bd6 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 23 Jan 2026 15:31:46 +1100 Subject: [PATCH 144/152] MDEV-36230 Fix SERVER port field bound check The Port field in the system table mysql.servers has type INT, which translates to Field_long. During parsing it is parsed as ulong_num, and in this patch we add bound checks there. --- mysql-test/main/servers.result | 22 ++++++++++++++++++++++ mysql-test/main/servers.test | 20 ++++++++++++++++++++ sql/sql_yacc.yy | 16 ++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/mysql-test/main/servers.result b/mysql-test/main/servers.result index db706fc6534..dcd15f92c51 100644 --- a/mysql-test/main/servers.result +++ b/mysql-test/main/servers.result @@ -104,4 +104,26 @@ uninstall soname "ha_example"; ERROR HY000: Cannot load from mysql.plugin. The table is probably corrupted drop table mysql.plugin; rename table mysql.plugin_save to mysql.plugin; +# +# MDEV-36230 SIGSEGV in store_server_fields on CREATE SERVER +# +## Error code depends on length of long +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 4294967295); +ERROR 22003: port value is out of range in 'INT' +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483647); +select * from mysql.servers; +Server_name Host Db Username Password Port Socket Wrapper Owner +s 2147483647 mysql +ALTER SERVER s OPTIONS (PORT 4294967295); +ERROR 22003: port value is out of range in 'INT' +select * from mysql.servers; +Server_name Host Db Username Password Port Socket Wrapper Owner +s 2147483647 mysql +drop server s; +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483648); +ERROR 22003: port value is out of range in 'INT' +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 18446744073709551615); +ERROR 22003: port value is out of range in 'INT' +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT -5); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-5)' at line 1 # End of 10.11 tests diff --git a/mysql-test/main/servers.test b/mysql-test/main/servers.test index 95f6c4f624e..81fee613894 100644 --- a/mysql-test/main/servers.test +++ b/mysql-test/main/servers.test @@ -112,4 +112,24 @@ uninstall soname "ha_example"; drop table mysql.plugin; rename table mysql.plugin_save to mysql.plugin; + +--echo # +--echo # MDEV-36230 SIGSEGV in store_server_fields on CREATE SERVER +--echo # +--echo ## Error code depends on length of long +--error ER_DATA_OUT_OF_RANGE +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 4294967295); +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483647); +select * from mysql.servers; +--error ER_DATA_OUT_OF_RANGE +ALTER SERVER s OPTIONS (PORT 4294967295); +select * from mysql.servers; +drop server s; +--error ER_DATA_OUT_OF_RANGE +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483648); +--error ER_DATA_OUT_OF_RANGE +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 18446744073709551615); +--error ER_PARSE_ERROR +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT -5); + --echo # End of 10.11 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b8c43643661..2ec1c170ed1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2873,6 +2873,22 @@ server_option: } | PORT_SYM ulong_num { + /* + We especially don't want this to happen: + + The value of $2 is ULONG_MAX, causing + server_options.port to be -1, which means "default + port". + + Because we are doing a check here, we may as well check + against the SQL data type in one go rather than just the + C++ type here and SQL type later in sql_servers.cc. + */ + if ($2 > INT32_MAX) + { + my_error(ER_DATA_OUT_OF_RANGE, myf(0), "port", "INT"); + MYSQL_YYABORT; + } Lex->server_options.port= $2; } ; From 7614f8fb5d0f6f808ac261edf689c1eceede5cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 28 Jan 2026 13:24:09 +0200 Subject: [PATCH 145/152] MDEV-38589: SELECT unnecessarily waits for log write The design of "binlog group commit" involves carrying some state across transaction boundaries. This includes trx_t::commit_lsn, which keeps track of how much write-ahead log needs to be written. Unfortunately, this field was not reset in a commit where a log write was elided. That would cause an unnecessary wait in a subsequent read-only transaction that happened to reuse the same transaction object. trx_deregister_from_2pc(): Reset trx->commit_lsn so that an earlier write that was executed in the same client connection will not result in an unnecessary wait during a subsequent read operation. trx_commit_complete_for_mysql(): Unless we are inside a binlog group commit, reset trx->commit_lsn. unlock_and_close_files(): Reset trx->commit_lsn after durably writing the log, and remove a redundant log write call from some callers. trx_t::rollback_finish(): Clear commit_lsn, because a rolled-back transaction will not need to be durably written. trx_t::clear_and_free(): Wrapper function to suppress a debug check in trx_t::free(). Also, remove some redundant ut_ad(!trx->will_lock) that will be checked in trx_t::free(). Reviewed by: Vladislav Vaintroub --- storage/innobase/dict/dict0crea.cc | 4 ++-- storage/innobase/dict/dict0defrag_bg.cc | 4 ++-- storage/innobase/dict/dict0stats.cc | 2 +- storage/innobase/fts/fts0fts.cc | 12 ++++++------ storage/innobase/fts/fts0opt.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 16 ++++++++-------- storage/innobase/handler/handler0alter.cc | 8 ++++++-- storage/innobase/include/trx0trx.h | 4 +++- storage/innobase/trx/trx0roll.cc | 2 ++ storage/innobase/trx/trx0trx.cc | 10 ++++++++-- 10 files changed, 39 insertions(+), 25 deletions(-) diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index a16c3440c58..a7f9f893f47 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1424,7 +1424,7 @@ err_exit: ut_strerr(error)); trx->rollback(); row_mysql_unlock_data_dictionary(trx); - trx->free(); + trx->clear_and_free(); srv_file_per_table= srv_file_per_table_backup; return error; } @@ -1463,7 +1463,7 @@ err_exit: trx->commit(); row_mysql_unlock_data_dictionary(trx); - trx->free(); + trx->clear_and_free(); srv_file_per_table= srv_file_per_table_backup; lock(SRW_LOCK_CALL); diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 9820bb20f8b..ef6a85905cc 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -242,7 +242,7 @@ dberr_t dict_stats_save_defrag_summary(dict_index_t *index, THD *thd) trx->rollback(); row_mysql_unlock_data_dictionary(trx); - trx->free(); + trx->clear_and_free(); stats.close(); return ret; @@ -359,7 +359,7 @@ dict_stats_save_defrag_stats( trx->rollback(); row_mysql_unlock_data_dictionary(trx); - trx->free(); + trx->clear_and_free(); stats.close(); return ret; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 84e06219ed6..baef36997b7 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -2987,7 +2987,7 @@ free_and_exit: trx->dict_operation_lock_mode = false; dict_sys.unlock(); unlocked_free_and_exit: - trx->free(); + trx->clear_and_free(); stats.close(); return ret; } diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index e6960901888..659c92c85c9 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2701,7 +2701,7 @@ func_exit: } } - trx->free(); + trx->clear_and_free(); return(error); } @@ -2777,7 +2777,7 @@ fts_update_sync_doc_id( fts_sql_rollback(trx); } - trx->free(); + trx->clear_and_free(); } return(error); @@ -2997,7 +2997,7 @@ fts_commit_table( fts_sql_commit(trx); - trx->free(); + trx->clear_and_free(); return(error); } @@ -4211,7 +4211,7 @@ fts_sync_commit( /* Avoid assertion in trx_t::free(). */ trx->dict_operation_lock_mode = false; - trx->free(); + trx->clear_and_free(); return(error); } @@ -4261,7 +4261,7 @@ fts_sync_rollback( /* Avoid assertion in trx_t::free(). */ trx->dict_operation_lock_mode = false; - trx->free(); + trx->clear_and_free(); } /** Run SYNC on the table, i.e., write out data from the cache to the @@ -5937,7 +5937,7 @@ cleanup: fts_sql_rollback(trx); } - trx->free(); + trx->clear_and_free(); } if (!cache->stopword_info.cached_stopword) { diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 38b45a94142..cac29121940 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -1736,7 +1736,7 @@ fts_optimize_free( mem_heap_t* heap = static_cast(optim->self_heap->arg); trx_commit_for_mysql(optim->trx); - optim->trx->free(); + optim->trx->clear_and_free(); optim->trx = NULL; fts_doc_ids_free(optim->to_delete); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e93d3d3f58d..af0b588f5ab 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1460,7 +1460,7 @@ static void innodb_drop_database(handlerton*, char *path) trx->commit(); row_mysql_unlock_data_dictionary(trx); - trx->free(); + trx->clear_and_free(); if (!stats_failed) stats.close(); @@ -2002,7 +2002,7 @@ fail: all_fail: mtr.commit(); - trx->free(); + trx->clear_and_free(); ut_free(pcur.old_rec_buf); ut_d(purge_sys.resume_FTS()); } @@ -2793,6 +2793,7 @@ trx_deregister_from_2pc( { trx->is_registered= false; trx->active_commit_ordered= false; + trx->commit_lsn= 0; } /** @@ -2922,7 +2923,6 @@ static int innobase_rollback_by_xid(handlerton*, XID *xid) noexcept trx_deregister_from_2pc(trx); THD* thd= trx->mysql_thd; dberr_t err= trx_rollback_for_mysql(trx); - ut_ad(!trx->will_lock); trx->free(); return convert_error_code_to_mysql(err, 0, thd); } @@ -13304,7 +13304,7 @@ ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, log_write_up_to(trx->commit_lsn, true); info.table()->release(); } - trx->free(); + trx->clear_and_free(); } } else if (!error && m_prebuilt) @@ -13742,6 +13742,7 @@ err_exit: for (pfs_os_file_t d : deleted) os_file_close(d); log_write_up_to(trx->commit_lsn, true); + trx->commit_lsn= 0; if (trx != parent_trx) trx->free(); if (!fts) @@ -13906,7 +13907,7 @@ int ha_innobase::truncate() m_prebuilt->stored_select_lock_type= stored_lock; } - trx->free(); + trx->clear_and_free(); #ifdef BTR_CUR_HASH_ADAPT if (UT_LIST_GET_LEN(ib_table->freed_indexes)) @@ -14066,7 +14067,7 @@ int ha_innobase::truncate() } } - trx->free(); + trx->clear_and_free(); if (!stats_failed) stats.close(); mem_heap_free(heap); @@ -14266,7 +14267,7 @@ ha_innobase::rename_table( log_write_up_to(trx->commit_lsn, true); } trx->flush_log_later = false; - trx->free(); + trx->clear_and_free(); if (!stats_fail) { stats.close(); } @@ -17268,7 +17269,6 @@ innobase_commit_by_xid( innobase_commit_low(trx); ut_ad(trx->mysql_thd == NULL); trx_deregister_from_2pc(trx); - ut_ad(!trx->will_lock); /* trx cache requirement */ trx->free(); return(XA_OK); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 7c663d1d09a..bd26c786342 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4388,8 +4388,11 @@ static void unlock_and_close_files(const std::vector &deleted, row_mysql_unlock_data_dictionary(trx); for (pfs_os_file_t d : deleted) os_file_close(d); - if (trx->commit_lsn) - log_write_up_to(trx->commit_lsn, true); + if (lsn_t lsn= trx->commit_lsn) + { + trx->commit_lsn= 0; + log_write_up_to(lsn, true); + } } /** Commit a DDL transaction and unlink any deleted files. */ @@ -9335,6 +9338,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, { free_and_exit: DBUG_ASSERT(ctx->prebuilt == prebuilt); + ut_d(ctx->trx->commit_lsn= 0); ctx->trx->free(); ctx->trx= nullptr; diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 348e55ca19b..0a4f64203a9 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1097,8 +1097,10 @@ public: bool has_stats_table_lock() const; /** Free the memory to trx_pools */ - void free(); + void free() noexcept; + /** Clear commit_lsn and free the memory */ + void clear_and_free() noexcept { ut_d(commit_lsn= 0;) free(); } void assert_freed() const { diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 87d8e0c187f..f54a82d859a 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -61,6 +61,7 @@ bool trx_t::rollback_finish() noexcept if (UNIV_LIKELY(error_state == DB_SUCCESS)) { commit(); + commit_lsn= 0; return true; } @@ -82,6 +83,7 @@ bool trx_t::rollback_finish() noexcept undo= nullptr; } commit_low(); + commit_lsn= 0; return commit_cleanup(); } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 6c8fcda7350..1ff3b9ac36d 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -357,7 +357,7 @@ trx_t *trx_create() } /** Free the memory to trx_pools */ -void trx_t::free() +void trx_t::free() noexcept { autoinc_locks.fake_defined(); #ifdef HAVE_MEM_CHECK @@ -378,8 +378,10 @@ void trx_t::free() ut_ad(magic_n == TRX_MAGIC_N); ut_ad(!read_only); ut_ad(!lock.wait_lock); + ut_ad(!commit_lsn); dict_operation= false; + commit_lsn= 0; trx_sys.deregister_trx(this); check_unique_secondary= true; check_foreigns= true; @@ -1255,6 +1257,8 @@ static void trx_flush_log_if_needed(lsn_t lsn, trx_t *trx) if (log_sys.get_flushed_lsn(std::memory_order_relaxed) >= lsn) return; + ut_ad(!trx->mysql_thd || !trx->mysql_thd->tx_read_only); + const bool flush= (srv_file_flush_method != SRV_NOSYNC && (srv_flush_log_at_trx_commit & 1)); @@ -1745,12 +1749,14 @@ void trx_commit_complete_for_mysql(trx_t *trx) return; switch (srv_flush_log_at_trx_commit) { case 0: - return; + goto func_exit; case 1: if (trx->active_commit_ordered) return; } trx_flush_log_if_needed(lsn, trx); + func_exit: + trx->commit_lsn= 0; } /**********************************************************************//** From e2088ce4d96a6dda8100f1d51bbbf554aa9fa9dc Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Wed, 24 Dec 2025 21:12:28 +0100 Subject: [PATCH 146/152] MDEV-38383 Fix MDEV-38073 MTR test warning MDEV-38073 MTR test started to fail with a warning after upstream merge from 11.4 a7528a6190807281d3224e4e67a9b76083a202a6 because THD responsible for creating SST user became read-only when the server was started with --transaction-read-only=TRUE. make sure the readonly flag on THDs created for wsp::thd utility class is cleared regardless of the --transaction-read-only value as it is intended only for client-facing THDs. --- mysql-test/suite/galera/r/MDEV-38073.result | 2 ++ mysql-test/suite/galera/t/MDEV-38073.test | 7 +++++++ sql/wsrep_utils.cc | 2 ++ 3 files changed, 11 insertions(+) diff --git a/mysql-test/suite/galera/r/MDEV-38073.result b/mysql-test/suite/galera/r/MDEV-38073.result index 3ab032a0dfe..c5790704940 100644 --- a/mysql-test/suite/galera/r/MDEV-38073.result +++ b/mysql-test/suite/galera/r/MDEV-38073.result @@ -1,5 +1,7 @@ connection node_2; connection node_1; +connection node_1; +connection node_2; connection node_2; connection node_1; CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; diff --git a/mysql-test/suite/galera/t/MDEV-38073.test b/mysql-test/suite/galera/t/MDEV-38073.test index b2f69219e25..8e48937a1c0 100644 --- a/mysql-test/suite/galera/t/MDEV-38073.test +++ b/mysql-test/suite/galera/t/MDEV-38073.test @@ -7,6 +7,11 @@ --source include/have_innodb.inc --source include/big_test.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + # Restart the node 2 in transaction_read_only mode. --connection node_2 --source include/shutdown_mysqld.inc @@ -37,3 +42,5 @@ SELECT COUNT(*) = 2 FROM t1; # Cleanup --connection node_1 DROP TABLE t1; + +--source include/auto_increment_offset_restore.inc diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index 20114eb38f4..4d18666092c 100644 --- a/sql/wsrep_utils.cc +++ b/sql/wsrep_utils.cc @@ -508,6 +508,8 @@ thd::thd (my_bool ini, bool system_thread) wsrep_assign_from_threadvars(ptr); wsrep_store_threadvars(ptr); + ptr->tx_read_only= false; + ptr->variables.tx_read_only= false; ptr->variables.tx_isolation= ISO_READ_COMMITTED; ptr->variables.sql_log_bin = 0; ptr->variables.option_bits &= ~OPTION_BIN_LOG; // disable binlog From a9e353e84f15c8386e756ef1a49ccde227d2d48b Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 6 Dec 2025 16:29:26 +0200 Subject: [PATCH 147/152] MDEV-38246 aria_read index failed on encrypted database during backup The backup of encrypted Aria tables was not supported. Added support for this. One complication is that the page checksum is for the not encrypted page. To be able to verify the checksum I have to temporarly decrypt the page. In the backup we store the encrypted pages. Other things: - Fixed some (not critical) memory leaks in mariabackup --- extra/mariabackup/aria_backup_client.cc | 21 ++- extra/mariabackup/backup_mysql.cc | 3 + extra/mariabackup/encryption_plugin.cc | 46 +++++ extra/mariabackup/xtrabackup.cc | 1 + include/aria_backup.h | 10 +- .../suite/mariabackup/aria_encrypted.opt | 7 + .../suite/mariabackup/aria_encrypted.result | 8 + .../suite/mariabackup/aria_encrypted.test | 18 ++ storage/maria/ma_backup.c | 160 +++++++++++++++--- storage/maria/ma_crypt.c | 24 ++- storage/maria/ma_crypt.h | 9 +- storage/maria/ma_open.c | 48 +++++- storage/maria/maria_def.h | 1 + storage/maria/s3_func.c | 2 +- storage/maria/test_ma_backup.c | 2 +- 15 files changed, 313 insertions(+), 47 deletions(-) create mode 100644 mysql-test/suite/mariabackup/aria_encrypted.opt create mode 100644 mysql-test/suite/mariabackup/aria_encrypted.result create mode 100644 mysql-test/suite/mariabackup/aria_encrypted.test diff --git a/extra/mariabackup/aria_backup_client.cc b/extra/mariabackup/aria_backup_client.cc index 32aeee6ba4c..1b42a9c58ec 100644 --- a/extra/mariabackup/aria_backup_client.cc +++ b/extra/mariabackup/aria_backup_client.cc @@ -161,7 +161,10 @@ public: File m_data_file = -1; MY_STAT m_data_file_stat; }; - Table() = default; + Table() + { + bzero(&m_cap, sizeof(m_cap)); + } Table (Table &&other) = delete; Table & operator= (Table &&other) = delete; Table(const Table &) = delete; @@ -222,6 +225,7 @@ private: }; Table::~Table() { + aria_free_capabilities(&m_cap); (void)close(); } @@ -298,7 +302,8 @@ bool Table::open(MYSQL *con, bool opt_no_lock, unsigned thread_num) { goto exit; } if (!have_capabilities) { - if ((error= aria_get_capabilities(partition.m_index_file, &m_cap))) { + if ((error= aria_get_capabilities(partition.m_index_file, + m_full_name.c_str(), &m_cap))) { msg(thread_num, "aria_get_capabilities failed: %d", error); goto exit; } @@ -343,6 +348,7 @@ exit: } bool Table::close() { + aria_free_capabilities(&m_cap); for (Partition &partition : m_partitions) { if (partition.m_index_file >= 0) { my_close(partition.m_index_file, MYF(MY_WME)); @@ -409,14 +415,17 @@ bool Table::copy(ds_ctxt_t *ds, bool is_index, unsigned thread_num) { { if (error == HA_ERR_END_OF_FILE) break; - msg(thread_num, "error: aria_read %s failed: %d", - is_index ? "index" : "data", error); + msg(thread_num, "error: aria_read %s from %s failed " + "with error %d", + is_index ? "index" : "data", full_name.c_str(), + error); goto err; } xtrabackup_io_throttling(); if ((error = ds_write(dst_file, copy_buffer, length))) { - msg(thread_num, "error: aria_write failed: %d", error); - goto err; + msg(thread_num, "error: aria_write to %s failed " + "with error: %d", dst_path, error); + goto err; } } diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 6537d05db34..a85a6c79b97 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -546,6 +546,7 @@ bool get_mysql_vars(MYSQL *connection) xb_load_list_string(ignore_db_dirs, ",", register_ignore_db_dirs_filter); out: + free_mysql_variables(mysql_vars); return (ret); } @@ -1513,7 +1514,9 @@ write_galera_info(ds_ctxt *datasink, MYSQL *connection) domain_id ? domain_id : domain_id55); cleanup: + free_mysql_variables(vars); free_mysql_variables(status); + free_mysql_variables(value); return(result); } diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc index e7e8d95823c..9d98a4a631f 100644 --- a/extra/mariabackup/encryption_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -29,6 +29,7 @@ extern struct st_maria_plugin *mysql_optional_plugins[]; extern struct st_maria_plugin *mysql_mandatory_plugins[]; static void encryption_plugin_init(int argc, char **argv); +void initialize_default_encryption(); extern char *xb_plugin_load; extern char *xb_plugin_dir; @@ -140,7 +141,10 @@ void encryption_plugin_backup_init(MYSQL *mysql) } mysql_free_result(result); if (!plugin_load.length()) + { + initialize_default_encryption(); return; + } oss << "plugin_load=" << plugin_load.c_str() + 1 << std::endl; @@ -248,3 +252,45 @@ static void encryption_plugin_init(int argc, char **argv) plugin_init(&argc, argv, PLUGIN_INIT_SKIP_PLUGIN_TABLE); } + +/* + Setup encryption_handler with default encryption to avoid crashes when + calling encryption_get_key +*/ +uint no_get_key(uint, uint, uchar*, uint*) +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} +uint no_key(uint) +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} + +static int ctx_init(void *ctx, const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, int flags, + unsigned int key_id, unsigned int key_version) +{ + return my_aes_crypt_init(ctx, MY_AES_CBC, flags, key, klen, iv, ivlen); +} + +static unsigned int get_length(unsigned int slen, unsigned int key_id, + unsigned int key_version) +{ + return my_aes_get_size(MY_AES_CBC, slen); +} + +uint ctx_size(unsigned int, unsigned int) +{ + return MY_AES_CTX_SIZE; +} + +void initialize_default_encryption() +{ + encryption_handler.encryption_ctx_size_func= ctx_size; + encryption_handler.encryption_ctx_init_func= ctx_init; + encryption_handler.encryption_ctx_update_func= my_aes_crypt_update; + encryption_handler.encryption_ctx_finish_func= my_aes_crypt_finish; + encryption_handler.encryption_encrypted_length_func= get_length; + encryption_handler.encryption_key_get_func= no_get_key; + encryption_handler.encryption_key_get_latest_version_func= no_key; +} diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 6febca7a555..3071206b201 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -5486,6 +5486,7 @@ fail: if (fil_system.is_initialised()) { innodb_shutdown(); } + backup_datasinks.destroy(); return(false); } diff --git a/include/aria_backup.h b/include/aria_backup.h index f399f6a6f40..dc931dbd33c 100644 --- a/include/aria_backup.h +++ b/include/aria_backup.h @@ -15,11 +15,15 @@ /* Interfaces for doing backups of Aria tables */ +#ifndef ARIA_BACKUP_INCLUDED + C_MODE_START typedef struct st_aria_table_capabilities { my_off_t header_size; + MARIA_CRYPT_DATA *crypt_data; + uint crypt_page_header_space; ulong bitmap_pages_covered; uint block_size; uint keypage_header; @@ -32,11 +36,15 @@ typedef struct st_aria_table_capabilities /* s3 capabilities */ ulong s3_block_size; uint8 compression; + char filename[FN_REFLEN]; } ARIA_TABLE_CAPABILITIES; -int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap); +int aria_get_capabilities(File kfile, const char *table_name, ARIA_TABLE_CAPABILITIES *cap); +void aria_free_capabilities(ARIA_TABLE_CAPABILITIES *cap); int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer); int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer, size_t *bytes_read); C_MODE_END + +#endif /* ARIA_BACKUP_INCLUDED */ diff --git a/mysql-test/suite/mariabackup/aria_encrypted.opt b/mysql-test/suite/mariabackup/aria_encrypted.opt new file mode 100644 index 00000000000..b277881dd85 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_encrypted.opt @@ -0,0 +1,7 @@ +--loose-innodb-encrypt-log=ON +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc +--loose-file-key-management-encryption-algorithm=aes_cbc +--aria-encrypt-tables=ON diff --git a/mysql-test/suite/mariabackup/aria_encrypted.result b/mysql-test/suite/mariabackup/aria_encrypted.result new file mode 100644 index 00000000000..8d21265d119 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_encrypted.result @@ -0,0 +1,8 @@ +# +# MDEV-38246 aria_read index failed on encrypted database during backup +# +CREATE TABLE t1 (product_id varchar(32) DEFAULT NULL, d1 date DEFAULT NULL, key(product_id)) engine=aria, row_format=page, transactional=1; +CREATE TABLE t2 (product_id varchar(32) DEFAULT NULL, d1 date DEFAULT NULL, key(product_id)) engine=aria, row_format=page, transactional=0; +insert into t1 select md5(seq), date_add("2025-05-05", interval seq day) from seq_1_to_10000; +insert into t2 select md5(seq), date_add("2025-05-05", interval seq day) from seq_1_to_10000; +drop table if exists t1,t2; diff --git a/mysql-test/suite/mariabackup/aria_encrypted.test b/mysql-test/suite/mariabackup/aria_encrypted.test new file mode 100644 index 00000000000..6ed3e0d08ef --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_encrypted.test @@ -0,0 +1,18 @@ +--source include/have_file_key_management.inc +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-38246 aria_read index failed on encrypted database during backup +--echo # + +CREATE TABLE t1 (product_id varchar(32) DEFAULT NULL, d1 date DEFAULT NULL, key(product_id)) engine=aria, row_format=page, transactional=1; +CREATE TABLE t2 (product_id varchar(32) DEFAULT NULL, d1 date DEFAULT NULL, key(product_id)) engine=aria, row_format=page, transactional=0; + +insert into t1 select md5(seq), date_add("2025-05-05", interval seq day) from seq_1_to_10000; +insert into t2 select md5(seq), date_add("2025-05-05", interval seq day) from seq_1_to_10000; + +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; +drop table if exists t1,t2; diff --git a/storage/maria/ma_backup.c b/storage/maria/ma_backup.c index 5c37167df78..9a9c7d142a9 100644 --- a/storage/maria/ma_backup.c +++ b/storage/maria/ma_backup.c @@ -18,6 +18,7 @@ #include "maria_def.h" #include "ma_blockrec.h" /* PAGE_SUFFIX_SIZE */ #include "ma_checkpoint.h" +#include "ma_crypt.h" #include /** @@ -30,8 +31,11 @@ @return X errno */ -int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap)__attribute__((visibility("default"))) ; -int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap) +int aria_get_capabilities(File kfile, const char *table_name, + ARIA_TABLE_CAPABILITIES *cap) + __attribute__((visibility("default"))) ; +int aria_get_capabilities(File kfile, const char *table_name, + ARIA_TABLE_CAPABILITIES *cap) { MARIA_SHARE share; int error= 0; @@ -42,6 +46,7 @@ int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap) DBUG_ENTER("aria_get_capabilities"); bzero(cap, sizeof(*cap)); + bzero(&share, sizeof(share)); if (my_pread(kfile,share.state.header.file_version, head_length, 0, MYF(MY_NABP))) DBUG_RETURN(HA_ERR_NOT_A_TABLE); @@ -67,13 +72,14 @@ int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap) goto err; } _ma_base_info_read(disc_cache + base_pos, &share.base); + strmake(cap->filename, table_name, sizeof(cap->filename)-1); cap->transactional= share.base.born_transactional; cap->checksum= MY_TEST(share.options & HA_OPTION_PAGE_CHECKSUM); cap->online_backup_safe= cap->transactional && cap->checksum; cap->header_size= share.base.keystart; cap->keypage_header= ((share.base.born_transactional ? - LSN_STORE_SIZE + TRANSID_SIZE : - 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + + LSN_STORE_SIZE + TRANSID_SIZE : 0) + + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + KEYPAGE_USED_SIZE); cap->block_size= share.base.block_size; cap->data_file_type= share.state.header.data_file_type; @@ -81,10 +87,23 @@ int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap) cap->compression= share.base.compression_algorithm; cap->encrypted= MY_TEST(share.base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED); + if (cap->encrypted) + { + share.data_file_name.str= (char*) table_name; /* in case of error */ + share.crypt_data= 0; + if (maria_read_crypt_data(kfile, &share)) + { + error= HA_ERR_DECRYPTION_FAILED; + goto err; + } + cap->keypage_header+= ma_crypt_get_index_page_header_space(&share); + cap->crypt_data= share.crypt_data; + cap->crypt_page_header_space= ma_crypt_get_data_page_header_space(); + } if (share.state.header.data_file_type == BLOCK_RECORD) { - /* Calulate how man pages the row bitmap covers. From _ma_bitmap_init() */ + /* Calulate how many pages the row bitmap covers. From _ma_bitmap_init() */ aligned_bit_blocks= (cap->block_size - PAGE_SUFFIX_SIZE) / 6; /* In each 6 bytes, we have 6*8/3 = 16 pages covered @@ -100,9 +119,26 @@ int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap) err: my_free(disc_cache); + if (error) + aria_free_capabilities(cap); DBUG_RETURN(error); } /* aria_get_capabilities */ + +void aria_free_capabilities(ARIA_TABLE_CAPABILITIES *cap) +{ + DBUG_ENTER("aria_free_capabilities"); + if (cap->crypt_data) + { + MARIA_SHARE share; + share.crypt_data= cap->crypt_data; + ma_crypt_free(&share); + cap->crypt_data= 0; + } + DBUG_VOID_RETURN; +} + + /**************************************************************************** ** store MARIA_BASE_INFO ****************************************************************************/ @@ -171,14 +207,14 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer) { MARIA_SHARE share; - int retry= 0; + int retry= 0, error= 0; DBUG_ENTER("aria_read_index"); share.keypage_header= cap->keypage_header; share.block_size= cap->block_size; - do + + for (;;) { - int error; size_t length; if ((length= my_pread(kfile, buffer, cap->block_size, block * cap->block_size, MYF(0))) != cap->block_size) @@ -199,15 +235,53 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, length= _ma_get_page_used(&share, buffer); if (length > cap->block_size - CRC_SIZE) DBUG_RETURN(HA_ERR_CRASHED); + + if (cap->encrypted) + { + /* We have to decrypt block to be able to calculate checksum */ + PAGECACHE_IO_HOOK_ARGS io_arg; + my_bool crypt_error; + io_arg.data= (void*) &share; + io_arg.page= buffer; + io_arg.crypt_buf= (uchar*) my_alloca(cap->block_size); + io_arg.pageno= block; + share.crypt_data= cap->crypt_data; + share.silence_encryption_errors= 1; + share.crypt_page_header_space= cap->crypt_page_header_space; + share.open_file_name.str= cap->filename; + + crypt_error= ma_crypt_index_post_read_hook(0, &io_arg); + my_afree(io_arg.crypt_buf); + if (!crypt_error) + DBUG_RETURN(0); /* ok */ + error= my_errno; + if (error == HA_ERR_DECRYPTION_FAILED || + error == HA_ERR_WRONG_CRC) + goto retry; + break; /* Give error */ + } + error= maria_page_crc_check(buffer, block, &share, MARIA_NO_CRC_NORMAL_PAGE, (int) length); - if (error == 0 || my_errno != HA_ERR_WRONG_CRC) - DBUG_RETURN(error); + if (error == 0) + DBUG_RETURN(0); + if ((error= my_errno) != HA_ERR_WRONG_CRC) + break; + } + retry: + if (retry++ >= MAX_RETRY) + { + error= HA_ERR_WRONG_CRC; + break; } my_sleep(100000); /* Sleep 0.1 seconds */ - } while (retry++ < MAX_RETRY); - DBUG_RETURN(HA_ERR_WRONG_CRC); + } + my_printf_error(error, + "Error %d reading index file %s block %lld", + MYF(ME_FATAL|ME_ERROR_LOG), + error, cap->filename, block); + DBUG_RETURN(error); } @@ -229,7 +303,7 @@ int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer, size_t *bytes_read) { MARIA_SHARE share; - int retry= 0; + int retry= 0, error= 0; DBUG_ENTER("aria_read_data"); share.keypage_header= cap->keypage_header; @@ -243,11 +317,9 @@ int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, DBUG_RETURN(HA_ERR_END_OF_FILE); DBUG_RETURN(*bytes_read > 0 ? 0 : (my_errno ? my_errno : -1)); } - *bytes_read= cap->block_size; - do + for (;;) { - int error; size_t length; if ((length= my_pread(dfile, buffer, cap->block_size, block * cap->block_size, MYF(0))) != cap->block_size) @@ -265,17 +337,55 @@ int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, if (length == cap->block_size) { if (!_ma_check_if_zero(buffer, share.block_size - CRC_SIZE)) - error= 0; + DBUG_RETURN(0); + /* Test if encrypted pages. Note that bitmap pages are not encrypted */ + if (cap->encrypted && (block % cap->bitmap_pages_covered)) + { + /* We have to decrypt block to be able to calculate checksum */ + PAGECACHE_IO_HOOK_ARGS io_arg; + my_bool crypt_error; + io_arg.data= (void*) &share; + io_arg.page= buffer; + io_arg.crypt_buf= (uchar*) my_alloca(cap->block_size); + io_arg.pageno= block; + share.crypt_data= cap->crypt_data; + share.silence_encryption_errors= 1; + share.crypt_page_header_space= cap->crypt_page_header_space; + share.open_file_name.str= cap->filename; + + crypt_error= ma_crypt_data_post_read_hook(0, &io_arg); + my_afree(io_arg.crypt_buf); + if (!crypt_error) + DBUG_RETURN(0); /* ok */ + if (my_errno == HA_ERR_DECRYPTION_FAILED || my_errno== HA_ERR_WRONG_CRC) + goto retry; + error= my_errno; + break; + } else + { error= maria_page_crc_check(buffer, block, &share, - ((block % cap->bitmap_pages_covered) == 0 ? - MARIA_NO_CRC_BITMAP_PAGE : - MARIA_NO_CRC_NORMAL_PAGE), - share.block_size - CRC_SIZE); - if (error == 0 || my_errno != HA_ERR_WRONG_CRC) - DBUG_RETURN(error); + ((block % cap->bitmap_pages_covered) == 0 ? + MARIA_NO_CRC_BITMAP_PAGE : + MARIA_NO_CRC_NORMAL_PAGE), + share.block_size - CRC_SIZE); + if (error == 0) + DBUG_RETURN(0); + if ((error= my_errno) != HA_ERR_WRONG_CRC) + break; + } + } +retry: + if (retry++ >= MAX_RETRY) + { + error= HA_ERR_WRONG_CRC; + break; } my_sleep(100000); /* Sleep 0.1 seconds */ - } while (retry++ < MAX_RETRY); - DBUG_RETURN(HA_ERR_WRONG_CRC); + } + my_printf_error(error, + "Error %d reading data file %s block %lld", + MYF(ME_FATAL|ME_ERROR_LOG), + error, cap->filename, block); + DBUG_RETURN(error); } diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index 6c8f6b6f94e..bc410306a52 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -37,8 +37,9 @@ struct st_crypt_key struct st_maria_crypt_data { struct st_encryption_scheme scheme; - uint space; mysql_mutex_t lock; /* protecting keys */ + uint space; + my_bool no_alloc; }; /** @@ -105,6 +106,7 @@ ma_crypt_create(MARIA_SHARE* share) (MARIA_CRYPT_DATA*)my_malloc(PSI_INSTRUMENT_ME, sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL)); crypt_data->scheme.type= CRYPT_SCHEME_1; crypt_data->scheme.locker= crypt_data_scheme_locker; + crypt_data->no_alloc= 0; mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock, MY_MUTEX_INIT_FAST); crypt_data->scheme.key_id= get_encryption_key_id(share); my_random_bytes(crypt_data->scheme.iv, sizeof(crypt_data->scheme.iv)); @@ -156,7 +158,7 @@ ma_crypt_write(MARIA_SHARE* share, File file) } uchar* -ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent) +ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent, my_bool no_alloc) { uchar type= buff[0]; uchar iv_length= buff[1]; @@ -176,7 +178,8 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent) { /* opening a table */ MARIA_CRYPT_DATA *crypt_data= - (MARIA_CRYPT_DATA*)my_malloc(PSI_INSTRUMENT_ME, sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL)); + (MARIA_CRYPT_DATA*) my_malloc(PSI_INSTRUMENT_ME, + sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL)); uint key_version; crypt_data->scheme.type= type; @@ -185,6 +188,7 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent) crypt_data->scheme.locker= crypt_data_scheme_locker; crypt_data->scheme.key_id= get_encryption_key_id(share); crypt_data->space= uint4korr(buff + 2); + crypt_data->no_alloc= no_alloc; memcpy(crypt_data->scheme.iv, buff + 6, sizeof(crypt_data->scheme.iv)); share->crypt_data= crypt_data; @@ -226,8 +230,8 @@ static my_bool ma_crypt_pre_read_hook(PAGECACHE_IO_HOOK_ARGS *args) return 0; } -static my_bool ma_crypt_data_post_read_hook(int res, - PAGECACHE_IO_HOOK_ARGS *args) +my_bool ma_crypt_data_post_read_hook(int res, + PAGECACHE_IO_HOOK_ARGS *args) { MARIA_SHARE *share= (MARIA_SHARE*) args->data; const uint size= share->block_size; @@ -263,7 +267,8 @@ static my_bool ma_crypt_data_post_read_hook(int res, uchar *tmp= args->page; args->page= args->crypt_buf; args->crypt_buf= NULL; - my_free(tmp); + if (!share->crypt_data->no_alloc) + my_free(tmp); } return maria_page_crc_check_data(res, args); @@ -361,8 +366,8 @@ void ma_crypt_set_data_pagecache_callbacks(PAGECACHE_FILE *file, } } -static my_bool ma_crypt_index_post_read_hook(int res, - PAGECACHE_IO_HOOK_ARGS *args) +my_bool ma_crypt_index_post_read_hook(int res, + PAGECACHE_IO_HOOK_ARGS *args) { MARIA_SHARE *share= (MARIA_SHARE*) args->data; const uint block_size= share->block_size; @@ -403,7 +408,8 @@ static my_bool ma_crypt_index_post_read_hook(int res, uchar *tmp= args->page; args->page= args->crypt_buf; args->crypt_buf= NULL; - my_free(tmp); + if (!share->crypt_data->no_alloc) + my_free(tmp); } return maria_page_crc_check_index(res, args); diff --git a/storage/maria/ma_crypt.h b/storage/maria/ma_crypt.h index acaf36ee831..367c95ff9ff 100644 --- a/storage/maria/ma_crypt.h +++ b/storage/maria/ma_crypt.h @@ -26,9 +26,12 @@ uint ma_crypt_get_index_page_header_space(struct st_maria_share *); uint ma_crypt_get_file_length(); /* bytes needed in file */ int ma_crypt_create(struct st_maria_share *); /* create encryption data */ int ma_crypt_write(struct st_maria_share *, File); /* write encryption data */ -uchar* ma_crypt_read(struct st_maria_share *, uchar *buff, - my_bool silent); /* read crypt data*/ - +uchar *ma_crypt_read(struct st_maria_share *, uchar *buff, + my_bool silent, my_bool no_alloc); /* read crypt data */ +my_bool ma_crypt_data_post_read_hook(int res, + PAGECACHE_IO_HOOK_ARGS *args); +my_bool ma_crypt_index_post_read_hook(int res, + PAGECACHE_IO_HOOK_ARGS *args); void ma_crypt_set_data_pagecache_callbacks(struct st_pagecache_file *file, struct st_maria_share *share); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index f7482624f92..44edea8dcf4 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -973,7 +973,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags, if (MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED)) { if (!(disk_pos= ma_crypt_read(share, disk_pos, - MY_TEST(open_flags & HA_OPEN_FOR_DROP)))) + MY_TEST(open_flags & HA_OPEN_FOR_DROP), 0))) goto err; } @@ -1258,6 +1258,52 @@ err: } /* maria_open */ +/* + Read the crypt from a maria key file + Crypt_data stored in share->crypt_data +*/ + +my_bool maria_read_crypt_data(File kfile, MARIA_SHARE *share) +{ + size_t base_pos, info_length, crypt_length; + uchar *cache; + uint keys, key_segs, uniques, unique_key_parts, columns; + my_bool error; + DBUG_ENTER("maria_read_crypt_data"); + + DBUG_ASSERT(share->base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED); + keys= (uint) share->state.header.keys; + key_segs= mi_uint2korr(share->state.header.key_parts); + uniques= (uint) share->state.header.uniques; + unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts); + columns= share->base.fields; + + base_pos= mi_uint2korr(share->state.header.base_pos); + /* Same calculation as in maria_create() */ + info_length= base_pos+(uint) (MARIA_BASE_INFO_SIZE+ + keys * MARIA_KEYDEF_SIZE+ + uniques * MARIA_UNIQUEDEF_SIZE + + (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+ + columns*(MARIA_COLUMNDEF_SIZE + 2)); + crypt_length= mi_uint2korr(share->state.header.header_length) - info_length; + if ((longlong) crypt_length < 0 || crypt_length > 1024) + { + my_errno=HA_ERR_NOT_A_TABLE; + DBUG_RETURN(1); + } + cache= (uchar*) my_alloca(crypt_length); + + error= 0; + if (mysql_file_pread(kfile, cache, crypt_length, info_length, + MYF(MY_FNABP | MY_WME)) || + !ma_crypt_read(share, cache, 0, 1)) + error= 1; + my_afree(cache); + + DBUG_RETURN(error); +} + + /* Reallocate a buffer, if the current buffer is not large enough */ diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 4c63e731e5e..82b850461e9 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -1659,6 +1659,7 @@ int _ma_open_keyfile(MARIA_SHARE *share); void _ma_setup_functions(MARIA_SHARE *share); my_bool _ma_dynmap_file(MARIA_HA *info, my_off_t size); void _ma_remap_file(MARIA_HA *info, my_off_t size); +my_bool maria_read_crypt_data(File kfile, MARIA_SHARE *share); MARIA_RECORD_POS _ma_write_init_default(MARIA_HA *info, const uchar *record); my_bool _ma_write_abort_default(MARIA_HA *info); diff --git a/storage/maria/s3_func.c b/storage/maria/s3_func.c index eeacc3deb71..4a47763b2e7 100644 --- a/storage/maria/s3_func.c +++ b/storage/maria/s3_func.c @@ -411,7 +411,7 @@ int aria_copy_to_s3(ms3_st *s3_client, const char *aws_bucket, O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_WME))) < 0) DBUG_RETURN(1); - if ((error= aria_get_capabilities(file, &cap))) + if ((error= aria_get_capabilities(file, table_name, &cap))) { fprintf(stderr, "Got error %d when reading Aria header from %s\n", error, path); diff --git a/storage/maria/test_ma_backup.c b/storage/maria/test_ma_backup.c index 5cb2b074887..288491ff9a0 100644 --- a/storage/maria/test_ma_backup.c +++ b/storage/maria/test_ma_backup.c @@ -103,7 +103,7 @@ static int copy_table(const char *table_name, int stage) O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_WME))) < 0) goto err; - if ((error= aria_get_capabilities(org_file, &cap))) + if ((error= aria_get_capabilities(org_file, table_name, &cap))) { fprintf(stderr, "aria_get_capabilities failed: %d\n", error); goto err; From a2b62fe57257b1563b5078ddd4934fef9f3b3c3b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 30 Jan 2026 16:17:55 +0100 Subject: [PATCH 148/152] MDEV-38246 aria_read index failed on encrypted database during backup Skip an all-zero pages in the index file. They can happen normally if the ma_checkpoint_background thread flushes some later page first (e.g. page 50 before page 48). Also: * don't do alloca() in a loop * correct the check in ma_crypt_index_post_read_hook(), the page can be completely full * compilation failure in ma_open.c:1289: comparison is always false due to limited range of data type --- storage/maria/ma_backup.c | 48 +++++++++++++++++++++++++++++++-------- storage/maria/ma_crypt.c | 2 +- storage/maria/ma_open.c | 2 +- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/storage/maria/ma_backup.c b/storage/maria/ma_backup.c index 9a9c7d142a9..4d46f7c143f 100644 --- a/storage/maria/ma_backup.c +++ b/storage/maria/ma_backup.c @@ -190,11 +190,10 @@ uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base) /** @brief Copy an index block with re-read if checksum doesn't match - @param dfile data file (.MAD) + @param kfile index file (.MAI) @param cap aria capabilities from aria_get_capabilities @param block block number to read (0, 1, 2, 3...) @param buffer read data to this buffer - @param bytes_read number of bytes actually read (in case of end of file) @return 0 ok @return HA_ERR_END_OF_FILE ; End of file @@ -208,6 +207,7 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, { MARIA_SHARE share; int retry= 0, error= 0; + void *alloca_ptr= 0; DBUG_ENTER("aria_read_index"); share.keypage_header= cap->keypage_header; @@ -220,21 +220,43 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, block * cap->block_size, MYF(0))) != cap->block_size) { if (length == 0) - DBUG_RETURN(HA_ERR_END_OF_FILE); + { + error= HA_ERR_END_OF_FILE; + goto end; + } if (length == (size_t) -1) - DBUG_RETURN(my_errno ? my_errno : -1); + { + error= my_errno ? my_errno : -1; + goto end; + } /* Assume we got a half read; Do a re-read */ } /* If not transactional or key file header, there are no checksums */ if (!cap->online_backup_safe || block < cap->header_size/ cap->block_size) - DBUG_RETURN(length == cap->block_size ? 0 : HA_ERR_CRASHED); + { + error= length == cap->block_size ? 0 : HA_ERR_CRASHED; + goto end; + } + + /* + skip an all-zero page. it can happen if the ma_checkpoint_background + thread flushes the later page before ever flushing this one. + */ + if (!_ma_check_if_zero(buffer, share.block_size)) + { + error= 0; + goto end; + } if (length == cap->block_size) { length= _ma_get_page_used(&share, buffer); if (length > cap->block_size - CRC_SIZE) - DBUG_RETURN(HA_ERR_CRASHED); + { + error= HA_ERR_CRASHED; + goto end; + } if (cap->encrypted) { @@ -243,7 +265,9 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, my_bool crypt_error; io_arg.data= (void*) &share; io_arg.page= buffer; - io_arg.crypt_buf= (uchar*) my_alloca(cap->block_size); + if (!alloca_ptr) + alloca_ptr= my_alloca(cap->block_size); + io_arg.crypt_buf= (uchar*) alloca_ptr; io_arg.pageno= block; share.crypt_data= cap->crypt_data; share.silence_encryption_errors= 1; @@ -251,9 +275,11 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, share.open_file_name.str= cap->filename; crypt_error= ma_crypt_index_post_read_hook(0, &io_arg); - my_afree(io_arg.crypt_buf); if (!crypt_error) - DBUG_RETURN(0); /* ok */ + { + error= 0; + goto end; + } error= my_errno; if (error == HA_ERR_DECRYPTION_FAILED || error == HA_ERR_WRONG_CRC) @@ -265,7 +291,7 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, MARIA_NO_CRC_NORMAL_PAGE, (int) length); if (error == 0) - DBUG_RETURN(0); + goto end; if ((error= my_errno) != HA_ERR_WRONG_CRC) break; } @@ -281,6 +307,8 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, "Error %d reading index file %s block %lld", MYF(ME_FATAL|ME_ERROR_LOG), error, cap->filename, block); +end: + my_afree(alloca_ptr); DBUG_RETURN(error); } diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index bc410306a52..ec8b2c0aef1 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -375,7 +375,7 @@ my_bool ma_crypt_index_post_read_hook(int res, if (res || page_used < share->keypage_header || - page_used >= block_size - CRC_SIZE) + page_used > block_size - CRC_SIZE) { res= 1; my_errno= HA_ERR_DECRYPTION_FAILED; diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 44edea8dcf4..e12d8f2305f 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -1286,7 +1286,7 @@ my_bool maria_read_crypt_data(File kfile, MARIA_SHARE *share) (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+ columns*(MARIA_COLUMNDEF_SIZE + 2)); crypt_length= mi_uint2korr(share->state.header.header_length) - info_length; - if ((longlong) crypt_length < 0 || crypt_length > 1024) + if (crypt_length > 1024) { my_errno=HA_ERR_NOT_A_TABLE; DBUG_RETURN(1); From 4802bfe4f9071c2963980fa8c913aee1577a0187 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 30 Jan 2026 17:59:42 +0100 Subject: [PATCH 149/152] MDEV-38710 Assertion is_lock_owner on error returning from auto-create in mysql_admin_table don't auto-add new partitions if we're already at TIMESTAMP_MAX_VALUE --- mysql-test/suite/versioning/r/partition.result | 10 +++++++++- mysql-test/suite/versioning/t/partition.test | 10 +++++++++- sql/partition_info.cc | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index d828e775c3d..2d408c170f4 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -3619,6 +3619,14 @@ create or replace table t (a int) with system versioning partition by system_time interval 10 year; drop table t; # -# End of 10.11 tests +# MDEV-38710 Assertion is_lock_owner on error returning from auto-create in mysql_admin_table # +set timestamp=2147483647; +create table t (x int) with system versioning partition by system_time interval 1 hour auto; +repair table t; +Table Op Msg_type Msg_text +test.t repair status OK +drop table t; +set timestamp=default; +# End of 10.11 tests set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 634ec009597..28633ab948f 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2843,8 +2843,16 @@ partition by system_time interval 10 year; drop table t; --echo # ---echo # End of 10.11 tests +--echo # MDEV-38710 Assertion is_lock_owner on error returning from auto-create in mysql_admin_table --echo # +set timestamp=2147483647; +create table t (x int) with system versioning partition by system_time interval 1 hour auto; +repair table t; +drop table t; +set timestamp=default; + +--echo # End of 10.11 tests + set global innodb_stats_persistent= @save_persistent; --source suite/versioning/common_finish.inc diff --git a/sql/partition_info.cc b/sql/partition_info.cc index b459608c764..fe2dd6f0895 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -832,7 +832,8 @@ bool partition_info::vers_set_hist_part(THD *thd, uint *create_count) } else if (vers_info->interval.is_set() && /* Left boundary is closed */ - vers_info->hist_part->range_value <= thd->query_start()) + vers_info->hist_part->range_value <= thd->query_start() && + vers_info->hist_part->range_value < TIMESTAMP_MAX_VALUE) { partition_element *next= NULL; bool error= true; From d5db6c1daa132acc85dfbbdd35724031db6843fe Mon Sep 17 00:00:00 2001 From: Hemant Dangi Date: Fri, 3 Oct 2025 11:16:26 +0530 Subject: [PATCH 150/152] MDL BF-BF conflict on ALTER and INSERT with multi-level foreign key parents Issue: On galera write node INSERT statements does not acquire MDL locks on it's all child tables and thereby wsrep certification keys are also added for limited tables, but on applier nodes it does acquire MDL locks for all child tables. This can result into MDL BF-BF conflict on applier node when transactions referring to parent and child tables are executed concurrently. For example: Tables with foreign keys: t1<-t2<-t3<-t4 Conflicting transactions: INSERT t1 and DROP TABLE t4 Wsrep certification keys taken on write node: - for INSERT t1: t1 and t2 - for DROP TABLE t4: t4 On applier node MDL BF-BF conflict happened between two transaction because MDL locks on t1, t2, t3 and t4 were taken for INSERT t1, which conflicted with MDL lock on t4 taken by DROP TABLE t4. The Wsrep certification keys helps in resolving this MDL BF-BF conflict by prioritizing and scheduling concurrent transactions. But to generate Wsrep certification keys it needs to open and take MDL locks on all the child tables. On applier nodes Write_rows event is implicitly a REPLACE, deleting all conflicting rows which can cause cascading FK actions and locks on foreign key children tables. Solution: For Galera applier nodes the Write_rows event is considered pure INSERT which will never cause cascading FK actions and locks on foreign key children tables. --- mysql-test/suite/galera/r/MDEV-25039.result | 63 ++++++++ .../r/galera_multi_level_fk_ddl_insert.result | 22 --- mysql-test/suite/galera/t/MDEV-25039.test | 109 ++++++++++++++ .../t/galera_multi_level_fk_ddl_insert.test | 137 +----------------- .../galera_multi_level_foreign_key_insert.inc | 44 ++++++ .../rpl/r/rpl_foreign_key_ddl_insert.result | 105 ++++++++++++++ .../rpl_foreign_key_lock_table_insert.result | 84 +++++++++++ mysql-test/suite/rpl/t/rpl_fk_ddl.inc | 38 +++++ .../rpl/t/rpl_foreign_key_ddl_insert.test | 114 +++++++++++++++ .../t/rpl_foreign_key_lock_table_insert.test | 130 +++++++++++++++++ sql/log_event_server.cc | 16 +- sql/sql_base.cc | 45 +----- sql/sql_table.cc | 7 + sql/table.h | 6 +- sql/wsrep_mysqld.cc | 2 +- 15 files changed, 720 insertions(+), 202 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-25039.result create mode 100644 mysql-test/suite/galera/t/MDEV-25039.test create mode 100644 mysql-test/suite/galera/t/galera_multi_level_foreign_key_insert.inc create mode 100644 mysql-test/suite/rpl/r/rpl_foreign_key_ddl_insert.result create mode 100644 mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result create mode 100644 mysql-test/suite/rpl/t/rpl_fk_ddl.inc create mode 100644 mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test create mode 100644 mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test diff --git a/mysql-test/suite/galera/r/MDEV-25039.result b/mysql-test/suite/galera/r/MDEV-25039.result new file mode 100644 index 00000000000..18f089f38fe --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-25039.result @@ -0,0 +1,63 @@ +connection node_2; +connection node_1; +# +# 1. LOCK TABLE and INSERT +# +connection node_1; +CREATE TABLE t1 ( +id varchar(100), +PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( +id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +a varchar(100), +b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; +connection node_2; +select * from t1; +id +a +connection node_1; +select * from t1; +id +a +DROP TABLE t3, t2, t1; +# +# 2. FLUSH TABLES WITH READ LOCK and INSERT +# +connection node_1; +CREATE TABLE t1 ( +id varchar(100), +PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( +id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +a varchar(100), +b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +FLUSH TABLES WITH READ LOCK; +INSERT INTO t1 VALUES ('a'); +ERROR HY000: Can't execute the query because you have a conflicting read lock +UNLOCK TABLES; +connection node_2; +select * from t1; +id +connection node_1; +select * from t1; +id +DROP TABLE t3, t2, t1; diff --git a/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_insert.result b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_insert.result index aa120e87cb9..f799d372484 100644 --- a/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_insert.result +++ b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_insert.result @@ -48,7 +48,6 @@ connection node_2; SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; SET SESSION wsrep_sync_wait = 0; connection node_1; -SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; START TRANSACTION; INSERT INTO t1 VALUES (3,0); COMMIT; @@ -62,10 +61,6 @@ connection node_1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL DEBUG_DBUG = ""; SET GLOBAL wsrep_slave_threads=DEFAULT; -connection node_1; -include/assert_grep.inc [Foreign key referenced table found: 2 tables] -include/assert_grep.inc [Foreign key referenced table found: test.t2] -include/assert_grep.inc [Foreign key referenced table found: test.t3] connection node_2; select * from t1; id f2 @@ -146,7 +141,6 @@ connection node_2; SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; SET SESSION wsrep_sync_wait = 0; connection node_1; -SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; START TRANSACTION; INSERT INTO t1 VALUES (3,0); COMMIT; @@ -160,11 +154,6 @@ connection node_1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL DEBUG_DBUG = ""; SET GLOBAL wsrep_slave_threads=DEFAULT; -connection node_1; -include/assert_grep.inc [Foreign key referenced table found: 3 tables] -include/assert_grep.inc [Foreign key referenced table found: test.t2] -include/assert_grep.inc [Foreign key referenced table found: test.t3] -include/assert_grep.inc [Foreign key referenced table found: test.t4] connection node_2; select * from t1; id f2 @@ -233,7 +222,6 @@ connection node_2; SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; SET SESSION wsrep_sync_wait = 0; connection node_1; -SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; START TRANSACTION; INSERT INTO t1 VALUES (3,0); COMMIT; @@ -247,11 +235,6 @@ connection node_1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL DEBUG_DBUG = ""; SET GLOBAL wsrep_slave_threads=DEFAULT; -connection node_1; -include/assert_grep.inc [Foreign key referenced table found: 2 tables] -include/assert_grep.inc [Foreign key referenced table found: test.t2] -include/assert_grep.inc [Foreign key referenced table found: test.t3] -include/assert_grep.inc [Foreign key referenced table found: test.t4] connection node_2; select * from t1; id f2 @@ -323,7 +306,6 @@ connection node_2; SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; SET SESSION wsrep_sync_wait = 0; connection node_1; -SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; START TRANSACTION; INSERT INTO t1 VALUES (3,0); COMMIT; @@ -337,10 +319,6 @@ connection node_1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL DEBUG_DBUG = ""; SET GLOBAL wsrep_slave_threads=DEFAULT; -connection node_1; -include/assert_grep.inc [Foreign key referenced table found: 1 tables] -include/assert_grep.inc [Foreign key referenced table found: test.t2] -include/assert_grep.inc [Foreign key referenced table found: test.t3] connection node_2; select * from t1; id f2 diff --git a/mysql-test/suite/galera/t/MDEV-25039.test b/mysql-test/suite/galera/t/MDEV-25039.test new file mode 100644 index 00000000000..5c2514028f6 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-25039.test @@ -0,0 +1,109 @@ +# +# MDEV-38216 was failing after MDEV-25039 changes. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_perfschema.inc + +--echo # +--echo # 1. LOCK TABLE and INSERT +--echo # + +# +# Setup +# +--connection node_1 +CREATE TABLE t1 ( + id varchar(100), + PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( + id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + a varchar(100), + b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + + +# +# Verify insert has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; + +--connection node_1 +select * from t1; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; + + +--echo # +--echo # 2. FLUSH TABLES WITH READ LOCK and INSERT +--echo # + +# +# Setup +# +--connection node_1 +CREATE TABLE t1 ( + id varchar(100), + PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( + id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + a varchar(100), + b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + + +# +# Verify insert has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; + +--connection node_1 +select * from t1; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; diff --git a/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test index d4a1874d51a..36fcb3947d5 100644 --- a/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test +++ b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test @@ -72,35 +72,8 @@ INSERT INTO t4 VALUES (2,2,1234); --let $fk_parent_query = DROP TABLE t4 --let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_mdl_lock_num = 3 ---source galera_multi_level_foreign_key.inc - - -# -# Verify Foreign key for referenced table added. -# ---connection node_1 ---let assert_text= Foreign key referenced table found: 2 tables ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 2 ---let assert_select= Foreign key referenced table found: ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t2 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 1 ---let assert_select= Foreign key referenced table found: test.t2 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t3 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 1 ---let assert_select= Foreign key referenced table found: test.t3 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key_insert.inc # # Verify insert and drop table has succeded. @@ -191,41 +164,8 @@ INSERT INTO t4 VALUES (2,2,1234); # Issue a INSERT to table that references t1 # --let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_mdl_lock_num = 4 ---source galera_multi_level_foreign_key.inc - - -# -# Verify Foreign key for referenced table added. -# ---connection node_1 ---let assert_text= Foreign key referenced table found: 3 tables ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 5 ---let assert_select= Foreign key referenced table found: ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t2 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 2 ---let assert_select= Foreign key referenced table found: test.t2 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t3 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 2 ---let assert_select= Foreign key referenced table found: test.t3 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t4 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 1 ---let assert_select= Foreign key referenced table found: test.t4 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key_insert.inc # @@ -296,42 +236,8 @@ INSERT INTO t3 VALUES (2,2,1234); --let $fk_parent_query = CREATE TABLE t4 (id INT PRIMARY KEY, t3_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t3_id(t3_id), CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE) --let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_mdl_lock_num = 4 ---source galera_multi_level_foreign_key.inc - - -# -# Verify Foreign key for referenced table added. -# ---connection node_1 ---let assert_text= Foreign key referenced table found: 2 tables ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 8 ---let assert_select= Foreign key referenced table found: ---let $assert_only_after = CURRENT_TEST: ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t2 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 3 ---let assert_select= Foreign key referenced table found: test.t2 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t3 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 3 ---let assert_select= Foreign key referenced table found: test.t3 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t4 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 2 ---let assert_select= Foreign key referenced table found: test.t4 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key_insert.inc # @@ -403,35 +309,8 @@ INSERT INTO t3 VALUES (2,2,1234); --let $fk_parent_query = OPTIMIZE TABLE t3 --let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_mdl_lock_num = 3 ---source galera_multi_level_foreign_key.inc - - -# -# Verify Foreign key for referenced table added. -# ---connection node_1 ---let assert_text= Foreign key referenced table found: 1 tables ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 10 ---let assert_select= Foreign key referenced table found: ---let $assert_only_after = CURRENT_TEST: ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t2 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 4 ---let assert_select= Foreign key referenced table found: test.t2 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc - ---let assert_text= Foreign key referenced table found: test.t3 ---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err ---let assert_count= 4 ---let assert_select= Foreign key referenced table found: test.t3 ---let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert ---source include/assert_grep.inc +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key_insert.inc # diff --git a/mysql-test/suite/galera/t/galera_multi_level_foreign_key_insert.inc b/mysql-test/suite/galera/t/galera_multi_level_foreign_key_insert.inc new file mode 100644 index 00000000000..5cb79bd4741 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_multi_level_foreign_key_insert.inc @@ -0,0 +1,44 @@ + +--connection node_2 +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; + +--connection node_1 +--eval $fk_parent_query + +--connection node_2 +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; + +# +# Execute child query on node_1. +# If bug is present, expect the wait condition +# to timeout and when the child query applies, it +# will be granted a MDL lock on parent table. +# When resumed, the parent query will +# also try to acquire MDL lock on parent table, +# causing a BF-BF conflict on that MDL lock. +# +--connection node_1 +START TRANSACTION; +--eval $fk_child_query +--let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" +--source include/wait_condition.inc +COMMIT; + + +--connection node_2 +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; + + +# +# Cleanup +# +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; + +--connection node_1 +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; diff --git a/mysql-test/suite/rpl/r/rpl_foreign_key_ddl_insert.result b/mysql-test/suite/rpl/r/rpl_foreign_key_ddl_insert.result new file mode 100644 index 00000000000..d680df55bf7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_foreign_key_ddl_insert.result @@ -0,0 +1,105 @@ +include/master-slave.inc +[connection master] +connection master; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +connection slave; +connection slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +set @@global.debug_dbug= "+d,sync.rm_table_no_locks"; +set global slave_exec_mode='IDEMPOTENT'; +connection master; +DROP TABLE t2; +connection slave; +set debug_sync='now WAIT_FOR after_lock_table'; +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES (3,0); +COMMIT; +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +set global slave_exec_mode='STRICT'; +connection slave; +select * from t1; +id f2 +1 0 +2 0 +3 0 +select * from t2; +ERROR 42S02: Table 'test.t2' doesn't exist +connection master; +select * from t1; +id f2 +1 0 +2 0 +3 0 +select * from t2; +ERROR 42S02: Table 'test.t2' doesn't exist +DROP TABLE t1; +connection slave; +connection master; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +connection slave; +connection slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +set @@global.debug_dbug= "+d,sync.rm_table_no_locks"; +set global slave_exec_mode='STRICT'; +connection master; +DROP TABLE t2; +connection slave; +set debug_sync='now WAIT_FOR after_lock_table'; +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES (3,0); +COMMIT; +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +set global slave_exec_mode='STRICT'; +connection slave; +select * from t1; +id f2 +1 0 +2 0 +3 0 +select * from t2; +ERROR 42S02: Table 'test.t2' doesn't exist +connection master; +select * from t1; +id f2 +1 0 +2 0 +3 0 +select * from t2; +ERROR 42S02: Table 'test.t2' doesn't exist +DROP TABLE t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result b/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result new file mode 100644 index 00000000000..396df9dfda5 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result @@ -0,0 +1,84 @@ +include/master-slave.inc +[connection master] +connection slave; +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( a varchar(100), b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; +DROP TABLE t3, t2, t1; +connection slave; +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='STRICT'; +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( a varchar(100), b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; +DROP TABLE t3, t2, t1; +connection slave; +connection slave; +SET DEBUG_SYNC= 'RESET'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET GLOBAL SLAVE_EXEC_MODE=DEFAULT; +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( a varchar(100), b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +FLUSH TABLES WITH READ LOCK; +INSERT INTO t1 VALUES ('a'); +ERROR HY000: Can't execute the query because you have a conflicting read lock +UNLOCK TABLES; +DROP TABLE t3, t2, t1; +connection slave; +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='STRICT'; +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; +CREATE TABLE t2 ( id varchar(100) , a varchar(100), +PRIMARY KEY (id,a), +KEY a (a), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( a varchar(100), b varchar(100) , +PRIMARY KEY (a, b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; +FLUSH TABLES WITH READ LOCK; +INSERT INTO t1 VALUES ('a'); +ERROR HY000: Can't execute the query because you have a conflicting read lock +UNLOCK TABLES; +DROP TABLE t3, t2, t1; +connection slave; +connection slave; +set global slave_exec_mode='STRICT'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_fk_ddl.inc b/mysql-test/suite/rpl/t/rpl_fk_ddl.inc new file mode 100644 index 00000000000..d17f6720898 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_fk_ddl.inc @@ -0,0 +1,38 @@ +# Set slave_exec_mode. +connection slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +--let $default_fk_slave_exec_mode= `SELECT @@global.slave_exec_mode` + +# Set debug sync point to block parent query on slave. +set @@global.debug_dbug= "+d,sync.rm_table_no_locks"; + +--eval set global slave_exec_mode='$fk_slave_exec_mode' + + +# Execute parent query. +connection master; +--eval $fk_parent_query + + +# Wait for parent query to take mdl lock. +--connection slave +set debug_sync='now WAIT_FOR after_lock_table'; +--let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_parent_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" +--source include/wait_condition.inc + + +# Now execute child query. +--connection master +START TRANSACTION; +--eval $fk_child_query +--let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_child_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" +--source include/wait_condition.inc +COMMIT; + + +# Cleanup +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +--eval set global slave_exec_mode='$default_fk_slave_exec_mode' diff --git a/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test b/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test new file mode 100644 index 00000000000..2a5600cc76b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test @@ -0,0 +1,114 @@ +source include/have_debug_sync.inc; +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +# 1. For slave_exec_mode=IDEMPOTENT. +# Query executed: INSERT t1 and DROP t2 +connection master; +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +--sync_slave_with_master + + +--let $fk_parent_query = DROP TABLE t2 +--let $fk_child_query = INSERT INTO t1 VALUES (3,0) +--let $fk_slave_exec_mode = IDEMPOTENT +--let $fk_mdl_lock_parent_num = 2 +--let $fk_mdl_lock_child_num = 1 +--source rpl_fk_ddl.inc + + +# +# Verify insert and drop table has succeded. +# +--connection slave +--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; +--error ER_NO_SUCH_TABLE +select * from t2; + +--connection master +select * from t1; +--error ER_NO_SUCH_TABLE +select * from t2; + + +# +# Cleanup +# +DROP TABLE t1; +--sync_slave_with_master + + +# 2. For slave_exec_mode=STRICT. +# Query executed: INSERT t1 and DROP t2 +connection master; +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +--sync_slave_with_master + + +--let $fk_parent_query = DROP TABLE t2 +--let $fk_child_query = INSERT INTO t1 VALUES (3,0) +--let $fk_slave_exec_mode = STRICT +--let $fk_mdl_lock_parent_num = 2 +--let $fk_mdl_lock_child_num = 1 +--source rpl_fk_ddl.inc + + +# +# Verify insert and drop table has succeded. +# +--connection slave +--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; +--error ER_NO_SUCH_TABLE +select * from t2; + +--connection master +select * from t1; +--error ER_NO_SUCH_TABLE +select * from t2; + + +# +# Cleanup +# +DROP TABLE t1; +--sync_slave_with_master + + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test b/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test new file mode 100644 index 00000000000..50820d99566 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test @@ -0,0 +1,130 @@ +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +connection slave; +--let $default_fk_slave_exec_mode= `SELECT @@global.slave_exec_mode` + +# 1. Set SLAVE_EXEC_MODE as IDEMPOTENT +# and execute INSERT with locked table. +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; + +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( a varchar(100), b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + +# Cleanup +DROP TABLE t3, t2, t1; +--sync_slave_with_master + + +# 2. Set SLAVE_EXEC_MODE as STRICT +# and execute INSERT with locked table. +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='STRICT'; + +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( a varchar(100), b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + +# Cleanup +DROP TABLE t3, t2, t1; +--sync_slave_with_master + +connection slave; +SET DEBUG_SYNC= 'RESET'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET GLOBAL SLAVE_EXEC_MODE=DEFAULT; + +# 3. Set SLAVE_EXEC_MODE as IDEMPOTENT +# and execute INSERT with locked table. +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; + +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( a varchar(100), b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + +# Cleanup +DROP TABLE t3, t2, t1; +--sync_slave_with_master + + +# 4. Set SLAVE_EXEC_MODE as STRICT +# and execute INSERT with locked table. +connection slave; +SET GLOBAL SLAVE_EXEC_MODE='STRICT'; + +connection master; +CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; + +CREATE TABLE t2 ( id varchar(100) , a varchar(100), + PRIMARY KEY (id,a), + KEY a (a), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( a varchar(100), b varchar(100) , + PRIMARY KEY (a, b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) +) ENGINE=InnoDB; + +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +INSERT INTO t1 VALUES ('a'); +UNLOCK TABLES; + +# Cleanup +DROP TABLE t3, t2, t1; +--sync_slave_with_master + +connection slave; +--eval set global slave_exec_mode='$default_fk_slave_exec_mode' + +--source include/rpl_end.inc diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 9ad2c5ebb1e..5beccb1e88c 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -8001,11 +8001,23 @@ Write_rows_log_event::do_exec_row(rpl_group_info *rgi) #if defined(HAVE_REPLICATION) uint8 Write_rows_log_event::get_trg_event_map() { - return trg2bit(TRG_EVENT_INSERT) | trg2bit(TRG_EVENT_UPDATE) | - trg2bit(TRG_EVENT_DELETE); + /* + In SLAVE_EXEC_MODE_IDEMPOTENT mode, Write_rows_log_event event is + implicitly a REPLACE, deleting all conflicting rows which can cause + foreign key constraint cascade operations on FK referencing table. + + In SLAVE_EXEC_MODE_STRICT mode, the Write_rows_log_event is pure INSERT, + will never cause foreign key constraint cascade operations on foreign key + referencing tables. + */ + if (slave_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT) + return trg2bit(TRG_EVENT_INSERT) | trg2bit(TRG_EVENT_DELETE); + else + return trg2bit(TRG_EVENT_INSERT); } #endif + /************************************************************************** Delete_rows_log_event member functions **************************************************************************/ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 44c0c275f12..11155aa36e1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3965,15 +3965,6 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables, (tables->updating && tables->lock_type >= TL_FIRST_WRITE) || thd->lex->default_used; -#ifdef WITH_WSREP - if (WSREP(thd) && !thd->wsrep_applier && - wsrep_is_active(thd) && - (sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) && - tables->lock_type == TL_READ) { - maybe_need_prelocking= true; - } -#endif - if (thd->locked_tables_mode <= LTM_LOCK_TABLES && ! has_prelocking_list && maybe_need_prelocking) { @@ -5106,7 +5097,6 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, Query_arena *arena, backup; TABLE *table= table_list->table; bool error= FALSE; - bool override_fk_ignore_table= FALSE; if (!table->file->referenced_by_foreign_key()) DBUG_RETURN(FALSE); @@ -5123,37 +5113,6 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, *need_prelocking= TRUE; -#ifdef WITH_WSREP - /* - MDL is enough for read-only FK checks, we don't need the table, - but on galera applier node lock_type is set to TL_FIRST_WRITE and not - TL_READ, which is due to Write_rows_log_event event logged for INSERT - is used to record insert, update and delete - (Write_rows_log_event::get_trg_event_map()), and therefore all child - tables will be opened and MDL locks will be taken on applier node, while - opening of multiple child tables is ignored on write node by setting - open_strategy= OPEN_STUB in init_one_table_for_prelocking(). - This difference in write and applier node can result in MDL deadlock. - Tables with foreign keys: t1<-t2<-t3<-t4 - Conflicting transactions: INSERT t1 and DROP TABLE t4 - Wsrep certification keys taken on write node: - - for INSERT t1: t1 and t2 - - for DROP TABLE t4: t4 - On applier node MDL deadlock happened between two transaction because - MDL locks for INSERT t1 were taken on t1, t2, t3 and t4, which conflicted - with MDL lock on t4 taken by DROP TABLE t4. - The Wsrep certification keys does helps in resolving in transactions - getting MDL deadlock. But to generate Wsrep certification keys it needs - to open and take MDL locks on all child tables. So that conflicting - transactions can be prioritize and scheduled. - */ - if (WSREP(thd) && !thd->wsrep_applier && - wsrep_is_active(thd) && - (sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA)) { - override_fk_ignore_table= TRUE; - } -#endif // WITH_WSREP - while ((fk= fk_list_it++)) { // FK_OPTION_RESTRICT and FK_OPTION_NO_ACTION only need read access @@ -5177,15 +5136,13 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST::PRELOCK_FK, table_list->belong_to_view, op, &prelocking_ctx->query_tables_last, - table_list->for_insert_data, - override_fk_ignore_table); + table_list->for_insert_data); #ifdef WITH_WSREP /* Append table level shared key for the referenced/foreign table for: - statement that updates existing rows (UPDATE, multi-update) - statement that deletes existing rows (DELETE, DELETE_MULTI) - - statement that inserts new rows (INSERT, REPLACE, LOAD, ALTER TABLE) This is done to avoid potential MDL conflicts with concurrent DDLs. */ if (wsrep_foreign_key_append(thd, fk)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 452ca09b31e..f732247d7e4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1555,6 +1555,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); + DBUG_EXECUTE_IF("sync.rm_table_no_locks", + { + const char action[] = "now SIGNAL after_lock_table" + " WAIT_FOR continue"; + DBUG_ASSERT(!debug_sync_set_action(thd, + STRING_WITH_LEN(action))); + };); if (drop_temporary) { /* "DROP TEMPORARY" but a temporary table was not found */ diff --git a/sql/table.h b/sql/table.h index 79ace8dcec7..3ec90ca778a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2383,8 +2383,7 @@ struct TABLE_LIST const LEX_CSTRING *table_name_arg, const LEX_CSTRING *alias_arg, enum thr_lock_type lock_type_arg, prelocking_types prelocking_type, TABLE_LIST *belong_to_view_arg, uint8 trg_event_map_arg, - TABLE_LIST ***last_ptr, my_bool insert_data, - my_bool override_fk_ignore_table= FALSE) + TABLE_LIST ***last_ptr, my_bool insert_data) { init_one_table(db_arg, table_name_arg, alias_arg, lock_type_arg); cacheable_table= 1; @@ -2395,8 +2394,7 @@ struct TABLE_LIST belong_to_view= belong_to_view_arg; trg_event_map= trg_event_map_arg; /* MDL is enough for read-only FK checks, we don't need the table */ - if (prelocking_type == PRELOCK_FK && lock_type < TL_FIRST_WRITE && - !override_fk_ignore_table) + if (prelocking_type == PRELOCK_FK && lock_type < TL_FIRST_WRITE) open_strategy= OPEN_STUB; **last_ptr= this; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index f08dec7fc84..bf868fef75f 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -4126,7 +4126,7 @@ bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk) if (WSREP(thd) && !thd->wsrep_applier && wsrep_is_active(thd) && (sql_command_flags[thd->lex->sql_command] & - (CF_UPDATES_DATA | CF_DELETES_DATA | CF_INSERTS_DATA))) + (CF_UPDATES_DATA | CF_DELETES_DATA))) { wsrep::key key(wsrep::key::shared); key.append_key_part(fk->foreign_db->str, fk->foreign_db->length); From 3218602d3100db9ce7a875511a591cddc173cc16 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Fri, 30 Jan 2026 15:39:36 -0700 Subject: [PATCH 151/152] MDEV-25039: MDL BF-BF conflict because of foreign key Fix rpl suite tests added by MDEV-25039. rpl_foreign_key_lock_table_insert.test is removed altogether because it is unclear what the purpose of the test is. The changes of the patch were done on the slave, yet all operations in the test were done on the master. Nothing different could happen on the slave because it is configured to be serial, so all transactions would run sequentially anyway, and no validations were performed. rpl_foreign_key_ddl_insert.test was renamed to rpl_row_foreign_key_mdl.test and the test itself was re-written to be a minimal test case to ensure that MDL locking behavior is different pre- and post- patch. A few problems with the original test: * No foreign-key locking was done on the slave because the table engine was not InnoDB. * rpl_fk_ddl.inc had inconsistent validation checking. I.e., the child query validation checks were done on the master (which is incorrect) and because the slave was configured to be serial, the two transactions could not run concurrently on the slave anyway. --- .../rpl_foreign_key_lock_table_insert.result | 84 ----------- .../rpl/r/rpl_row_foreign_key_mdl.result | 68 +++++++++ mysql-test/suite/rpl/t/rpl_fk_ddl.inc | 38 ----- .../rpl/t/rpl_foreign_key_ddl_insert.test | 114 --------------- .../t/rpl_foreign_key_lock_table_insert.test | 130 ------------------ .../suite/rpl/t/rpl_row_foreign_key_mdl.inc | 39 ++++++ .../suite/rpl/t/rpl_row_foreign_key_mdl.test | 55 ++++++++ sql/log_event_server.cc | 6 + sql/sql_table.cc | 7 - 9 files changed, 168 insertions(+), 373 deletions(-) delete mode 100644 mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result create mode 100644 mysql-test/suite/rpl/r/rpl_row_foreign_key_mdl.result delete mode 100644 mysql-test/suite/rpl/t/rpl_fk_ddl.inc delete mode 100644 mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test delete mode 100644 mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.inc create mode 100644 mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.test diff --git a/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result b/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result deleted file mode 100644 index 396df9dfda5..00000000000 --- a/mysql-test/suite/rpl/r/rpl_foreign_key_lock_table_insert.result +++ /dev/null @@ -1,84 +0,0 @@ -include/master-slave.inc -[connection master] -connection slave; -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; -CREATE TABLE t2 ( id varchar(100) , a varchar(100), -PRIMARY KEY (id,a), -KEY a (a), -CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; -CREATE TABLE t3 ( a varchar(100), b varchar(100) , -PRIMARY KEY (a, b), -CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; -DROP TABLE t3, t2, t1; -connection slave; -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='STRICT'; -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; -CREATE TABLE t2 ( id varchar(100) , a varchar(100), -PRIMARY KEY (id,a), -KEY a (a), -CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; -CREATE TABLE t3 ( a varchar(100), b varchar(100) , -PRIMARY KEY (a, b), -CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; -DROP TABLE t3, t2, t1; -connection slave; -connection slave; -SET DEBUG_SYNC= 'RESET'; -SET @@GLOBAL.debug_dbug = @saved_dbug; -SET GLOBAL SLAVE_EXEC_MODE=DEFAULT; -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; -CREATE TABLE t2 ( id varchar(100) , a varchar(100), -PRIMARY KEY (id,a), -KEY a (a), -CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; -CREATE TABLE t3 ( a varchar(100), b varchar(100) , -PRIMARY KEY (a, b), -CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; -FLUSH TABLES WITH READ LOCK; -INSERT INTO t1 VALUES ('a'); -ERROR HY000: Can't execute the query because you have a conflicting read lock -UNLOCK TABLES; -DROP TABLE t3, t2, t1; -connection slave; -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='STRICT'; -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; -CREATE TABLE t2 ( id varchar(100) , a varchar(100), -PRIMARY KEY (id,a), -KEY a (a), -CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; -CREATE TABLE t3 ( a varchar(100), b varchar(100) , -PRIMARY KEY (a, b), -CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; -FLUSH TABLES WITH READ LOCK; -INSERT INTO t1 VALUES ('a'); -ERROR HY000: Can't execute the query because you have a conflicting read lock -UNLOCK TABLES; -DROP TABLE t3, t2, t1; -connection slave; -connection slave; -set global slave_exec_mode='STRICT'; -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_foreign_key_mdl.result b/mysql-test/suite/rpl/r/rpl_row_foreign_key_mdl.result new file mode 100644 index 00000000000..2bd31906c32 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_foreign_key_mdl.result @@ -0,0 +1,68 @@ +include/master-slave.inc +[connection master] +# +# Initialize test data +connection master; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY AUTO_INCREMENT, +f2 INTEGER +) engine=innodb; +CREATE TABLE t2 ( +id INT PRIMARY KEY AUTO_INCREMENT, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +) engine=innodb; +INSERT INTO t1 (f2) VALUES (0); +INSERT INTO t1 (f2) VALUES (0); +INSERT INTO t2 (t1_id, f2) VALUES (1,1234); +connection slave; +# +# slave_exec_mode = IDEMPOTENT +connection slave; +set @saved_dbug = @@global.debug_dbug; +set @saved_exec_mode= @@global.slave_exec_mode; +set @@global.debug_dbug= "+d,rows_log_event_after_open_table"; +include/stop_slave.inc +set global slave_exec_mode='IDEMPOTENT'; +include/start_slave.inc +# INSERT on master so it is replicated to slave (where its execution will be blocked after taking locks) +connection master; +INSERT INTO t1 (f2) VALUES (0); +connection slave; +set debug_sync='now WAIT_FOR after_open_table'; +# test.t1 should always be locked with SHARED_WRITE +# test.t2 lock type should be SHARED_WRITE only when slave_exec_mode is IDEMPOTENT. Current mode: IDEMPOTENT +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue_rows_ev'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET @@GLOBAL.slave_exec_mode = @saved_exec_mode; +# +# slave_exec_mode = STRICT +connection slave; +set @saved_dbug = @@global.debug_dbug; +set @saved_exec_mode= @@global.slave_exec_mode; +set @@global.debug_dbug= "+d,rows_log_event_after_open_table"; +include/stop_slave.inc +set global slave_exec_mode='STRICT'; +include/start_slave.inc +# INSERT on master so it is replicated to slave (where its execution will be blocked after taking locks) +connection master; +INSERT INTO t1 (f2) VALUES (0); +connection slave; +set debug_sync='now WAIT_FOR after_open_table'; +# test.t1 should always be locked with SHARED_WRITE +# test.t2 lock type should be SHARED_WRITE only when slave_exec_mode is IDEMPOTENT. Current mode: STRICT +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue_rows_ev'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET @@GLOBAL.slave_exec_mode = @saved_exec_mode; +connection master; +DROP TABLE t2; +DROP TABLE t1; +connection slave; +include/rpl_end.inc +# End of rpl_row_foreign_key_mdl.test diff --git a/mysql-test/suite/rpl/t/rpl_fk_ddl.inc b/mysql-test/suite/rpl/t/rpl_fk_ddl.inc deleted file mode 100644 index d17f6720898..00000000000 --- a/mysql-test/suite/rpl/t/rpl_fk_ddl.inc +++ /dev/null @@ -1,38 +0,0 @@ -# Set slave_exec_mode. -connection slave; -SET @saved_dbug = @@GLOBAL.debug_dbug; ---let $default_fk_slave_exec_mode= `SELECT @@global.slave_exec_mode` - -# Set debug sync point to block parent query on slave. -set @@global.debug_dbug= "+d,sync.rm_table_no_locks"; - ---eval set global slave_exec_mode='$fk_slave_exec_mode' - - -# Execute parent query. -connection master; ---eval $fk_parent_query - - -# Wait for parent query to take mdl lock. ---connection slave -set debug_sync='now WAIT_FOR after_lock_table'; ---let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_parent_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" ---source include/wait_condition.inc - - -# Now execute child query. ---connection master -START TRANSACTION; ---eval $fk_child_query ---let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_child_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" ---source include/wait_condition.inc -COMMIT; - - -# Cleanup -connection slave; -SET DEBUG_SYNC= 'RESET'; -set debug_sync='now SIGNAL continue'; -SET @@GLOBAL.debug_dbug = @saved_dbug; ---eval set global slave_exec_mode='$default_fk_slave_exec_mode' diff --git a/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test b/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test deleted file mode 100644 index 2a5600cc76b..00000000000 --- a/mysql-test/suite/rpl/t/rpl_foreign_key_ddl_insert.test +++ /dev/null @@ -1,114 +0,0 @@ -source include/have_debug_sync.inc; -source include/have_binlog_format_row.inc; -source include/master-slave.inc; - -# 1. For slave_exec_mode=IDEMPOTENT. -# Query executed: INSERT t1 and DROP t2 -connection master; -CREATE TABLE t1 ( - id INTEGER PRIMARY KEY, - f2 INTEGER -); - -CREATE TABLE t2 ( - id INT PRIMARY KEY, - t1_id INT NOT NULL, - f2 INTEGER NOT NULL, - KEY key_t1_id(t1_id), - CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE -); - -INSERT INTO t1 VALUES (1,0); -INSERT INTO t1 VALUES (2,0); -INSERT INTO t2 VALUES (1,1,1234); ---sync_slave_with_master - - ---let $fk_parent_query = DROP TABLE t2 ---let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_slave_exec_mode = IDEMPOTENT ---let $fk_mdl_lock_parent_num = 2 ---let $fk_mdl_lock_child_num = 1 ---source rpl_fk_ddl.inc - - -# -# Verify insert and drop table has succeded. -# ---connection slave ---let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1 ---source include/wait_condition.inc - -select * from t1; ---error ER_NO_SUCH_TABLE -select * from t2; - ---connection master -select * from t1; ---error ER_NO_SUCH_TABLE -select * from t2; - - -# -# Cleanup -# -DROP TABLE t1; ---sync_slave_with_master - - -# 2. For slave_exec_mode=STRICT. -# Query executed: INSERT t1 and DROP t2 -connection master; -CREATE TABLE t1 ( - id INTEGER PRIMARY KEY, - f2 INTEGER -); - -CREATE TABLE t2 ( - id INT PRIMARY KEY, - t1_id INT NOT NULL, - f2 INTEGER NOT NULL, - KEY key_t1_id(t1_id), - CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE -); - -INSERT INTO t1 VALUES (1,0); -INSERT INTO t1 VALUES (2,0); -INSERT INTO t2 VALUES (1,1,1234); ---sync_slave_with_master - - ---let $fk_parent_query = DROP TABLE t2 ---let $fk_child_query = INSERT INTO t1 VALUES (3,0) ---let $fk_slave_exec_mode = STRICT ---let $fk_mdl_lock_parent_num = 2 ---let $fk_mdl_lock_child_num = 1 ---source rpl_fk_ddl.inc - - -# -# Verify insert and drop table has succeded. -# ---connection slave ---let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1 ---source include/wait_condition.inc - -select * from t1; ---error ER_NO_SUCH_TABLE -select * from t2; - ---connection master -select * from t1; ---error ER_NO_SUCH_TABLE -select * from t2; - - -# -# Cleanup -# -DROP TABLE t1; ---sync_slave_with_master - - - ---source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test b/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test deleted file mode 100644 index 50820d99566..00000000000 --- a/mysql-test/suite/rpl/t/rpl_foreign_key_lock_table_insert.test +++ /dev/null @@ -1,130 +0,0 @@ ---source include/have_binlog_format_row.inc ---source include/master-slave.inc ---source include/have_innodb.inc ---source include/have_debug.inc ---source include/have_debug_sync.inc - -connection slave; ---let $default_fk_slave_exec_mode= `SELECT @@global.slave_exec_mode` - -# 1. Set SLAVE_EXEC_MODE as IDEMPOTENT -# and execute INSERT with locked table. -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; - -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; - -CREATE TABLE t2 ( id varchar(100) , a varchar(100), - PRIMARY KEY (id,a), - KEY a (a), - CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; - -CREATE TABLE t3 ( a varchar(100), b varchar(100) , - PRIMARY KEY (a, b), - CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; - -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; - -# Cleanup -DROP TABLE t3, t2, t1; ---sync_slave_with_master - - -# 2. Set SLAVE_EXEC_MODE as STRICT -# and execute INSERT with locked table. -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='STRICT'; - -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; - -CREATE TABLE t2 ( id varchar(100) , a varchar(100), - PRIMARY KEY (id,a), - KEY a (a), - CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; - -CREATE TABLE t3 ( a varchar(100), b varchar(100) , - PRIMARY KEY (a, b), - CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; - -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; - -# Cleanup -DROP TABLE t3, t2, t1; ---sync_slave_with_master - -connection slave; -SET DEBUG_SYNC= 'RESET'; -SET @@GLOBAL.debug_dbug = @saved_dbug; -SET GLOBAL SLAVE_EXEC_MODE=DEFAULT; - -# 3. Set SLAVE_EXEC_MODE as IDEMPOTENT -# and execute INSERT with locked table. -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='IDEMPOTENT'; - -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; - -CREATE TABLE t2 ( id varchar(100) , a varchar(100), - PRIMARY KEY (id,a), - KEY a (a), - CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; - -CREATE TABLE t3 ( a varchar(100), b varchar(100) , - PRIMARY KEY (a, b), - CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; - -FLUSH TABLES WITH READ LOCK; ---error ER_CANT_UPDATE_WITH_READLOCK -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; - -# Cleanup -DROP TABLE t3, t2, t1; ---sync_slave_with_master - - -# 4. Set SLAVE_EXEC_MODE as STRICT -# and execute INSERT with locked table. -connection slave; -SET GLOBAL SLAVE_EXEC_MODE='STRICT'; - -connection master; -CREATE TABLE t1 ( id varchar(100) , PRIMARY KEY (id)) engine=innodb; - -CREATE TABLE t2 ( id varchar(100) , a varchar(100), - PRIMARY KEY (id,a), - KEY a (a), - CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (id) -) ENGINE=InnoDB; - -CREATE TABLE t3 ( a varchar(100), b varchar(100) , - PRIMARY KEY (a, b), - CONSTRAINT FOREIGN KEY (a) REFERENCES t2 (a) -) ENGINE=InnoDB; - -FLUSH TABLES WITH READ LOCK; ---error ER_CANT_UPDATE_WITH_READLOCK -INSERT INTO t1 VALUES ('a'); -UNLOCK TABLES; - -# Cleanup -DROP TABLE t3, t2, t1; ---sync_slave_with_master - -connection slave; ---eval set global slave_exec_mode='$default_fk_slave_exec_mode' - ---source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.inc b/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.inc new file mode 100644 index 00000000000..a7381d92d01 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.inc @@ -0,0 +1,39 @@ +# set slave_exec_mode. +connection slave; +set @saved_dbug = @@global.debug_dbug; +set @saved_exec_mode= @@global.slave_exec_mode; + +# set debug sync point to block parent query on slave. +set @@global.debug_dbug= "+d,rows_log_event_after_open_table"; + +--source include/stop_slave.inc +--eval set global slave_exec_mode='$fk_slave_exec_mode' +--source include/start_slave.inc + +--echo # INSERT on master so it is replicated to slave (where its execution will be blocked after taking locks) +connection master; +INSERT INTO t1 (f2) VALUES (0); + +--connection slave +set debug_sync='now WAIT_FOR after_open_table'; + +--echo # test.t1 should always be locked with SHARED_WRITE +--let $wait_condition = SELECT COUNT(*)=1 FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND OBJECT_NAME='t1' AND LOCK_STATUS='GRANTED' AND LOCK_TYPE='SHARED_WRITE' +--source include/wait_condition.inc + +--let $t2_lock_type= SHARED_READ +if (`SELECT strcmp("$fk_slave_exec_mode", "IDEMPOTENT") = 0`) +{ + --let $t2_lock_type= SHARED_WRITE +} + +--echo # test.t2 lock type should be SHARED_WRITE only when slave_exec_mode is IDEMPOTENT. Current mode: $fk_slave_exec_mode +--let $wait_condition = SELECT COUNT(*)=1 FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND OBJECT_NAME='t2' AND LOCK_STATUS='GRANTED' AND LOCK_TYPE='$t2_lock_type' +--source include/wait_condition.inc + +# Cleanup +connection slave; +SET DEBUG_SYNC= 'RESET'; +set debug_sync='now SIGNAL continue_rows_ev'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET @@GLOBAL.slave_exec_mode = @saved_exec_mode; diff --git a/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.test b/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.test new file mode 100644 index 00000000000..0a5725ece39 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_foreign_key_mdl.test @@ -0,0 +1,55 @@ +# +# Test ensures that MDL locks for foreign keys are taken correctly for Write +# rows log events. That is, when slave_exec_mode=STRICT, MDL locks for only +# target tables are taken. When slave_exec_mode=IDEMPOTENT, MDL locks for +# target tables and tables referenced in foreign keys are taken. +# +# References: +# MDEV-25039: MDL BF-BF conflict because of foreign key +# +source include/have_innodb.inc; +source include/have_debug_sync.inc; +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +--echo # +--echo # Initialize test data +connection master; +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + f2 INTEGER +) engine=innodb; + +CREATE TABLE t2 ( + id INT PRIMARY KEY AUTO_INCREMENT, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +) engine=innodb; + +INSERT INTO t1 (f2) VALUES (0); +INSERT INTO t1 (f2) VALUES (0); +INSERT INTO t2 (t1_id, f2) VALUES (1,1234); +--sync_slave_with_master + +--echo # +--echo # slave_exec_mode = IDEMPOTENT +--let $fk_slave_exec_mode = IDEMPOTENT +--source rpl_row_foreign_key_mdl.inc + +--echo # +--echo # slave_exec_mode = STRICT +--let $fk_slave_exec_mode = STRICT +--source rpl_row_foreign_key_mdl.inc + +# +# Cleanup +# +--connection master +DROP TABLE t2; +DROP TABLE t1; +--sync_slave_with_master + +--source include/rpl_end.inc +--echo # End of rpl_row_foreign_key_mdl.test diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 5beccb1e88c..53216ff6a4a 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -6005,6 +6005,12 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) goto err; } + DBUG_EXECUTE_IF("rows_log_event_after_open_table", { + const char action[]= + "now SIGNAL after_open_table WAIT_FOR continue_rows_ev"; + DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(action))); + };); + /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f732247d7e4..452ca09b31e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1555,13 +1555,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); - DBUG_EXECUTE_IF("sync.rm_table_no_locks", - { - const char action[] = "now SIGNAL after_lock_table" - " WAIT_FOR continue"; - DBUG_ASSERT(!debug_sync_set_action(thd, - STRING_WITH_LEN(action))); - };); if (drop_temporary) { /* "DROP TEMPORARY" but a temporary table was not found */ From 9749d71f9527822a2a16f0a900f7d06e4889ec7e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 30 Jan 2026 11:48:21 +0100 Subject: [PATCH 152/152] MDEV-38709 ASAN heap-buffer-overflow in my_convert_using_func Don't forget up to update stored_rec_length when extending temp table reclength. Followup for 4f9a13e9ecf2 --- mysql-test/main/group_by.result | 37 +++++++++++++-- mysql-test/main/group_by.test | 80 +++++++++++++++++++++------------ sql/sql_select.cc | 2 +- 3 files changed, 87 insertions(+), 32 deletions(-) diff --git a/mysql-test/main/group_by.result b/mysql-test/main/group_by.result index 1a6a30919f7..57a3cf97e94 100644 --- a/mysql-test/main/group_by.result +++ b/mysql-test/main/group_by.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); ERROR HY000: Invalid use of group function CREATE TABLE t1 ( @@ -3089,10 +3088,8 @@ EXPLAIN } } DROP TABLE t1,t2; -# # End of 10.5 tests # -# # Test new group_min_max optimization # create table t1 (a int, b int, c int, key(a,b,c)); @@ -3123,3 +3120,37 @@ explain select a from t1 where a in (1,2,3) and c=1 group by a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 1161 Using where; Using index drop table t1; +# End of 11.4 tests +# +# MDEV-38709 ASAN heap-buffer-overflow in my_convert_using_func +# +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES +('LOXRI'),('willing'),('bright'),('behavior'),('RUQIW'),('z'),('RFRYY'), +('KQFQA'),('b'),('ZKUAX'),('l'),('z'),('t-shirt'),('o'),('o'),('c'),('MOUYN'), +('v'),('precise'),('QCOHK'),('c'),('any'),('hers'),('e'),('we'),('mood'), +('AVBWK'),('h'),('frequent'),('AUZDU'),('z'),('sculpture'),('passion'),('n'), +('b'),('sodium'),('j'),('power'),('y'),('CHJYX'),('YYULQ'),('h'),('HRMPR'), +('p'),('a'),('r'),('m'),('s'),('different'),('QABLI'),('s'),('p'),('train'), +('cause'),('MYEFD'),('fierce'),('r'),('l'),('x'),('monthly'),('x'),('t'), +('RQWBD'),('panic'),('HDRLD'),('m'),('j'),('r'),('convert'),('simple'),('y'), +('b'),('f'),('flip'),('l'),('desire'),('film'); +CREATE TABLE t2 (b varchar(1024)); +INSERT INTO t2 VALUES +('c'),('BPYFY'),('i'),('l'),('n'),('programming'),('r'),('then'),('t'), +('MVAUI'),('XQGSK'),('i'),('regret'),('m'),('XIDWZ'),('KORLB'),('agree'), +('relatively'),('frequency'),('certainly'); +SELECT a, b AS b1, b AS b2 FROM t1 JOIN t2 WHERE a IS NOT NULL GROUP BY a, b1, b2 LIMIT 1000,10; +a b1 b2 +v r r +v regret regret +v relatively relatively +v t t +v then then +v XIDWZ XIDWZ +v XQGSK XQGSK +we agree agree +we BPYFY BPYFY +we c c +DROP TABLE t1, t2; +# End of 11.8 tests diff --git a/mysql-test/main/group_by.test b/mysql-test/main/group_by.test index 15278780df9..dd8185bbf21 100644 --- a/mysql-test/main/group_by.test +++ b/mysql-test/main/group_by.test @@ -1,14 +1,9 @@ --source include/have_sequence.inc -# Initialise ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - # # Simple test without tables --- error 1111 +--error ER_INVALID_GROUP_FUNC_USE SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); # @@ -83,7 +78,7 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6); ---error 1056 +--error ER_WRONG_GROUP_FIELD SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew; drop table t1; @@ -825,12 +820,12 @@ SET SQL_MODE = ''; # SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; create table t1(f1 int, f2 int); ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select * from t1 group by f1; ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select * from t1 group by f2; select * from t1 group by f1, f2; ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select t1.f1,t.* from t1, t1 t group by 1; drop table t1; SET SQL_MODE = ''; @@ -882,49 +877,49 @@ CREATE TABLE t2 SELECT * FROM t1; SELECT 1 FROM t1 ORDER BY COUNT(*); SELECT 1 FROM t1 ORDER BY COUNT(*) + 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY COUNT(*) + a; SELECT 1 FROM t1 ORDER BY COUNT(*), 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY COUNT(*), a; SELECT 1 FROM t1 ORDER BY SUM(a); SELECT 1 FROM t1 ORDER BY SUM(a + 1); SELECT 1 FROM t1 ORDER BY SUM(a) + 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY SUM(a), b; --disable_service_connection ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT a FROM t1 ORDER BY COUNT(b); SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a) FROM t2); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a), t2.a FROM t2); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a) FROM t2 ORDER BY t2.a); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT t2.a FROM t2 ORDER BY SUM(t2.b) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 WHERE t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t2.b) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t2.a) LIMIT 1); SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a IN (SELECT t2.a FROM t2 ORDER BY SUM(t1.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a IN (SELECT t2.a FROM t2 ORDER BY t2.a, SUM(t2.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > ANY (SELECT t2.a FROM t2 ORDER BY t2.a, SUM(t2.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 WHERE t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t1.b)); @@ -935,13 +930,13 @@ SELECT 1 FROM t1 GROUP BY t1.a SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(t1.b + t2.b) FROM t2 ORDER BY SUM(t2.a) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(SUM(t1.b) + 1) FROM t2 ORDER BY t2.a LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(SUM(t1.b) + t2.b) FROM t2 ORDER BY t2.a LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(t1.b + t2.b) FROM t2 ORDER BY t2.a LIMIT 1); @@ -981,7 +976,7 @@ from t1 as most_outer; --disable_service_connection ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS select avg ( (select ( (select sum(outr.a + innr.a) from t1 as innr limit 1)) as tt @@ -2184,9 +2179,7 @@ explain format=json SELECT 1+0, MIN(t1.a) FROM t1,t2 WHERE t2.a = rand(); DROP TABLE t1,t2; ---echo # --echo # End of 10.5 tests ---echo # --echo # --echo # Test new group_min_max optimization @@ -2206,3 +2199,34 @@ explain select a,b,c from t1 where (a,b) in ((1,1),(2,2),(3,3)) and c=3 group by explain select a from t1 where a in (1,2,3) and b>1 group by a; explain select a from t1 where a in (1,2,3) and c=1 group by a; drop table t1; + +--echo # End of 11.4 tests + +--echo # +--echo # MDEV-38709 ASAN heap-buffer-overflow in my_convert_using_func +--echo # +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES +('LOXRI'),('willing'),('bright'),('behavior'),('RUQIW'),('z'),('RFRYY'), +('KQFQA'),('b'),('ZKUAX'),('l'),('z'),('t-shirt'),('o'),('o'),('c'),('MOUYN'), +('v'),('precise'),('QCOHK'),('c'),('any'),('hers'),('e'),('we'),('mood'), +('AVBWK'),('h'),('frequent'),('AUZDU'),('z'),('sculpture'),('passion'),('n'), +('b'),('sodium'),('j'),('power'),('y'),('CHJYX'),('YYULQ'),('h'),('HRMPR'), +('p'),('a'),('r'),('m'),('s'),('different'),('QABLI'),('s'),('p'),('train'), +('cause'),('MYEFD'),('fierce'),('r'),('l'),('x'),('monthly'),('x'),('t'), +('RQWBD'),('panic'),('HDRLD'),('m'),('j'),('r'),('convert'),('simple'),('y'), +('b'),('f'),('flip'),('l'),('desire'),('film'); + +CREATE TABLE t2 (b varchar(1024)); +INSERT INTO t2 VALUES +('c'),('BPYFY'),('i'),('l'),('n'),('programming'),('r'),('then'),('t'), +('MVAUI'),('XQGSK'),('i'),('regret'),('m'),('XIDWZ'),('KORLB'),('agree'), +('relatively'),('frequency'),('certainly'); + +SELECT a, b AS b1, b AS b2 FROM t1 JOIN t2 WHERE a IS NOT NULL GROUP BY a, b1, b2 LIMIT 1000,10; + +DROP TABLE t1, t2; + +--echo # End of 11.8 tests + + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5ae50a10537..1964de0d80d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -23154,7 +23154,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *org_keyinfo, bzero(table->record[0]+ share->reclength, MARIA_UNIQUE_HASH_LENGTH); bzero(share->default_values+ share->reclength, MARIA_UNIQUE_HASH_LENGTH); - share->reclength+= MARIA_UNIQUE_HASH_LENGTH; + share->stored_rec_length= share->reclength+= MARIA_UNIQUE_HASH_LENGTH; } else {