summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-08-24 09:22:34 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-08-24 09:22:34 +0300
commitbdd80e3fb1cb653c367099639bec46840eca86e1 (patch)
treeab3d208ab5102d7f7db1b222a7a4531012a0ebcd
parentdc11fd07fdaf7316d340569f97a84fa0fd2d307e (diff)
parent5b4c832c7ebd59d9f5a5e7feef570568e20e5b86 (diff)
downloadmariadb-git-bdd80e3fb1cb653c367099639bec46840eca86e1.tar.gz
Merge 10.6 into 10.7
-rw-r--r--cmake/os/Darwin.cmake16
-rw-r--r--cmake/os/WindowsCache.cmake1
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake8
-rw-r--r--extra/mariabackup/ds_compress.cc51
-rw-r--r--extra/mariabackup/xtrabackup.cc4
-rw-r--r--include/aligned.h5
-rw-r--r--mysql-test/main/func_json.result44
-rw-r--r--mysql-test/main/func_json.test30
-rw-r--r--mysql-test/main/timezone2.result22
-rw-r--r--mysql-test/main/timezone2.test15
-rw-r--r--mysql-test/suite/innodb/r/change_column_collation.result14
-rw-r--r--mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff12
-rw-r--r--mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff12
-rw-r--r--mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff12
-rw-r--r--mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff12
-rw-r--r--mysql-test/suite/innodb/r/check_ibd_filesize.result4
-rw-r--r--mysql-test/suite/innodb/t/change_column_collation.test10
-rw-r--r--mysql-test/suite/innodb/t/temporary_table.test1
-rw-r--r--mysql-test/suite/innodb_zip/r/wl6347_comp_indx_stat.result20
-rw-r--r--mysql-test/suite/mariabackup/compress_qpress.test4
-rw-r--r--mysql-test/suite/mariabackup/log_page_corruption.result24
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.result16
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.test11
-rw-r--r--sql/item_jsonfunc.cc18
-rw-r--r--sql/sql_class.cc80
-rw-r--r--sql/sql_class.h2
-rw-r--r--storage/innobase/btr/btr0btr.cc52
-rw-r--r--storage/innobase/btr/btr0cur.cc6
-rw-r--r--storage/innobase/btr/btr0sea.cc39
-rw-r--r--storage/innobase/buf/buf0buf.cc12
-rw-r--r--storage/innobase/buf/buf0flu.cc10
-rw-r--r--storage/innobase/dict/dict0dict.cc31
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc44
-rw-r--r--storage/innobase/include/btr0sea.h18
-rw-r--r--storage/innobase/include/dict0dict.h2
-rw-r--r--storage/innobase/include/dict0mem.h2
-rw-r--r--storage/innobase/include/mtr0mtr.h13
-rw-r--r--storage/innobase/log/log0recv.cc27
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc23
-rw-r--r--storage/innobase/row/row0purge.cc3
-rw-r--r--storage/innobase/trx/trx0rseg.cc7
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result38
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_29008.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test39
-rw-r--r--storage/spider/spd_db_conn.cc4
46 files changed, 627 insertions, 195 deletions
diff --git a/cmake/os/Darwin.cmake b/cmake/os/Darwin.cmake
deleted file mode 100644
index 21e18360dfe..00000000000
--- a/cmake/os/Darwin.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
-#
-# 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
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
-
-# This file includes OSX specific options and quirks, related to system checks
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake
index 923ec371609..a5f808c8d2c 100644
--- a/cmake/os/WindowsCache.cmake
+++ b/cmake/os/WindowsCache.cmake
@@ -23,7 +23,6 @@ IF(MSVC)
SET(BFD_H_EXISTS 0 CACHE INTERNAL "")
SET(HAVE_ACCESS 1 CACHE INTERNAL "")
SET(HAVE_ALARM CACHE INTERNAL "")
-SET(HAVE_ALIGNED_ALLOC CACHE INTERNAL "")
SET(HAVE_ALLOCA_H CACHE INTERNAL "")
SET(HAVE_ARPA_INET_H CACHE INTERNAL "")
SET(HAVE_BACKTRACE CACHE INTERNAL "")
diff --git a/config.h.cmake b/config.h.cmake
index 46d7b209246..cdacac164af 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -19,7 +19,6 @@
/* Headers we may want to use. */
#cmakedefine STDC_HEADERS 1
#cmakedefine _GNU_SOURCE 1
-#cmakedefine HAVE_ALIGNED_ALLOC 1
#cmakedefine HAVE_ALLOCA_H 1
#cmakedefine HAVE_ARPA_INET_H 1
#cmakedefine HAVE_ASM_TERMBITS_H 1
diff --git a/configure.cmake b/configure.cmake
index 98bc2ad73c0..46da0363689 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -326,14 +326,6 @@ ENDIF()
CHECK_FUNCTION_EXISTS (accept4 HAVE_ACCEPT4)
CHECK_FUNCTION_EXISTS (access HAVE_ACCESS)
CHECK_FUNCTION_EXISTS (alarm HAVE_ALARM)
-IF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT WITH_ASAN)
- # When an old custom memory allocator library is used, aligned_alloc()
- # could invoke the built-in allocator in libc, not matching
- # the overriden free() in the custom memory allocator.
- SET(HAVE_ALIGNED_ALLOC 0)
-ELSE()
- CHECK_FUNCTION_EXISTS (aligned_alloc HAVE_ALIGNED_ALLOC)
-ENDIF()
SET(HAVE_ALLOCA 1)
CHECK_FUNCTION_EXISTS (backtrace HAVE_BACKTRACE)
CHECK_FUNCTION_EXISTS (backtrace_symbols HAVE_BACKTRACE_SYMBOLS)
diff --git a/extra/mariabackup/ds_compress.cc b/extra/mariabackup/ds_compress.cc
index 64f342df462..f7a9b7a1fbd 100644
--- a/extra/mariabackup/ds_compress.cc
+++ b/extra/mariabackup/ds_compress.cc
@@ -34,9 +34,10 @@ typedef struct {
pthread_t id;
uint num;
pthread_mutex_t data_mutex;
+ pthread_cond_t avail_cond;
pthread_cond_t data_cond;
pthread_cond_t done_cond;
- my_bool data_avail;
+ pthread_t data_avail;
my_bool cancelled;
const char *from;
size_t from_len;
@@ -195,9 +196,13 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
threads = comp_ctxt->threads;
nthreads = comp_ctxt->nthreads;
+ const pthread_t self = pthread_self();
+
ptr = (const char *) buf;
while (len > 0) {
- uint max_thread;
+ bool wait = nthreads == 1;
+retry:
+ bool submitted = false;
/* Send data to worker threads for compression */
for (i = 0; i < nthreads; i++) {
@@ -206,16 +211,33 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
thd = threads + i;
pthread_mutex_lock(&thd->data_mutex);
+ if (thd->data_avail == pthread_t(~0UL)) {
+ } else if (!wait) {
+skip:
+ pthread_mutex_unlock(&thd->data_mutex);
+ continue;
+ } else {
+ for (;;) {
+ pthread_cond_wait(&thd->avail_cond,
+ &thd->data_mutex);
+ if (thd->data_avail
+ == pthread_t(~0UL)) {
+ break;
+ }
+ goto skip;
+ }
+ }
chunk_len = (len > COMPRESS_CHUNK_SIZE) ?
COMPRESS_CHUNK_SIZE : len;
thd->from = ptr;
thd->from_len = chunk_len;
- thd->data_avail = TRUE;
+ thd->data_avail = self;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
+ submitted = true;
len -= chunk_len;
if (len == 0) {
break;
@@ -223,13 +245,20 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
ptr += chunk_len;
}
- max_thread = (i < nthreads) ? i : nthreads - 1;
+ if (!submitted) {
+ wait = true;
+ goto retry;
+ }
- /* Reap and stream the compressed data */
- for (i = 0; i <= max_thread; i++) {
+ for (i = 0; i < nthreads; i++) {
thd = threads + i;
pthread_mutex_lock(&thd->data_mutex);
+ if (thd->data_avail != self) {
+ pthread_mutex_unlock(&thd->data_mutex);
+ continue;
+ }
+
while (!thd->to_len) {
pthread_cond_wait(&thd->done_cond,
&thd->data_mutex);
@@ -247,6 +276,8 @@ compress_write(ds_file_t *file, const uchar *buf, size_t len)
}
thd->to_len = 0;
+ thd->data_avail = pthread_t(~0UL);
+ pthread_cond_signal(&thd->avail_cond);
pthread_mutex_unlock(&thd->data_mutex);
if (fail) {
@@ -334,6 +365,7 @@ destroy_worker_thread(comp_thread_ctxt_t *thd)
pthread_join(thd->id, NULL);
+ pthread_cond_destroy(&thd->avail_cond);
pthread_cond_destroy(&thd->data_cond);
pthread_cond_destroy(&thd->done_cond);
pthread_mutex_destroy(&thd->data_mutex);
@@ -364,11 +396,14 @@ create_worker_threads(uint n)
/* Initialize and data mutex and condition var */
if (pthread_mutex_init(&thd->data_mutex, NULL) ||
+ pthread_cond_init(&thd->avail_cond, NULL) ||
pthread_cond_init(&thd->data_cond, NULL) ||
pthread_cond_init(&thd->done_cond, NULL)) {
goto err;
}
+ thd->data_avail = pthread_t(~0UL);
+
if (pthread_create(&thd->id, NULL, compress_worker_thread_func,
thd)) {
msg("compress: pthread_create() failed: "
@@ -410,13 +445,13 @@ compress_worker_thread_func(void *arg)
pthread_mutex_lock(&thd->data_mutex);
while (1) {
- while (!thd->data_avail && !thd->cancelled) {
+ while (!thd->cancelled
+ && (thd->to_len || thd->data_avail == pthread_t(~0UL))) {
pthread_cond_wait(&thd->data_cond, &thd->data_mutex);
}
if (thd->cancelled)
break;
- thd->data_avail = FALSE;
thd->to_len = qlz_compress(thd->from, thd->to, thd->from_len,
&thd->state);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index f6681fa148d..da32b243ec0 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -2478,11 +2478,11 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info)
/* ================= backup ================= */
void xtrabackup_io_throttling()
{
- if (!xtrabackup_backup)
+ if (!xtrabackup_backup || !xtrabackup_throttle)
return;
mysql_mutex_lock(&log_sys.mutex);
- if (xtrabackup_throttle && (io_ticket--) < 0)
+ if (io_ticket-- < 0)
mysql_cond_wait(&wait_throttle, &log_sys.mutex);
mysql_mutex_unlock(&log_sys.mutex);
}
diff --git a/include/aligned.h b/include/aligned.h
index 0ae1f0d0848..81bd5d3f6f7 100644
--- a/include/aligned.h
+++ b/include/aligned.h
@@ -14,8 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
-#ifdef HAVE_ALIGNED_ALLOC
-#elif defined __linux__
+#if defined __linux__
# include <malloc.h>
#endif
@@ -23,8 +22,6 @@ inline void *aligned_malloc(size_t size, size_t alignment)
{
#ifdef _WIN32
return _aligned_malloc(size, alignment);
-#elif defined HAVE_ALIGNED_ALLOC
- return aligned_alloc(alignment, size);
#elif defined __linux__
return memalign(alignment, size);
#else
diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result
index cb5d8b4efdc..7b92544ee13 100644
--- a/mysql-test/main/func_json.result
+++ b/mysql-test/main/func_json.result
@@ -822,7 +822,7 @@ CREATE TABLE t2 SELECT JSON_ARRAY_INSERT(fld, '$.[0]', '0') FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
- `JSON_ARRAY_INSERT(fld, '$.[0]', '0')` varchar(25) DEFAULT NULL
+ `JSON_ARRAY_INSERT(fld, '$.[0]', '0')` varchar(21) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
SET sql_mode=default;
@@ -1016,6 +1016,33 @@ j
{"ID": "4", "Name": "Betty", "Age": 19}
drop table t1;
#
+# MDEV-27151: JSON_VALUE() does not parse NULL properties properly
+#
+#
+# It is correct for JSON_EXTRACT() to give null instead of "NULL" because
+# it returns the json literal that is put inside json.
+# Hence it should return null as in 'null' string and not SQL NULL.
+# JSON_VALUE() returns the "VALUE" so it is correct for it to return SQl NULL
+#
+SELECT NULL;
+NULL
+NULL
+SELECT JSON_VALUE('{"nulltest": null}', '$.nulltest');
+JSON_VALUE('{"nulltest": null}', '$.nulltest')
+NULL
+SELECT 1 + NULL;
+1 + NULL
+NULL
+SELECT 1 + JSON_VALUE('{"nulltest": null}', '$.nulltest');
+1 + JSON_VALUE('{"nulltest": null}', '$.nulltest')
+NULL
+SELECT NULL;
+NULL
+NULL
+SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a');
+JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a')
+null
+#
# End of 10.3 tests
#
#
@@ -1437,5 +1464,20 @@ f
DROP VIEW v;
DROP TABLE t;
#
+# MDEV-29264 JSON functions overflow error based ON LONGTEXT field
+#
+CREATE TABLE t(l1 LONGTEXT, l2 LONGTEXT, l3 LONGTEXT, l4 LONGTEXT);
+INSERT INTO t VALUES('k1', 'v1', 'k2', 'v2');
+SELECT JSON_ARRAY(l1, l2, l3, l4), JSON_OBJECT(l1, l2, l3, l4) from t;
+JSON_ARRAY(l1, l2, l3, l4) JSON_OBJECT(l1, l2, l3, l4)
+["k1", "v1", "k2", "v2"] {"k1": "v1", "k2": "v2"}
+SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') from t;
+JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3')
+[["k1", "k3"], "v1", "k2", "v2"] ["k3", "k1", "v1", "k2", "v2"]
+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;
+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')
+{"k1": "v1", "k2": "v2", "k3": "v3"} {"k1": "v1", "k2": "new v2"} {"k1": "v1", "k2": "new v2"}
+DROP TABLE t;
+#
# End of 10.5 tests
#
diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test
index dd7e23c0674..83f4bf9d1ad 100644
--- a/mysql-test/main/func_json.test
+++ b/mysql-test/main/func_json.test
@@ -628,6 +628,25 @@ SELECT * FROM t1 WHERE JSON_EXTRACT(j, '$.Age')=19;
drop table t1;
--echo #
+--echo # MDEV-27151: JSON_VALUE() does not parse NULL properties properly
+--echo #
+--echo #
+--echo # It is correct for JSON_EXTRACT() to give null instead of "NULL" because
+--echo # it returns the json literal that is put inside json.
+--echo # Hence it should return null as in 'null' string and not SQL NULL.
+--echo # JSON_VALUE() returns the "VALUE" so it is correct for it to return SQl NULL
+--echo #
+
+SELECT NULL;
+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 # End of 10.3 tests
--echo #
@@ -927,6 +946,17 @@ SELECT JSON_ARRAYAGG(a) AS f FROM v;
DROP VIEW v;
DROP TABLE t;
+
+--echo #
+--echo # MDEV-29264 JSON functions overflow error based ON LONGTEXT field
+--echo #
+CREATE TABLE t(l1 LONGTEXT, l2 LONGTEXT, l3 LONGTEXT, l4 LONGTEXT);
+INSERT INTO t VALUES('k1', 'v1', 'k2', 'v2');
+SELECT JSON_ARRAY(l1, l2, l3, l4), JSON_OBJECT(l1, l2, l3, l4) from t;
+SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') from t;
+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 # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result
index f943e285951..806255f26f5 100644
--- a/mysql-test/main/timezone2.result
+++ b/mysql-test/main/timezone2.result
@@ -654,3 +654,25 @@ SET time_zone=DEFAULT;
#
# End of 10.4 tests
#
+#
+# MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
+#
+SET time_zone='Europe/Moscow';
+CREATE TABLE t1 (a TIMESTAMP NULL);
+SET timestamp=1288477526;
+/* this is summer time, earlier */
+INSERT INTO t1 VALUES (NOW());
+SET timestamp=1288477526+3599;
+/* this is winter time, later */
+INSERT INTO t1 VALUES (NOW());
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+a UNIX_TIMESTAMP(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:25 1288481125
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
+a UNIX_TIMESTAMP(a)
+2010-10-31 02:25:26 1288477526
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
+a UNIX_TIMESTAMP(a)
+2010-10-31 02:25:25 1288481125
+DROP TABLE t1;
diff --git a/mysql-test/main/timezone2.test b/mysql-test/main/timezone2.test
index 6a8c9f258e4..1feb8916871 100644
--- a/mysql-test/main/timezone2.test
+++ b/mysql-test/main/timezone2.test
@@ -598,3 +598,18 @@ SET time_zone=DEFAULT;
--echo #
--echo # End of 10.4 tests
--echo #
+
+--echo #
+--echo # MDEV-27101 Subquery using the ALL keyword on TIMESTAMP columns produces a wrong result
+--echo #
+
+SET time_zone='Europe/Moscow';
+CREATE TABLE t1 (a TIMESTAMP NULL);
+SET timestamp=1288477526; /* this is summer time, earlier */
+INSERT INTO t1 VALUES (NOW());
+SET timestamp=1288477526+3599; /* this is winter time, later */
+INSERT INTO t1 VALUES (NOW());
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a <= ALL (SELECT * FROM t1);
+SELECT a, UNIX_TIMESTAMP(a) FROM t1 WHERE a >= ALL (SELECT * FROM t1);
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/change_column_collation.result b/mysql-test/suite/innodb/r/change_column_collation.result
index b1771b2bd00..94dfa77bbd0 100644
--- a/mysql-test/suite/innodb/r/change_column_collation.result
+++ b/mysql-test/suite/innodb/r/change_column_collation.result
@@ -95,3 +95,17 @@ ALTER TABLE t1 MODIFY msg_2 VARCHAR(100) CHARACTER SET utf8
COLLATE utf8_unicode_ci, ALGORITHM=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
DROP TABLE t1;
+#
+# MDEV-29314 Assertion `n_fields > n_cols' failed
+# in dict_index_t::init_change_cols
+#
+CREATE TABLE t (a VARCHAR(16) COLLATE utf8_bin,
+FULLTEXT (a)) ENGINE=InnoDB COLLATE utf8_unicode_520_ci;
+ALTER TABLE t MODIFY COLUMN a VARCHAR(512);
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` varchar(512) COLLATE utf8mb3_unicode_520_ci DEFAULT NULL,
+ FULLTEXT KEY `a` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_520_ci
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff
index 6cf0fdf4159..44446602b9f 100644
--- a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff
+++ b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff
@@ -1,18 +1,18 @@
---- check_ibd_filesize.result
-+++ check_ibd_filesize.result,32k
+--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530
++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:29:25.129637040 +0530
@@ -3,18 +3,12 @@
# SPACE IN 5.7 THAN IN 5.6
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 196608
+-# bytes: 65536
++# bytes: 131072
INSERT INTO t1 SELECT * FROM seq_1_to_25000;
-# bytes: 9437184
+# bytes: 786432
DROP TABLE t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 196608
+-# bytes: 65536
++# bytes: 131072
INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20;
-# bytes: 4194304
-DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff
index 52cd6832755..ef55ad971fe 100644
--- a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff
+++ b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff
@@ -1,17 +1,17 @@
---- check_ibd_filesize.result
-+++ check_ibd_filesize.result,4k
+--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530
++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:39.288769153 +0530
@@ -3,18 +3,18 @@
# SPACE IN 5.7 THAN IN 5.6
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 24576
+-# bytes: 65536
++# bytes: 16384
INSERT INTO t1 SELECT * FROM seq_1_to_25000;
# bytes: 9437184
DROP TABLE t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 24576
+-# bytes: 65536
++# bytes: 16384
INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20;
# bytes: 4194304
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff
index 23d9fbe608f..bcdcea31160 100644
--- a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff
+++ b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff
@@ -1,18 +1,18 @@
---- check_ibd_filesize.result
-+++ check_ibd_filesize.result,64k
+--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530
++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:30:28.957174270 +0530
@@ -3,18 +3,12 @@
# SPACE IN 5.7 THAN IN 5.6
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 393216
+-# bytes: 65536
++# bytes: 262144
INSERT INTO t1 SELECT * FROM seq_1_to_25000;
-# bytes: 9437184
+# bytes: 983040
DROP TABLE t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 393216
+-# bytes: 65536
++# bytes: 262144
INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20;
-# bytes: 4194304
-DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff
index 17936a3def9..7b699ef4cea 100644
--- a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff
+++ b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff
@@ -1,17 +1,17 @@
---- check_ibd_filesize.result
-+++ check_ibd_filesize.result,8k
+--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530
++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:03.516962339 +0530
@@ -3,18 +3,18 @@
# SPACE IN 5.7 THAN IN 5.6
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 49152
+-# bytes: 65536
++# bytes: 32768
INSERT INTO t1 SELECT * FROM seq_1_to_25000;
# bytes: 9437184
DROP TABLE t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB;
--# bytes: 98304
-+# bytes: 49152
+-# bytes: 65536
++# bytes: 32768
INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20;
# bytes: 4194304
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize.result b/mysql-test/suite/innodb/r/check_ibd_filesize.result
index a6f5fbd9387..0d224d6ac5f 100644
--- a/mysql-test/suite/innodb/r/check_ibd_filesize.result
+++ b/mysql-test/suite/innodb/r/check_ibd_filesize.result
@@ -3,12 +3,12 @@
# SPACE IN 5.7 THAN IN 5.6
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
-# bytes: 98304
+# bytes: 65536
INSERT INTO t1 SELECT * FROM seq_1_to_25000;
# bytes: 9437184
DROP TABLE t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB;
-# bytes: 98304
+# bytes: 65536
INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20;
# bytes: 4194304
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/change_column_collation.test b/mysql-test/suite/innodb/t/change_column_collation.test
index f63d1974c72..9b811830d3f 100644
--- a/mysql-test/suite/innodb/t/change_column_collation.test
+++ b/mysql-test/suite/innodb/t/change_column_collation.test
@@ -122,4 +122,14 @@ ALTER TABLE t1 MODIFY msg_2 VARCHAR(100) CHARACTER SET utf8
COLLATE utf8_unicode_ci, ALGORITHM=inplace;
DROP TABLE t1;
+--echo #
+--echo # MDEV-29314 Assertion `n_fields > n_cols' failed
+--echo # in dict_index_t::init_change_cols
+--echo #
+CREATE TABLE t (a VARCHAR(16) COLLATE utf8_bin,
+ FULLTEXT (a)) ENGINE=InnoDB COLLATE utf8_unicode_520_ci;
+ALTER TABLE t MODIFY COLUMN a VARCHAR(512);
+SHOW CREATE TABLE t;
+DROP TABLE t;
+
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test
index 594ab95ef58..e59f51623b7 100644
--- a/mysql-test/suite/innodb/t/temporary_table.test
+++ b/mysql-test/suite/innodb/t/temporary_table.test
@@ -5,6 +5,7 @@
#
--source include/have_innodb.inc
+--source include/innodb_page_size.inc
# Embedded server does not restart of server
--source include/not_embedded.inc
--source include/no_valgrind_without_big.inc
diff --git a/mysql-test/suite/innodb_zip/r/wl6347_comp_indx_stat.result b/mysql-test/suite/innodb_zip/r/wl6347_comp_indx_stat.result
index ad1c1141a20..05b4793eb4d 100644
--- a/mysql-test/suite/innodb_zip/r/wl6347_comp_indx_stat.result
+++ b/mysql-test/suite/innodb_zip/r/wl6347_comp_indx_stat.result
@@ -1024,7 +1024,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 122880
+The size of the tab5.ibd file: 106496
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -1331,7 +1331,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 245760
+The size of the tab5.ibd file: 212992
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -2637,7 +2637,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 122880
+The size of the tab5.ibd file: 106496
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -2946,7 +2946,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 245760
+The size of the tab5.ibd file: 212992
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -4151,7 +4151,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 122880
+The size of the tab5.ibd file: 106496
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -4439,7 +4439,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 245760
+The size of the tab5.ibd file: 212992
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -5697,7 +5697,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 122880
+The size of the tab5.ibd file: 106496
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -6004,7 +6004,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 245760
+The size of the tab5.ibd file: 212992
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -7288,7 +7288,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 122880
+The size of the tab5.ibd file: 106496
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
@@ -7595,7 +7595,7 @@ AND compress_ops BETWEEN @inl_val AND 1000
AND table_name='tab5' AND database_name='test'
AND index_name like 'idx%' ;
compress_stat 1
-The size of the tab5.ibd file: 245760
+The size of the tab5.ibd file: 212992
# for determintic resons simple data should be inserted.
# insert some 100 records
# Load the data
diff --git a/mysql-test/suite/mariabackup/compress_qpress.test b/mysql-test/suite/mariabackup/compress_qpress.test
index f86efe44e5d..c7762f8e55e 100644
--- a/mysql-test/suite/mariabackup/compress_qpress.test
+++ b/mysql-test/suite/mariabackup/compress_qpress.test
@@ -12,6 +12,10 @@ INSERT INTO t VALUES(2);
echo # xtrabackup prepare;
--disable_result_log
+# Because MDEV-24626 in 10.6 optimized file creation, we could end up with
+# t.new.qp instead of t.ibd.qp unless a log checkpoint happened to be
+# triggered between CREATE TABLE and the backup run.
+--replace_result t.new t.ibd
list_files $targetdir/test *.qp;
exec $XTRABACKUP --decompress --remove-original --target-dir=$targetdir;
list_files $targetdir/test *.qp;
diff --git a/mysql-test/suite/mariabackup/log_page_corruption.result b/mysql-test/suite/mariabackup/log_page_corruption.result
index 4dcd21f1e2f..f2a88ea4bdf 100644
--- a/mysql-test/suite/mariabackup/log_page_corruption.result
+++ b/mysql-test/suite/mariabackup/log_page_corruption.result
@@ -31,13 +31,13 @@ FOUND 1 /Database page corruption detected.*/ in backup.log
FOUND 1 /completed OK!/ in backup.log
--- "innodb_corrupted_pages" file content: ---
test/t1_corrupted
-6 8 9
+4 6 7
test/t2_corrupted
-7 8 10
+5 6 8
test/t4_corrupted_new
1
test/t5_corrupted_to_rename_renamed
-6
+4
test/t7_corrupted_to_alter
3
------
@@ -48,19 +48,19 @@ INSERT INTO t3_inc VALUES (3), (4), (5), (6), (7), (8), (9);
# Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option
--- "innodb_corrupted_pages" file content: ---
test/t1_corrupted
-6 8 9
+4 6 7
test/t1_inc_corrupted
-6 8 9
+4 6 7
test/t2_corrupted
-7 8 10
+5 6 8
test/t2_inc_corrupted
-7 8 10
+5 6 8
test/t4_inc_corrupted_new
1
test/t5_corrupted_to_rename_renamed
-6
+4
test/t5_inc_corrupted_to_rename_renamed
-6
+4
test/t7_inc_corrupted_to_alter
3
------
@@ -85,16 +85,16 @@ DROP TABLE t7_inc_corrupted_to_alter;
# Full backup with --log-innodb-page-corruption
--- "innodb_corrupted_pages" file content: ---
test/t3
-6 8
+4 6
------
# Extend some tablespace and corrupt extended pages for incremental backup
# restart
# Incremental backup --log-innodb-page-corruption
--- "innodb_corrupted_pages" file content: ---
test/t3
-6 8
+4 6
test/t3_inc
-6 8
+4 6
------
# Full backup prepare
# "innodb_corrupted_pages" file must not exist after successful prepare
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result
index cfb9189ea28..6d00e1771cc 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result
@@ -2214,6 +2214,22 @@ id name
DROP TABLE divisions;
DROP TABLE companies;
#
+# MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
+#
+CREATE TABLE t1 (d INET6);
+INSERT INTO t1 VALUES ('1::0'), ('12::0');
+SELECT * FROM t1 ORDER BY d;
+d
+1::
+12::
+SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
+d
+1::
+SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
+d
+12::
+DROP TABLE t1;
+#
# MDEV-27015 Assertion `!is_null()' failed in FixedBinTypeBundle<FbtImpl>::Fbt FixedBinTypeBundle<FbtImpl>::Field_fbt::to_fbt()
#
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a INET6(6) DEFAULT '::10');
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test
index f7453d2d67e..0f587a75a7d 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test
@@ -1631,6 +1631,17 @@ DROP TABLE divisions;
DROP TABLE companies;
--echo #
+--echo # MDEV-27099 Subquery using the ALL keyword on INET6 columns produces a wrong result
+--echo #
+
+CREATE TABLE t1 (d INET6);
+INSERT INTO t1 VALUES ('1::0'), ('12::0');
+SELECT * FROM t1 ORDER BY d;
+SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1);
+SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1);
+DROP TABLE t1;
+
+--echo #
--echo # MDEV-27015 Assertion `!is_null()' failed in FixedBinTypeBundle<FbtImpl>::Fbt FixedBinTypeBundle<FbtImpl>::Field_fbt::to_fbt()
--echo #
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index a729ec24977..37980319d41 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, 2021, MariaDB Corporation.
+/* Copyright (c) 2016, 2022, MariaDB Corporation.
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
@@ -651,10 +651,6 @@ bool Item_func_json_query::fix_length_and_dec()
}
-/*
- Returns NULL, not an error if the found value
- is not a scalar.
-*/
bool Json_path_extractor::extract(String *str, Item *item_js, Item *item_jp,
CHARSET_INFO *cs)
{
@@ -687,6 +683,9 @@ continue_search:
if (json_read_value(&je))
return true;
+ if (je.value_type == JSON_VALUE_NULL)
+ return true;
+
if (unlikely(check_and_get_value(&je, str, &error)))
{
if (error)
@@ -1169,7 +1168,6 @@ my_decimal *Item_func_json_extract::val_decimal(my_decimal *to)
case JSON_VALUE_ARRAY:
case JSON_VALUE_FALSE:
case JSON_VALUE_UNINITIALIZED:
- // TODO: fix: NULL should be NULL
case JSON_VALUE_NULL:
int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to);
return to;
@@ -1798,7 +1796,7 @@ bool Item_func_json_array::fix_length_and_dec()
return TRUE;
for (n_arg=0 ; n_arg < arg_count ; n_arg++)
- char_length+= args[n_arg]->max_char_length() + 4;
+ char_length+= static_cast<ulonglong>(args[n_arg]->max_char_length()) + 4;
fix_char_length_ulonglong(char_length);
tmp_val.set_charset(collation.collation);
@@ -1857,7 +1855,8 @@ bool Item_func_json_array_append::fix_length_and_dec()
for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
{
paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
- char_length+= args[n_arg/2+1]->max_char_length() + 4;
+ char_length+=
+ static_cast<ulonglong>(args[n_arg+1]->max_char_length()) + 4;
}
fix_char_length_ulonglong(char_length);
@@ -3017,7 +3016,8 @@ bool Item_func_json_insert::fix_length_and_dec()
for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
{
paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
- char_length+= args[n_arg/2+1]->max_char_length() + 4;
+ char_length+=
+ static_cast<ulonglong>(args[n_arg+1]->max_char_length()) + 4;
}
fix_char_length_ulonglong(char_length);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index c07c70f55a4..3661df5de69 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3663,6 +3663,41 @@ void select_max_min_finder_subselect::cleanup()
}
+void select_max_min_finder_subselect::set_op(const Type_handler *th)
+{
+ if (th->is_val_native_ready())
+ {
+ op= &select_max_min_finder_subselect::cmp_native;
+ return;
+ }
+
+ switch (th->cmp_type()) {
+ case REAL_RESULT:
+ op= &select_max_min_finder_subselect::cmp_real;
+ break;
+ case INT_RESULT:
+ op= &select_max_min_finder_subselect::cmp_int;
+ break;
+ case STRING_RESULT:
+ op= &select_max_min_finder_subselect::cmp_str;
+ break;
+ case DECIMAL_RESULT:
+ op= &select_max_min_finder_subselect::cmp_decimal;
+ break;
+ case TIME_RESULT:
+ if (th->field_type() == MYSQL_TYPE_TIME)
+ op= &select_max_min_finder_subselect::cmp_time;
+ else
+ op= &select_max_min_finder_subselect::cmp_str;
+ break;
+ case ROW_RESULT:
+ // This case should never be chosen
+ DBUG_ASSERT(0);
+ op= 0;
+ }
+}
+
+
int select_max_min_finder_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_max_min_finder_subselect::send_data");
@@ -3681,30 +3716,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
if (!cache)
{
cache= val_item->get_cache(thd);
- switch (val_item->cmp_type()) {
- case REAL_RESULT:
- op= &select_max_min_finder_subselect::cmp_real;
- break;
- case INT_RESULT:
- op= &select_max_min_finder_subselect::cmp_int;
- break;
- case STRING_RESULT:
- op= &select_max_min_finder_subselect::cmp_str;
- break;
- case DECIMAL_RESULT:
- op= &select_max_min_finder_subselect::cmp_decimal;
- break;
- case TIME_RESULT:
- if (val_item->field_type() == MYSQL_TYPE_TIME)
- op= &select_max_min_finder_subselect::cmp_time;
- else
- op= &select_max_min_finder_subselect::cmp_str;
- break;
- case ROW_RESULT:
- // This case should never be chosen
- DBUG_ASSERT(0);
- op= 0;
- }
+ set_op(val_item->type_handler());
}
cache->store(val_item);
it->store(0, cache);
@@ -3798,6 +3810,26 @@ bool select_max_min_finder_subselect::cmp_str()
return (sortcmp(val1, val2, cache->collation.collation) < 0);
}
+
+bool select_max_min_finder_subselect::cmp_native()
+{
+ NativeBuffer<STRING_BUFFER_USUAL_SIZE> cvalue, mvalue;
+ Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
+ bool cvalue_is_null= cache->val_native(thd, &cvalue);
+ bool mvalue_is_null= maxmin->val_native(thd, &mvalue);
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cvalue_is_null)
+ return (is_all && !mvalue_is_null) || (!is_all && mvalue_is_null);
+ if (mvalue_is_null)
+ return !is_all;
+
+ const Type_handler *th= cache->type_handler();
+ return fmax ? th->cmp_native(cvalue, mvalue) > 0 :
+ th->cmp_native(cvalue, mvalue) < 0;
+}
+
+
int select_exists_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_exists_subselect::send_data");
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 979c4cd1b4b..06e183c2fab 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -6702,6 +6702,7 @@ class select_max_min_finder_subselect :public select_subselect
bool (select_max_min_finder_subselect::*op)();
bool fmax;
bool is_all;
+ void set_op(const Type_handler *ha);
public:
select_max_min_finder_subselect(THD *thd_arg, Item_subselect *item_arg,
bool mx, bool all):
@@ -6714,6 +6715,7 @@ public:
bool cmp_decimal();
bool cmp_str();
bool cmp_time();
+ bool cmp_native();
};
/* EXISTS subselect interface class */
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index b9521d7e0e5..1d2c7b8ff8f 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -513,9 +513,28 @@ btr_page_alloc_low(
page should be initialized. */
dberr_t* err) /*!< out: error code */
{
- buf_block_t *root= btr_root_block_get(index, RW_SX_LATCH, mtr, err);
+ const auto savepoint= mtr->get_savepoint();
+ buf_block_t *root= btr_root_block_get(index, RW_NO_LATCH, mtr, err);
if (UNIV_UNLIKELY(!root))
return root;
+
+ if (mtr->have_u_or_x_latch(*root))
+ {
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!root->index || !root->index->freed());
+#endif
+ mtr->release_block_at_savepoint(savepoint, root);
+ }
+ else
+ {
+ mtr->u_lock_register(savepoint);
+ root->page.lock.u_lock();
+#ifdef BTR_CUR_HASH_ADAPT
+ if (root->index)
+ mtr_t::defer_drop_ahi(root, MTR_MEMO_PAGE_SX_FIX);
+#endif
+ }
+
fseg_header_t *seg_header= root->page.frame +
(level ? PAGE_HEADER + PAGE_BTR_SEG_TOP : PAGE_HEADER + PAGE_BTR_SEG_LEAF);
return fseg_alloc_free_page_general(seg_header, hint_page_no, file_direction,
@@ -584,8 +603,8 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
bool blob, bool space_latched)
{
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
-#ifdef BTR_CUR_HASH_ADAPT
- if (block->index && !block->index->freed())
+#if defined BTR_CUR_HASH_ADAPT && defined UNIV_DEBUG
+ if (btr_search_check_marked_free_index(block))
{
ut_ad(!blob);
ut_ad(page_is_leaf(block->page.frame));
@@ -610,11 +629,30 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
fil_space_t *space= index->table->space;
dberr_t err;
- if (page_t* root = btr_root_get(index, mtr, &err))
+
+ const auto savepoint= mtr->get_savepoint();
+ if (buf_block_t *root= btr_root_block_get(index, RW_NO_LATCH, mtr, &err))
{
- err= fseg_free_page(&root[blob || page_is_leaf(block->page.frame)
- ? PAGE_HEADER + PAGE_BTR_SEG_LEAF
- : PAGE_HEADER + PAGE_BTR_SEG_TOP],
+ if (mtr->have_u_or_x_latch(*root))
+ {
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!root->index || !root->index->freed());
+#endif
+ mtr->release_block_at_savepoint(savepoint, root);
+ }
+ else
+ {
+ mtr->u_lock_register(savepoint);
+ root->page.lock.u_lock();
+#ifdef BTR_CUR_HASH_ADAPT
+ if (root->index)
+ mtr_t::defer_drop_ahi(root, MTR_MEMO_PAGE_SX_FIX);
+#endif
+ }
+ err= fseg_free_page(&root->page.frame[blob ||
+ page_is_leaf(block->page.frame)
+ ? PAGE_HEADER + PAGE_BTR_SEG_LEAF
+ : PAGE_HEADER + PAGE_BTR_SEG_TOP],
space, page, mtr, space_latched);
}
if (err == DB_SUCCESS)
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index d11a3229e7c..fb51a69448a 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -283,7 +283,7 @@ latch_block:
block->page.fix();
block->page.lock.x_lock();
#ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!block->index || !block->index->freed());
+ ut_ad(!btr_search_check_marked_free_index(block));
#endif
if (UNIV_LIKELY_NULL(rtr_info)) {
@@ -7022,7 +7022,7 @@ btr_store_big_rec_extern_fields(
rec_block->page.fix();
rec_block->page.lock.x_lock();
#ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!rec_block->index || !rec_block->index->freed());
+ ut_ad(!btr_search_check_marked_free_index(rec_block));
#endif
uint32_t hint_prev = prev_page_no;
@@ -7400,7 +7400,7 @@ skip_free:
block->fix();
block->page.lock.x_lock();
#ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!block->index || !block->index->freed());
+ ut_ad(!btr_search_check_marked_free_index(block));
#endif
const page_t* page = buf_block_get_frame(ext_block);
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 137a8b10d9f..2ca4417db37 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1279,8 +1279,11 @@ fail_and_release_page:
index page for which we know that
block->buf_fix_count == 0 or it is an index page which
has already been removed from the buf_pool.page_hash
- i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
-void btr_search_drop_page_hash_index(buf_block_t* block)
+ i.e.: it is in state BUF_BLOCK_REMOVE_HASH
+@param[in] garbage_collect drop ahi only if the index is marked
+ as freed */
+void btr_search_drop_page_hash_index(buf_block_t* block,
+ bool garbage_collect)
{
ulint n_fields;
ulint n_bytes;
@@ -1316,13 +1319,21 @@ retry:
auto part = btr_search_sys.get_part(index_id,
block->page.id().space());
+ part->latch.rd_lock(SRW_LOCK_CALL);
+
dict_index_t* index = block->index;
bool is_freed = index && index->freed();
if (is_freed) {
+ part->latch.rd_unlock();
part->latch.wr_lock(SRW_LOCK_CALL);
- } else {
- part->latch.rd_lock(SRW_LOCK_CALL);
+ if (index != block->index) {
+ part->latch.wr_unlock();
+ goto retry;
+ }
+ } else if (garbage_collect) {
+ part->latch.rd_unlock();
+ return;
}
assert_block_ahi_valid(block);
@@ -1797,12 +1808,13 @@ drop_exit:
return;
}
+ ahi_latch->rd_lock(SRW_LOCK_CALL);
+
if (index->freed()) {
+ ahi_latch->rd_unlock();
goto drop_exit;
}
- ahi_latch->rd_lock(SRW_LOCK_CALL);
-
if (block->index) {
uint16_t n_fields = block->curr_n_fields;
uint16_t n_bytes = block->curr_n_bytes;
@@ -2394,5 +2406,20 @@ btr_search_validate()
return(true);
}
+#ifdef UNIV_DEBUG
+bool btr_search_check_marked_free_index(const buf_block_t *block)
+{
+ const index_id_t index_id= btr_page_get_index_id(block->page.frame);
+ auto part= btr_search_sys.get_part(index_id, block->page.id().space());
+
+ part->latch.rd_lock(SRW_LOCK_CALL);
+
+ bool is_freed= block->index && block->index->freed();
+
+ part->latch.rd_unlock();
+
+ return is_freed;
+}
+#endif /* UNIV_DEBUG */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 30b2d44c769..7f0ae398ae6 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2758,11 +2758,7 @@ re_evict:
&& state < buf_page_t::WRITE_FIX));
#ifdef BTR_CUR_HASH_ADAPT
- if (dict_index_t* index = block->index) {
- if (index->freed()) {
- btr_search_drop_page_hash_index(block);
- }
- }
+ btr_search_drop_page_hash_index(block, true);
#endif /* BTR_CUR_HASH_ADAPT */
dberr_t e;
@@ -2820,10 +2816,8 @@ get_latch:
}
get_latch_valid:
#ifdef BTR_CUR_HASH_ADAPT
- if (dict_index_t* index = block->index) {
- if (index->freed()) {
- mtr_t::defer_drop_ahi(block, fix_type);
- }
+ if (block->index) {
+ mtr_t::defer_drop_ahi(block, fix_type);
}
#endif /* BTR_CUR_HASH_ADAPT */
mtr->memo_push(block, fix_type);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index d205b78e6b8..c51db802a24 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -573,19 +573,9 @@ static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot)
buffer be bigger than input buffer. Adjust the allocated size. */
ulint size= srv_page_size;
if (provider_service_lzo->is_loaded)
- {
size= LZO1X_1_15_MEM_COMPRESS;
-#ifdef HAVE_ALIGNED_ALLOC
- size= MY_ALIGN(size, srv_page_size);
-#endif
- }
else if (provider_service_snappy->is_loaded)
- {
size= snappy_max_compressed_length(size);
-#ifdef HAVE_ALIGNED_ALLOC
- size= MY_ALIGN(size, srv_page_size);
-#endif
- }
slot->comp_buf= static_cast<byte*>(aligned_malloc(size, srv_page_size));
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index f1b4af1b309..817aa5fff03 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -662,7 +662,7 @@ dict_table_t::parse_name<>(char(&)[NAME_LEN + 1], char(&)[NAME_LEN + 1],
@param[in] table_op operation to perform when opening
@return table object after locking MDL shared
@retval nullptr if the table is not readable, or if trylock && MDL blocked */
-template<bool trylock>
+template<bool trylock, bool purge_thd>
dict_table_t*
dict_acquire_mdl_shared(dict_table_t *table,
THD *thd,
@@ -674,9 +674,11 @@ dict_acquire_mdl_shared(dict_table_t *table,
MDL_context *mdl_context= static_cast<MDL_context*>(thd_mdl_context(thd));
size_t db_len;
+ dict_table_t *not_found= nullptr;
if (trylock)
{
+ static_assert(!trylock || !purge_thd, "usage");
dict_sys.freeze(SRW_LOCK_CALL);
db_len= dict_get_db_name_len(table->name.m_name);
dict_sys.unfreeze();
@@ -748,7 +750,13 @@ retry:
}
}
+retry_table_open:
dict_sys.freeze(SRW_LOCK_CALL);
+ if (purge_thd && purge_sys.must_wait_FTS())
+ {
+ not_found= reinterpret_cast<dict_table_t*>(-1);
+ goto return_without_mdl;
+ }
table= dict_sys.find_table(table_id);
if (table)
table->acquire();
@@ -756,6 +764,11 @@ retry:
{
dict_sys.unfreeze();
dict_sys.lock(SRW_LOCK_CALL);
+ if (purge_thd && purge_sys.must_wait_FTS())
+ {
+ dict_sys.unlock();
+ goto retry_table_open;
+ }
table= dict_load_table_on_id(table_id,
table_op == DICT_TABLE_OP_LOAD_TABLESPACE
? DICT_ERR_IGNORE_RECOVER_LOCK
@@ -777,7 +790,7 @@ return_without_mdl:
mdl_context->release_lock(*mdl);
*mdl= nullptr;
}
- return nullptr;
+ return not_found;
}
size_t db1_len, tbl1_len;
@@ -814,9 +827,9 @@ return_without_mdl:
goto retry;
}
-template dict_table_t* dict_acquire_mdl_shared<false>
+template dict_table_t* dict_acquire_mdl_shared<false, false>
(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t);
-template dict_table_t* dict_acquire_mdl_shared<true>
+template dict_table_t* dict_acquire_mdl_shared<true, false>
(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t);
/** Look up a table by numeric identifier.
@@ -842,13 +855,14 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
{
if (purge_thd && purge_sys.must_wait_FTS())
{
- table= nullptr;
+ table= reinterpret_cast<dict_table_t*>(-1);
goto func_exit;
}
table->acquire();
if (thd && !dict_locked)
- table= dict_acquire_mdl_shared<false>(table, thd, mdl, table_op);
+ table= dict_acquire_mdl_shared<false, purge_thd>(
+ table, thd, mdl, table_op);
}
else if (table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED)
{
@@ -866,7 +880,7 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
if (purge_thd && purge_sys.must_wait_FTS())
{
dict_sys.unlock();
- return nullptr;
+ return reinterpret_cast<dict_table_t*>(-1);
}
table->acquire();
}
@@ -876,7 +890,8 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
if (table && thd)
{
dict_sys.freeze(SRW_LOCK_CALL);
- table= dict_acquire_mdl_shared<false>(table, thd, mdl, table_op);
+ table= dict_acquire_mdl_shared<false, purge_thd>(
+ table, thd, mdl, table_op);
dict_sys.unfreeze();
}
return table;
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index f6b4470c242..d6716af7610 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1664,6 +1664,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
fseg_inode_t* inode;
ib_id_t seg_id;
uint32_t n_reserved;
+ bool reserved_extent = false;
DBUG_ENTER("fseg_create");
@@ -1677,14 +1678,6 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
ut_ad(!block || block->page.id().space() == space->id);
- if (!has_done_reservation) {
- *err = fsp_reserve_free_extents(&n_reserved, space, 2,
- FSP_NORMAL, mtr);
- if (UNIV_UNLIKELY(*err != DB_SUCCESS)) {
- DBUG_RETURN(nullptr);
- }
- }
-
buf_block_t* header = fsp_get_header(space, mtr, err);
if (!header) {
block = nullptr;
@@ -1693,10 +1686,32 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
buf_block_t* iblock;
+inode_alloc:
inode = fsp_alloc_seg_inode(space, header, &iblock, mtr, err);
- if (inode == NULL) {
+ if (!inode) {
block = nullptr;
+reserve_extent:
+ if (!has_done_reservation && !reserved_extent) {
+ *err = fsp_reserve_free_extents(&n_reserved, space, 2,
+ FSP_NORMAL, mtr);
+ if (UNIV_UNLIKELY(*err != DB_SUCCESS)) {
+ DBUG_RETURN(nullptr);
+ }
+
+ /* Extents reserved successfully. So
+ try allocating the page or inode */
+ reserved_extent = true;
+ if (inode) {
+ goto page_alloc;
+ }
+
+ goto inode_alloc;
+ }
+
+ if (inode) {
+ fsp_free_seg_inode(space, inode, iblock, mtr);
+ }
goto funct_exit;
}
@@ -1724,6 +1739,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
FSEG_FRAG_SLOT_SIZE * FSEG_FRAG_ARR_N_SLOTS, 0xff);
if (!block) {
+page_alloc:
block = fseg_alloc_free_page_low(space,
inode, iblock, 0, FSP_UP,
#ifdef UNIV_DEBUG
@@ -1731,13 +1747,9 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
#endif /* UNIV_DEBUG */
mtr, mtr, err);
- /* The allocation cannot fail if we have already reserved a
- space for the page. */
- ut_ad(!has_done_reservation || block != NULL);
-
if (!block) {
- fsp_free_seg_inode(space, inode, iblock, mtr);
- goto funct_exit;
+ ut_ad(!has_done_reservation);
+ goto reserve_extent;
}
ut_d(const auto x = block->page.lock.x_lock_count());
@@ -1759,7 +1771,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
+ block->page.frame, space->id);
funct_exit:
- if (!has_done_reservation) {
+ if (!has_done_reservation && reserved_extent) {
space->release_free_extents(n_reserved);
}
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 106582286a9..b5686602610 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 2022, MariaDB Corporation.
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 the Free Software
@@ -100,8 +100,11 @@ btr_search_move_or_delete_hash_entries(
index page for which we know that
block->buf_fix_count == 0 or it is an index page which
has already been removed from the buf_pool.page_hash
- i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
-void btr_search_drop_page_hash_index(buf_block_t* block);
+ i.e.: it is in state BUF_BLOCK_REMOVE_HASH
+@param[in] garbage_collect drop ahi only if the index is marked
+ as freed */
+void btr_search_drop_page_hash_index(buf_block_t* block,
+ bool garbage_collect= false);
/** Drop possible adaptive hash index entries when a page is evicted
from the buffer pool or freed in a file, or the index is being dropped.
@@ -146,16 +149,23 @@ static inline void btr_search_s_lock_all();
/** Unlock all search latches from shared mode. */
static inline void btr_search_s_unlock_all();
+# ifdef UNIV_DEBUG
+/** @return if the index is marked as freed */
+bool btr_search_check_marked_free_index(const buf_block_t *block);
+# endif /* UNIV_DEBUG */
#else /* BTR_CUR_HASH_ADAPT */
# define btr_search_sys_create()
# define btr_search_sys_free()
-# define btr_search_drop_page_hash_index(block)
+# define btr_search_drop_page_hash_index(block, garbage_collect)
# define btr_search_s_lock_all(index)
# define btr_search_s_unlock_all(index)
# define btr_search_info_update(index, cursor)
# define btr_search_move_or_delete_hash_entries(new_block, block)
# define btr_search_update_hash_on_insert(cursor, ahi_latch)
# define btr_search_update_hash_on_delete(cursor)
+# ifdef UNIV_DEBUG
+# define btr_search_check_marked_free_index(block)
+# endif /* UNIV_DEBUG */
#endif /* BTR_CUR_HASH_ADAPT */
#ifdef BTR_CUR_ADAPT
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index cf937e3b66d..a76fec31416 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -132,7 +132,7 @@ enum dict_table_op_t {
@param[in] table_op operation to perform when opening
@return table object after locking MDL shared
@retval NULL if the table is not readable, or if trylock && MDL blocked */
-template<bool trylock>
+template<bool trylock, bool purge_thd= false>
dict_table_t*
dict_acquire_mdl_shared(dict_table_t *table,
THD *thd,
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index a487a72d3f0..83987789bb5 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -1345,7 +1345,7 @@ public:
@param n_cols number of columns whose collation is changing */
void init_change_cols(unsigned n_cols)
{
- ut_ad(n_fields > n_cols);
+ ut_ad(n_fields > n_cols || type & DICT_FTS);
change_col_info= static_cast<col_info*>
(mem_heap_zalloc(heap, sizeof(col_info)));
change_col_info->n_cols= n_cols;
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index ebe9ed78534..067e5a86b46 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -177,6 +177,10 @@ struct mtr_t {
@param block buffer pool block to search for */
bool have_x_latch(const buf_block_t &block) const;
+ /** Check if we are holding a block latch in S or U mode
+ @param block buffer pool block to search for */
+ bool have_u_or_x_latch(const buf_block_t &block) const;
+
/** Copy the tablespaces associated with the mini-transaction
(needed for generating FILE_MODIFY records)
@param[in] mtr mini-transaction that may modify
@@ -336,6 +340,15 @@ public:
@param rw_latch RW_S_LATCH, RW_SX_LATCH, RW_X_LATCH, RW_NO_LATCH */
void page_lock(buf_block_t *block, ulint rw_latch);
+ /** Register a page latch on a buffer-fixed block was buffer-fixed.
+ @param latch latch type */
+ void u_lock_register(ulint savepoint)
+ {
+ mtr_memo_slot_t *slot= m_memo.at<mtr_memo_slot_t*>(savepoint);
+ ut_ad(slot->type == MTR_MEMO_BUF_FIX);
+ slot->type= MTR_MEMO_PAGE_SX_FIX;
+ }
+
/** Upgrade U locks on a block to X */
void page_lock_upgrade(const buf_block_t &block);
/** Upgrade X lock to X */
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 61f7d3961d2..25a1d49ccaf 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -829,7 +829,29 @@ processed:
fil_space_t *space= fil_space_t::create(it->first, flags,
FIL_TYPE_TABLESPACE, crypt_data);
ut_ad(space);
- space->add(name.c_str(), OS_FILE_CLOSED, size, false, false);
+ const char *filename= name.c_str();
+ if (srv_operation == SRV_OPERATION_RESTORE)
+ {
+ const char* tbl_name = strrchr(filename, '/');
+#ifdef _WIN32
+ if (const char *last = strrchr(filename, '\\'))
+ {
+ if (last > tbl_name)
+ tbl_name = last;
+ }
+#endif
+ if (tbl_name)
+ {
+ while (--tbl_name > filename &&
+#ifdef _WIN32
+ *tbl_name != '\\' &&
+#endif
+ *tbl_name != '/');
+ if (tbl_name > filename)
+ filename= tbl_name + 1;
+ }
+ }
+ space->add(filename, OS_FILE_CLOSED, size, false, false);
space->recv_size= it->second.size;
space->size_in_header= size;
return space;
@@ -1227,9 +1249,6 @@ static void fil_name_process(const char *name, ulint len, uint32_t space_id,
d->deleted = true;
goto got_deleted;
}
- if (ftype == FILE_RENAME) {
- d->file_name= fname.name;
- }
goto reload;
}
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index ee71b638984..ebde21ca4df 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -1219,6 +1219,21 @@ struct FindBlockX
}
};
+/** Find out whether a block was not X or U latched by the mini-transaction */
+struct FindBlockUX
+{
+ const buf_block_t &block;
+
+ FindBlockUX(const buf_block_t &block): block(block) {}
+
+ /** @return whether the block was not found x-latched */
+ bool operator()(const mtr_memo_slot_t *slot) const
+ {
+ return slot->object != &block ||
+ !(slot->type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX));
+ }
+};
+
#ifdef UNIV_DEBUG
/** Assert that the block is not present in the mini-transaction */
struct FindNoBlock
@@ -1249,6 +1264,14 @@ bool mtr_t::have_x_latch(const buf_block_t &block) const
return true;
}
+bool mtr_t::have_u_or_x_latch(const buf_block_t &block) const
+{
+ if (m_memo.for_each_block(CIterate<FindBlockUX>(FindBlockUX(block))))
+ return false;
+ ut_ad(block.page.lock.have_u_or_x());
+ return true;
+}
+
/** Check if we are holding exclusive tablespace latch
@param space tablespace to search for
@param shared whether to look for shared latch, instead of exclusive
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 47625b91f35..8bbb0a36144 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -941,7 +941,8 @@ try_again:
table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd,
&node->mdl_ticket);
- if (!node->table && purge_sys.must_wait_FTS()) {
+ if (node->table == reinterpret_cast<dict_table_t*>(-1)) {
+ /* purge stop signal */
goto try_again;
}
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 34ec21d6013..760c4e707ce 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -290,6 +290,11 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid)
buf_block_t *trx_rseg_t::get(mtr_t *mtr, dberr_t *err) const
{
+ if (!space)
+ {
+ if (err) *err= DB_TABLESPACE_NOT_FOUND;
+ return nullptr;
+ }
return buf_page_get_gen(page_id(), 0, RW_X_LATCH, nullptr,
BUF_GET, mtr, err);
}
@@ -435,6 +440,8 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
mtr_t *mtr)
{
+ if (!rseg->space)
+ return DB_TABLESPACE_NOT_FOUND;
dberr_t err;
const buf_block_t *rseg_hdr=
buf_page_get_gen(rseg->page_id(), 0, RW_S_LATCH, nullptr, BUF_GET, mtr,
diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result
new file mode 100644
index 00000000000..66e33f42a7e
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result
@@ -0,0 +1,38 @@
+#
+# MDEV-29008 Server crash or assertion `field' failed in spider_db_open_item_ident / group by handler
+#
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+connection child2_1;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+CREATE TABLE tbl_a (
+a INT,
+b INT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO tbl_a VALUES (1,2),(3,4);
+connection master_1;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+CREATE TABLE tbl_a (
+a INT,
+b INT
+) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"';
+SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2 ORDER BY f1, f2;
+f1 f2
+1 2
+1 4
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.cnf
new file mode 100644
index 00000000000..05dfd8a0bce
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.cnf
@@ -0,0 +1,3 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
+!include ../my_2_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test
new file mode 100644
index 00000000000..28d9a9244e3
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test
@@ -0,0 +1,39 @@
+--echo #
+--echo # MDEV-29008 Server crash or assertion `field' failed in spider_db_open_item_ident / group by handler
+--echo #
+
+--disable_query_log
+--disable_result_log
+--source ../../t/test_init.inc
+--enable_result_log
+--enable_query_log
+
+--connection child2_1
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+eval CREATE TABLE tbl_a (
+ a INT,
+ b INT
+) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+INSERT INTO tbl_a VALUES (1,2),(3,4);
+
+--connection master_1
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+eval CREATE TABLE tbl_a (
+ a INT,
+ b INT
+) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';
+
+SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2 ORDER BY f1, f2;
+
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+--connection child2_1
+DROP DATABASE IF EXISTS auto_test_remote;
+
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_query_log
+--enable_result_log
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 3692bb6f6d6..b21f7c4e1e7 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -1,5 +1,5 @@
/* Copyright (C) 2008-2019 Kentoku Shiba
- Copyright (C) 2019, 2020, MariaDB Corporation.
+ Copyright (C) 2019, 2022, MariaDB Corporation.
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
@@ -9891,8 +9891,6 @@ int spider_db_open_item_ident(
SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder;
spider = field_holder->spider;
share = spider->share;
- field = spider->field_exchange(field);
- DBUG_ASSERT(field);
if ((error_num = share->dbton_share[dbton_id]->
append_column_name_with_alias(str, field->field_index,
field_holder->alias->ptr(), field_holder->alias->length())))