summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--extra/innochecksum.cc5
-rw-r--r--extra/mariabackup/backup_copy.cc68
-rw-r--r--extra/mariabackup/xtrabackup.cc35
m---------libmariadb0
-rw-r--r--libmysqld/CMakeLists.txt1
-rw-r--r--mysql-test/main/cast.result6
-rw-r--r--mysql-test/main/cast.test6
-rw-r--r--mysql-test/main/constraints.result20
-rw-r--r--mysql-test/main/constraints.test23
-rw-r--r--mysql-test/main/cte_nonrecursive.result8
-rw-r--r--mysql-test/main/derived.result54
-rw-r--r--mysql-test/main/derived.test30
-rw-r--r--mysql-test/main/derived_view.result2
-rw-r--r--mysql-test/main/events_grant.result2
-rw-r--r--mysql-test/main/func_gconcat.result14
-rw-r--r--mysql-test/main/func_gconcat.test12
-rw-r--r--mysql-test/main/grant.result10
-rw-r--r--mysql-test/main/information_schema.result2
-rw-r--r--mysql-test/main/join_cache.result6
-rw-r--r--mysql-test/main/subselect_extra.result2
-rw-r--r--mysql-test/main/subselect_extra_no_semijoin.result2
-rw-r--r--mysql-test/main/trigger.result32
-rw-r--r--mysql-test/main/trigger.test34
-rw-r--r--mysql-test/suite/encryption/r/innodb-key-rotation-disable.result4
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result80
-rw-r--r--mysql-test/suite/encryption/t/innodb-key-rotation-disable.test5
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt2
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test83
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_trig_03e.result6
-rw-r--r--mysql-test/suite/funcs_1/r/is_column_privileges.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_schema_privileges.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_table_privileges.result8
-rw-r--r--mysql-test/suite/funcs_1/r/is_triggers.result2
-rw-r--r--mysql-test/suite/funcs_1/r/memory_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/memory_trig_03e.result6
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_trig_03e.result6
-rw-r--r--mysql-test/suite/innodb/r/page_reorganize.result27
-rw-r--r--mysql-test/suite/innodb/t/page_reorganize.test56
-rw-r--r--mysql-test/suite/innodb_zip/r/innochecksum_2.result2
-rw-r--r--mysql-test/suite/mariabackup/backup_grants.result1
-rw-r--r--mysql-test/suite/mariabackup/backup_grants.test3
-rw-r--r--mysql-test/suite/plugins/r/server_audit.result17
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test11
-rw-r--r--mysql-test/suite/versioning/r/truncate_privilege.result10
-rw-r--r--plugin/server_audit/server_audit.c69
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_sum.cc14
-rw-r--r--sql/lock.cc11
-rw-r--r--sql/log.cc2
-rw-r--r--sql/mysqld.cc17
-rw-r--r--sql/semisync_master.cc11
-rw-r--r--sql/semisync_master.h8
-rw-r--r--sql/semisync_master_ack_receiver.cc3
-rw-r--r--sql/session_tracker.cc765
-rw-r--r--sql/session_tracker.h287
-rw-r--r--sql/set_var.cc8
-rw-r--r--sql/set_var.h3
-rw-r--r--sql/signal_handler.cc46
-rw-r--r--sql/sql_acl.cc4
-rw-r--r--sql/sql_analyze_stmt.cc10
-rw-r--r--sql/sql_class.cc22
-rw-r--r--sql/sql_class.h11
-rw-r--r--sql/sql_lex.cc5
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_plugin.cc47
-rw-r--r--sql/sql_plugin.h3
-rw-r--r--sql/sql_show.cc17
-rw-r--r--sql/sql_trigger.h2
-rw-r--r--sql/sql_type.cc2
-rw-r--r--sql/sql_union.cc40
-rw-r--r--sql/sys_vars.cc27
-rw-r--r--sql/sys_vars.ic37
-rw-r--r--sql/table.cc20
-rw-r--r--sql/transaction.cc37
-rw-r--r--sql/wsrep_server_service.cc8
-rw-r--r--storage/innobase/buf/buf0buddy.cc11
-rw-r--r--storage/innobase/buf/buf0dblwr.cc2
-rw-r--r--storage/innobase/buf/buf0flu.cc5
-rw-r--r--storage/innobase/data/data0data.cc4
-rw-r--r--storage/innobase/fil/fil0crypt.cc162
-rw-r--r--storage/innobase/fil/fil0fil.cc87
-rw-r--r--storage/innobase/fts/fts0fts.cc3
-rw-r--r--storage/innobase/gis/gis0geo.cc23
-rw-r--r--storage/innobase/gis/gis0rtree.cc9
-rw-r--r--storage/innobase/gis/gis0sea.cc6
-rw-r--r--storage/innobase/handler/ha_innodb.cc33
-rw-r--r--storage/innobase/handler/handler0alter.cc1
-rw-r--r--storage/innobase/include/buf0buf.h10
-rw-r--r--storage/innobase/include/data0data.h183
-rw-r--r--storage/innobase/include/data0data.ic156
-rw-r--r--storage/innobase/include/fil0fil.h6
-rw-r--r--storage/innobase/include/gis0geo.h3
-rw-r--r--storage/innobase/include/ha_prototypes.h1
-rw-r--r--storage/innobase/include/log0log.h16
-rw-r--r--storage/innobase/include/log0recv.h10
-rw-r--r--storage/innobase/include/page0page.ic2
-rw-r--r--storage/innobase/include/rem0cmp.ic4
-rw-r--r--storage/innobase/include/row0mysql.h2
-rw-r--r--storage/innobase/include/row0vers.h6
-rw-r--r--storage/innobase/include/trx0rec.h6
-rw-r--r--storage/innobase/include/univ.i2
-rw-r--r--storage/innobase/include/ut0lst.h130
-rw-r--r--storage/innobase/lock/lock0lock.cc67
-rw-r--r--storage/innobase/log/log0log.cc50
-rw-r--r--storage/innobase/log/log0recv.cc48
-rw-r--r--storage/innobase/os/os0file.cc18
-rw-r--r--storage/innobase/row/row0import.cc2
-rw-r--r--storage/innobase/row/row0ins.cc7
-rw-r--r--storage/innobase/row/row0merge.cc15
-rw-r--r--storage/innobase/row/row0mysql.cc4
-rw-r--r--storage/innobase/row/row0row.cc11
-rw-r--r--storage/innobase/row/row0sel.cc20
-rw-r--r--storage/innobase/row/row0upd.cc30
-rw-r--r--storage/innobase/row/row0vers.cc22
-rw-r--r--storage/innobase/srv/srv0srv.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc23
-rw-r--r--storage/innobase/trx/trx0rec.cc13
-rw-r--r--storage/innobase/trx/trx0trx.cc3
-rw-r--r--unittest/mysys/CMakeLists.txt2
-rw-r--r--unittest/mysys/byte_order-t.c102
125 files changed, 1936 insertions, 1722 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96f251e9553..7480b76b5ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -228,7 +228,7 @@ IF (WITH_UBSAN)
IF(SECURITY_HARDENED)
MESSAGE(FATAL_ERROR "WITH_UBSAN and SECURITY_HARDENED are mutually exclusive")
ENDIF()
- MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined" DEBUG RELWITHDEBINFO)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -fno-sanitize=alignment" DEBUG RELWITHDEBINFO)
ENDIF()
IF(NOT WITH_TSAN)
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index dc49e3e0817..77b1767c426 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -1211,7 +1211,7 @@ static struct my_option innochecksum_options[] = {
{"verbose", 'v', "Verbose (prints progress every 5 seconds).",
&verbose, &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", '#', "Output debug log. See " REFMAN "dbug-package.html",
+ {"debug", '#', "Output debug log. See https://mariadb.com/kb/en/library/creating-a-trace-file/",
&dbug_setting, &dbug_setting, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif /* !DBUG_OFF */
{"count", 'c', "Print the count of pages in the file and exits.",
@@ -1278,7 +1278,8 @@ static void usage(void)
"[-p <page>] [-i] [-v] [-a <allow mismatches>] [-n] "
"[-C <strict-check>] [-w <write>] [-S] [-D <page type dump>] "
"[-l <log>] [-l] [-m <merge pages>] <filename or [-]>\n", my_progname);
- printf("See " REFMAN "innochecksum.html for usage hints.\n");
+ printf("See https://mariadb.com/kb/en/library/innochecksum/"
+ " for usage hints.\n");
my_print_help(innochecksum_options);
my_print_variables(innochecksum_options);
}
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index abd9f710983..02998d9b5e5 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -986,6 +986,65 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
return(ret);
}
+#ifdef _WIN32
+#include <windows.h>
+#include <accctrl.h>
+#include <aclapi.h>
+/*
+ On Windows, fix permission of the file after "copyback"
+ We assume that after copyback, mysqld will run as service as NetworkService
+ user, thus well give full permission on given file to that user.
+*/
+
+static int fix_win_file_permissions(const char *file)
+{
+ struct {
+ TOKEN_USER tokenUser;
+ BYTE buffer[SECURITY_MAX_SID_SIZE];
+ } tokenInfoBuffer;
+ HANDLE hFile = CreateFile(file, READ_CONTROL | WRITE_DAC, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return -1;
+ ACL* pOldDACL;
+ SECURITY_DESCRIPTOR* pSD = NULL;
+ EXPLICIT_ACCESS ea = { 0 };
+ BOOL isWellKnownSID = FALSE;
+ PSID pSid = NULL;
+
+ GetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
+ &pOldDACL, NULL, (void**)&pSD);
+ DWORD size = SECURITY_MAX_SID_SIZE;
+ pSid = (PSID)tokenInfoBuffer.buffer;
+ if (!CreateWellKnownSid(WinNetworkServiceSid, NULL, pSid,
+ &size))
+ {
+ return 1;
+ }
+ ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea.Trustee.ptstrName = (LPTSTR)pSid;
+
+ ea.grfAccessMode = GRANT_ACCESS;
+ ea.grfAccessPermissions = GENERIC_ALL;
+ ea.grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
+ ea.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ACL* pNewDACL = 0;
+ DWORD err = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
+ if (pNewDACL)
+ {
+ SetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
+ pNewDACL, NULL);
+ }
+ if (pSD != NULL)
+ LocalFree((HLOCAL)pSD);
+ if (pNewDACL != NULL)
+ LocalFree((HLOCAL)pNewDACL);
+ CloseHandle(hFile);
+ return 0;
+}
+
+#endif
+
/************************************************************************
Copy file for backup/restore.
@@ -1034,6 +1093,10 @@ copy_file(ds_ctxt_t *datasink,
/* close */
msg(thread_n," ...done");
datafile_close(&cursor);
+#ifdef _WIN32
+ if (xtrabackup_copy_back || xtrabackup_move_back)
+ ut_a(!fix_win_file_permissions(dstfile->path));
+#endif
if (ds_close(dstfile)) {
goto error_close;
}
@@ -1104,7 +1167,10 @@ move_file(ds_ctxt_t *datasink,
errbuf);
return(false);
}
-
+#ifdef _WIN32
+ if (xtrabackup_copy_back || xtrabackup_move_back)
+ ut_a(!fix_win_file_permissions(dst_file_path_abs));
+#endif
msg(thread_n," ...done");
return(true);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 274248163d5..6a7f2e78ce5 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -4162,7 +4162,7 @@ reread_log_header:
memset(&stat_info, 0, sizeof(MY_STAT));
dst_log_file = ds_open(ds_redo, "ib_logfile0", &stat_info);
if (dst_log_file == NULL) {
- msg("§rror: failed to open the target stream for "
+ msg("Error: failed to open the target stream for "
"'ib_logfile0'.");
goto fail;
}
@@ -4914,9 +4914,9 @@ xtrabackup_apply_delta(
/* first block of block cluster */
offset = ((incremental_buffers * (page_size / 4))
<< page_size_shift);
- success = os_file_read(IORequestRead, src_file,
- incremental_buffer, offset, page_size);
- if (success != DB_SUCCESS) {
+ if (os_file_read(IORequestRead, src_file,
+ incremental_buffer, offset, page_size)
+ != DB_SUCCESS) {
goto error;
}
@@ -4946,10 +4946,10 @@ xtrabackup_apply_delta(
ut_a(last_buffer || page_in_buffer == page_size / 4);
/* read whole of the cluster */
- success = os_file_read(IORequestRead, src_file,
- incremental_buffer,
- offset, page_in_buffer * page_size);
- if (success != DB_SUCCESS) {
+ if (os_file_read(IORequestRead, src_file,
+ incremental_buffer,
+ offset, page_in_buffer * page_size)
+ != DB_SUCCESS) {
goto error;
}
@@ -4995,9 +4995,9 @@ xtrabackup_apply_delta(
}
}
- success = os_file_write(IORequestWrite,
- dst_path, dst_file, buf, off, page_size);
- if (success != DB_SUCCESS) {
+ if (os_file_write(IORequestWrite,
+ dst_path, dst_file, buf, off,
+ page_size) != DB_SUCCESS) {
goto error;
}
}
@@ -5763,7 +5763,18 @@ static bool check_all_privileges()
PRIVILEGE_WARNING);
}
- return !(check_result & PRIVILEGE_ERROR);
+ if (check_result & PRIVILEGE_ERROR) {
+ msg("Current privileges, as reported by 'SHOW GRANTS': ");
+ int n=1;
+ for (std::list<std::string>::const_iterator it = granted_privileges.begin();
+ it != granted_privileges.end();
+ it++,n++) {
+ msg(" %d.%s", n, it->c_str());
+ }
+ return false;
+ }
+
+ return true;
}
bool
diff --git a/libmariadb b/libmariadb
-Subproject 1285dc72a043f09d9a51abcfc3a4fbfb5192067
+Subproject 1dd39fb9f7418f533da05ca1156aa8f60937b7e
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 4d9b07195ba..baa5577bc39 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -119,7 +119,6 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_sequence.cc ../sql/sql_sequence.h
../sql/ha_sequence.cc ../sql/ha_sequence.h
../sql/temporary_tables.cc
- ../sql/session_tracker.cc
../sql/proxy_protocol.cc ../sql/backup.cc
../sql/sql_tvc.cc ../sql/sql_tvc.h
../sql/opt_split.cc
diff --git a/mysql-test/main/cast.result b/mysql-test/main/cast.result
index f1e7eb7b502..17329cb596f 100644
--- a/mysql-test/main/cast.result
+++ b/mysql-test/main/cast.result
@@ -1277,3 +1277,9 @@ END;
$$
ERROR 22007: Truncated incorrect CHAR(1) value: '10:20:30'
SET sql_mode=DEFAULT;
+#
+# MDEV-10307 CAST(11068046444225730969 AS SIGNED) does not return a warning
+#
+SELECT CAST(11068046444225730969 AS SIGNED);
+CAST(11068046444225730969 AS SIGNED)
+-7378697629483820647
diff --git a/mysql-test/main/cast.test b/mysql-test/main/cast.test
index b514dbb5b2d..f48d6d9f95f 100644
--- a/mysql-test/main/cast.test
+++ b/mysql-test/main/cast.test
@@ -724,3 +724,9 @@ $$
DELIMITER ;$$
SET sql_mode=DEFAULT;
+
+--echo #
+--echo # MDEV-10307 CAST(11068046444225730969 AS SIGNED) does not return a warning
+--echo #
+
+SELECT CAST(11068046444225730969 AS SIGNED);
diff --git a/mysql-test/main/constraints.result b/mysql-test/main/constraints.result
index aba226cdd33..0b7577dd3ac 100644
--- a/mysql-test/main/constraints.result
+++ b/mysql-test/main/constraints.result
@@ -1,4 +1,3 @@
-drop table if exists t1;
create table t1 (a int check (a>0));
show create table t1;
Table Create Table
@@ -111,6 +110,25 @@ long_enough_name CREATE TABLE `long_enough_name` (
CONSTRAINT `constr` CHECK (`f6` >= 0)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE long_enough_name;
+CREATE TABLE test.t(t int COMMENT 't_comment' CHECK(t>0));
+SHOW CREATE TABLE test.t;
+Table Create Table
+t CREATE TABLE `t` (
+ `t` int(11) DEFAULT NULL COMMENT 't_comment' CHECK (`t` > 0)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP table test.t;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
+CREATE TABLE test.t (f int foo=bar check(f>0));
+Warnings:
+Warning 1911 Unknown option 'foo'
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `f` int(11) DEFAULT NULL `foo`=bar CHECK (`f` > 0)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP table test.t;
+SET @@SQL_MODE=@OLD_SQL_MODE;
create table t1 (a int check (a>10)) select 100 as 'a';
show create table t1;
Table Create Table
diff --git a/mysql-test/main/constraints.test b/mysql-test/main/constraints.test
index c06f585d04f..d7a5b41d708 100644
--- a/mysql-test/main/constraints.test
+++ b/mysql-test/main/constraints.test
@@ -1,10 +1,6 @@
#
# Testing of constraints
#
---disable_warnings
-drop table if exists t1;
---enable_warnings
-
create table t1 (a int check (a>0));
show create table t1;
insert into t1 values (1);
@@ -104,7 +100,24 @@ SHOW CREATE TABLE long_enough_name;
DROP TABLE long_enough_name;
#
-# Check that we don't loose constraints as part of CREATE ... SELECT
+# MDEV-17654 Incorrect syntax returned for column with CHECK constraint
+# in the "SHOW CREATE TABLE ..." result
+#
+
+CREATE TABLE test.t(t int COMMENT 't_comment' CHECK(t>0));
+SHOW CREATE TABLE test.t;
+DROP table test.t;
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
+
+CREATE TABLE test.t (f int foo=bar check(f>0));
+SHOW CREATE TABLE t;
+DROP table test.t;
+SET @@SQL_MODE=@OLD_SQL_MODE;
+
+#
+# Check that we don't lose constraints as part of CREATE ... SELECT
#
create table t1 (a int check (a>10)) select 100 as 'a';
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 4fea05f79b4..2556fd4b06b 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -244,7 +244,7 @@ with t as (select distinct a from t1 where b >= 'c')
select * from t as r1, t as r2 where r1.a=r2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 Using where
-1 PRIMARY <derived3> ref key0 key0 5 r1.a 2
+1 PRIMARY <derived3> ref key0 key0 5 r1.a 1
3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
explain
@@ -253,7 +253,7 @@ select * from (select distinct a from t1 where b >= 'c') as r1,
where r1.a=r2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 Using where
-1 PRIMARY <derived3> ref key0 key0 5 r1.a 2
+1 PRIMARY <derived3> ref key0 key0 5 r1.a 1
3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
# two references to t specified by a query
@@ -369,7 +369,7 @@ select c as a from t2 where c < 4)
select * from t2,t where t2.c=t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
-1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 1
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where
3 UNION t2 ALL NULL NULL NULL NULL 4 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -381,7 +381,7 @@ select c as a from t2 where c < 4) as t
where t2.c=t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
-1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 1
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where
3 UNION t2 ALL NULL NULL NULL NULL 4 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result
index 9874f16aa8a..abf087f891c 100644
--- a/mysql-test/main/derived.result
+++ b/mysql-test/main/derived.result
@@ -1195,3 +1195,57 @@ drop table t1,t2,t3;
#
# End of 10.2 tests
#
+#
+# MDEV-9959: A serious MariaDB server performance bug
+#
+create table t1(a int);
+insert into t1 values (1),(2),(3),(4),(5),(6);
+create table t2(a int, b int,c int);
+insert into t2(a,b,c) values (1,1,2),(2,2,3),(3,1,4),(4,2,2),(5,1,1),(6,2,5);
+create table t3(a int, b int);
+insert into t3(a,b) values (1,1),(2,2),(2,1),(1,2),(5,1),(9,2);
+table "<derived2>" should have type=ref and rows=1
+one select in derived table
+with distinct
+analyze select * from t1 , ((select distinct t2.a from t2 order by c))q where t1.a=q.a;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 1 1.00 100.00 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using temporary; Using filesort
+analyze select * from t1 , ((select distinct t2.a, t2.b from t2 order by c))q where t1.a=q.a;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 2 1.00 100.00 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using temporary; Using filesort
+# multiple selects in derived table
+# NO UNION ALL
+analyze select * from t1 , ( (select t2.a from t2 order by c) union (select t2.a from t2 order by c))q where t1.a=q.a;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 1 1.00 100.00 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00
+3 UNION t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL 6.00 NULL NULL
+select * from t1 , ( (select t2.a from t2 order by c) union (select t2.a from t2 order by c))q where t1.a=q.a;
+a a
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+# UNION ALL and EXCEPT
+analyze select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a from t2 order by c) except(select t3.a from t3 order by b))q where t1.a=q.a;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 1 0.50 100.00 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00
+3 UNION t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00
+4 EXCEPT t3 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL 3.00 NULL NULL
+select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a from t2 order by c) except(select t3.a from t3 order by b))q where t1.a=q.a;
+a a
+3 3
+4 4
+6 6
+drop table t1,t2,t3;
diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test
index 6c51f23c51e..990f955450a 100644
--- a/mysql-test/main/derived.test
+++ b/mysql-test/main/derived.test
@@ -1032,3 +1032,33 @@ drop table t1,t2,t3;
--echo #
--echo # End of 10.2 tests
--echo #
+
+--echo #
+--echo # MDEV-9959: A serious MariaDB server performance bug
+--echo #
+
+create table t1(a int);
+insert into t1 values (1),(2),(3),(4),(5),(6);
+create table t2(a int, b int,c int);
+insert into t2(a,b,c) values (1,1,2),(2,2,3),(3,1,4),(4,2,2),(5,1,1),(6,2,5);
+create table t3(a int, b int);
+insert into t3(a,b) values (1,1),(2,2),(2,1),(1,2),(5,1),(9,2);
+
+--echo table "<derived2>" should have type=ref and rows=1
+--echo one select in derived table
+
+--echo with distinct
+analyze select * from t1 , ((select distinct t2.a from t2 order by c))q where t1.a=q.a;
+analyze select * from t1 , ((select distinct t2.a, t2.b from t2 order by c))q where t1.a=q.a;
+
+--echo # multiple selects in derived table
+--echo # NO UNION ALL
+analyze select * from t1 , ( (select t2.a from t2 order by c) union (select t2.a from t2 order by c))q where t1.a=q.a;
+select * from t1 , ( (select t2.a from t2 order by c) union (select t2.a from t2 order by c))q where t1.a=q.a;
+
+--echo # UNION ALL and EXCEPT
+analyze select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a from t2 order by c) except(select t3.a from t3 order by b))q where t1.a=q.a;
+
+select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a from t2 order by c) except(select t3.a from t3 order by b))q where t1.a=q.a;
+
+drop table t1,t2,t3;
diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result
index 45de32d1ee1..28c3e2958e9 100644
--- a/mysql-test/main/derived_view.result
+++ b/mysql-test/main/derived_view.result
@@ -1525,7 +1525,7 @@ EXPLAIN
SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 1 FirstMatch(t1)
3 DERIVED t2 ALL NULL NULL NULL NULL 6
4 UNION t3 ALL NULL NULL NULL NULL 4
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
diff --git a/mysql-test/main/events_grant.result b/mysql-test/main/events_grant.result
index 51b80742737..cc7796975a6 100644
--- a/mysql-test/main/events_grant.result
+++ b/mysql-test/main/events_grant.result
@@ -23,7 +23,7 @@ SHOW GRANTS;
Grants for ev_test@localhost
GRANT USAGE ON *.* TO 'ev_test'@'localhost'
GRANT ALL PRIVILEGES ON `events_test`.* TO 'ev_test'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER, DELETE VERSIONING ROWS ON `events_test2`.* TO 'ev_test'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER, DELETE HISTORY ON `events_test2`.* TO 'ev_test'@'localhost'
"Here comes an error:";
SHOW EVENTS;
ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_test2'
diff --git a/mysql-test/main/func_gconcat.result b/mysql-test/main/func_gconcat.result
index 723a1952d79..1701bb364e8 100644
--- a/mysql-test/main/func_gconcat.result
+++ b/mysql-test/main/func_gconcat.result
@@ -1378,5 +1378,19 @@ group_concat(a,b limit ?)
1a,1b,2x,2y
drop table t2;
#
+# MDEV-18943: Group Concat with limit not working with views
+#
+create table t1 (a int, b varchar(10));
+insert into t1 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
+select group_concat(a,b limit 2) from t1;
+group_concat(a,b limit 2)
+1a,1b
+create view v1 as select group_concat(a,b limit 2) from t1;
+select * from v1;
+group_concat(a,b limit 2)
+1a,1b
+drop view v1;
+drop table t1;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/main/func_gconcat.test b/mysql-test/main/func_gconcat.test
index 5cbc6969e02..b8ab96bdea4 100644
--- a/mysql-test/main/func_gconcat.test
+++ b/mysql-test/main/func_gconcat.test
@@ -986,5 +986,17 @@ execute STMT using @x;
drop table t2;
--echo #
+--echo # MDEV-18943: Group Concat with limit not working with views
+--echo #
+
+create table t1 (a int, b varchar(10));
+insert into t1 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
+select group_concat(a,b limit 2) from t1;
+create view v1 as select group_concat(a,b limit 2) from t1;
+select * from v1;
+drop view v1;
+drop table t1;
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result
index 46d87a4777f..fad874d7d64 100644
--- a/mysql-test/main/grant.result
+++ b/mysql-test/main/grant.result
@@ -227,7 +227,7 @@ revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
flush privileges;
@@ -664,8 +664,8 @@ SELECT TABLE_SCHEMA, TABLE_NAME, GROUP_CONCAT(PRIVILEGE_TYPE ORDER BY
PRIVILEGE_TYPE SEPARATOR ', ') AS PRIVILEGES FROM TABLE_PRIVILEGES WHERE GRANTEE
= '\'dummy\'@\'localhost\'' GROUP BY TABLE_SCHEMA, TABLE_NAME;
TABLE_SCHEMA TABLE_NAME PRIVILEGES
-mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
-mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE HISTORY, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE HISTORY, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
FLUSH PRIVILEGES;
SHOW GRANTS FOR dummy@localhost;
Grants for dummy@localhost
@@ -676,8 +676,8 @@ SELECT TABLE_SCHEMA, TABLE_NAME, GROUP_CONCAT(PRIVILEGE_TYPE ORDER BY
PRIVILEGE_TYPE SEPARATOR ', ') AS PRIVILEGES FROM TABLE_PRIVILEGES WHERE GRANTEE
= '\'dummy\'@\'localhost\'' GROUP BY TABLE_SCHEMA, TABLE_NAME;
TABLE_SCHEMA TABLE_NAME PRIVILEGES
-mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
-mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE HISTORY, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE HISTORY, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
SHOW FIELDS FROM mysql.tables_priv;
Field Type Null Key Default Extra
Host char(60) NO PRI
diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result
index dd093aae5e9..b4d2d065d4a 100644
--- a/mysql-test/main/information_schema.result
+++ b/mysql-test/main/information_schema.result
@@ -493,7 +493,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_1'@'localhost' def test ALTER ROUTINE YES
'mysqltest_1'@'localhost' def test EVENT YES
'mysqltest_1'@'localhost' def test TRIGGER YES
-'mysqltest_1'@'localhost' def test DELETE VERSIONING ROWS YES
+'mysqltest_1'@'localhost' def test DELETE HISTORY YES
select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%';
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_1'@'localhost' def test t1 SELECT NO
diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result
index 681d6f1fca2..999ed500a84 100644
--- a/mysql-test/main/join_cache.result
+++ b/mysql-test/main/join_cache.result
@@ -5202,7 +5202,7 @@ SELECT * FROM (SELECT DISTINCT * FROM t1) t
WHERE t.a IN (SELECT t2.a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary
-1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 End temporary
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 1 End temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
SELECT * FROM (SELECT DISTINCT * FROM t1) t
WHERE t.a IN (SELECT t2.a FROM t2);
@@ -5213,8 +5213,8 @@ EXPLAIN
SELECT * FROM (SELECT DISTINCT * FROM t1) t
WHERE t.a IN (SELECT t2.a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
-1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 1 End temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
SELECT * FROM (SELECT DISTINCT * FROM t1) t
WHERE t.a IN (SELECT t2.a FROM t2);
diff --git a/mysql-test/main/subselect_extra.result b/mysql-test/main/subselect_extra.result
index edae4abfb3d..c654fdfca13 100644
--- a/mysql-test/main/subselect_extra.result
+++ b/mysql-test/main/subselect_extra.result
@@ -413,7 +413,7 @@ EXPLAIN
SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 1 FirstMatch(t1)
3 DERIVED t2 ALL NULL NULL NULL NULL 6
4 UNION t3 ALL NULL NULL NULL NULL 4
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
diff --git a/mysql-test/main/subselect_extra_no_semijoin.result b/mysql-test/main/subselect_extra_no_semijoin.result
index 8aca24b6097..faeaf75c590 100644
--- a/mysql-test/main/subselect_extra_no_semijoin.result
+++ b/mysql-test/main/subselect_extra_no_semijoin.result
@@ -415,7 +415,7 @@ EXPLAIN
SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 2 Using where
+2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 1 Using where
3 DERIVED t2 ALL NULL NULL NULL NULL 6
4 UNION t3 ALL NULL NULL NULL NULL 4
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
diff --git a/mysql-test/main/trigger.result b/mysql-test/main/trigger.result
index 1adf3c68a08..ab9dbc63888 100644
--- a/mysql-test/main/trigger.result
+++ b/mysql-test/main/trigger.result
@@ -1964,7 +1964,7 @@ ERROR HY000: Can't update table 't2' in stored function/trigger because it is al
DROP TABLE t1;
DROP TRIGGER t_insert;
DROP TABLE t2;
-End of 5.0 tests
+# End of 5.0 tests
drop table if exists table_25411_a;
drop table if exists table_25411_b;
create table table_25411_a(a int);
@@ -2135,7 +2135,7 @@ b
# Work around Bug#45235
DROP DATABASE db1;
USE test;
-End of 5.1 tests.
+# End of 5.1 tests.
create table t1 (i int);
create table t2 (i int);
flush tables;
@@ -2154,7 +2154,7 @@ select * from t2;
i
2
drop table t1,t2;
-End of 5.2 tests.
+# End of 5.2 tests.
#
# Bug#34453 Can't change size of file (Errcode: 1224)
#
@@ -2257,7 +2257,7 @@ c
aaa
DROP TABLE t1;
-End of 5.5 tests.
+# End of 5.5 tests.
#
# BUG #910083: materialized subquery in a trigger
#
@@ -2304,7 +2304,7 @@ b
SET optimizer_switch=@save_optimizer_switch;
DROP TRIGGER tr;
DROP TABLE t1, t2;
-End of 5.3 tests.
+# End of 5.3 tests.
set time_zone="+00:00";
SET TIMESTAMP=UNIX_TIMESTAMP('2001-01-01 10:20:30');
SET @@session.sql_mode = 'STRICT_ALL_TABLES,STRICT_TRANS_TABLES';
@@ -2411,7 +2411,24 @@ AFTER UPDATE ON t1 FOR EACH ROW SELECT (SELECT b FROM t2) INTO @x;
# Running 20000 queries
DROP TABLE t1,t2;
#
-# Start of 10.3 tests
+# MDEV-19188 Server Crash When Using a Trigger With A Number of Virtual Columns on INSERT/UPDATE
+#
+CREATE TABLE t1 (
+virt1 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt2 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt3 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt4 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt5 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt6 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt7 INT GENERATED ALWAYS AS (0) VIRTUAL,
+virt8 INT GENERATED ALWAYS AS (0) VIRTUAL
+);
+INSERT INTO t1 () VALUES ();
+CREATE TRIGGER t1_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
+INSERT INTO t1 () VALUES ();
+DROP TABLE t1;
+#
+# End of 10.2 tests
#
#
# MDEV-12461 TYPE OF and ROW TYPE OF anchored data types
@@ -2430,3 +2447,6 @@ SELECT * FROM t1;
a b total
10 20 30
DROP TABLE t1;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/trigger.test b/mysql-test/main/trigger.test
index 020117e046f..2eeab16ec5a 100644
--- a/mysql-test/main/trigger.test
+++ b/mysql-test/main/trigger.test
@@ -2184,7 +2184,7 @@ DROP TABLE t1;
DROP TRIGGER t_insert;
DROP TABLE t2;
---echo End of 5.0 tests
+--echo # End of 5.0 tests
#
# Bug#25411 (trigger code truncated)
@@ -2406,7 +2406,7 @@ let $MYSQLD_DATADIR = `select @@datadir`;
DROP DATABASE db1;
USE test;
---echo End of 5.1 tests.
+--echo # End of 5.1 tests.
#
# Test that using a trigger will not open mysql.proc
@@ -2430,7 +2430,7 @@ select * from t1;
select * from t2;
drop table t1,t2;
---echo End of 5.2 tests.
+--echo # End of 5.2 tests.
--echo #
--echo # Bug#34453 Can't change size of file (Errcode: 1224)
@@ -2574,7 +2574,7 @@ SELECT c FROM t1;
DROP TABLE t1;
--echo
---echo End of 5.5 tests.
+--echo # End of 5.5 tests.
--echo #
--echo # BUG #910083: materialized subquery in a trigger
@@ -2613,7 +2613,7 @@ SET optimizer_switch=@save_optimizer_switch;
DROP TRIGGER tr;
DROP TABLE t1, t2;
---echo End of 5.3 tests.
+--echo # End of 5.3 tests.
#
# MDEV-4829 BEFORE INSERT triggers dont issue 1406 error
@@ -2737,9 +2737,27 @@ while ($n)
DROP TABLE t1,t2;
+--echo #
+--echo # MDEV-19188 Server Crash When Using a Trigger With A Number of Virtual Columns on INSERT/UPDATE
+--echo #
+
+CREATE TABLE t1 (
+ virt1 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt2 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt3 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt4 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt5 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt6 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt7 INT GENERATED ALWAYS AS (0) VIRTUAL,
+ virt8 INT GENERATED ALWAYS AS (0) VIRTUAL
+);
+INSERT INTO t1 () VALUES ();
+CREATE TRIGGER t1_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
+INSERT INTO t1 () VALUES ();
+DROP TABLE t1;
--echo #
---echo # Start of 10.3 tests
+--echo # End of 10.2 tests
--echo #
--echo #
@@ -2760,3 +2778,7 @@ DELIMITER ;$$
INSERT INTO t1 (a,b) VALUES (10, 20);
SELECT * FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
index 690a24b7edd..02304fbda17 100644
--- a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
+++ b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
@@ -39,10 +39,6 @@ NAME ENCRYPTION_SCHEME CURRENT_KEY_ID
enctests/t7 0 1
enctests/t8 0 1
enctests/t9 0 1
-SET GLOBAL innodb_encrypt_tables=OFF;
-ERROR 42000: Variable 'innodb_encrypt_tables' can't be set to the value of 'OFF'
-SET GLOBAL innodb_encrypt_tables=ON;
-ERROR 42000: Variable 'innodb_encrypt_tables' can't be set to the value of 'ON'
# t1 default on expecting NOT FOUND
NOT FOUND /secred/ in t1.ibd
# t2 default on expecting NOT FOUND
diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result
new file mode 100644
index 00000000000..3dfa449daf8
--- /dev/null
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result
@@ -0,0 +1,80 @@
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(256))engine=innodb;
+INSERT INTO t1 VALUES(1, 'MariaDB'), (2, 'Robot'), (3, 'Science');
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2(f1 INT, f2 VARCHAR(256))engine=innodb;
+INSERT INTO t2 SELECT * FROM t1;
+CREATE TABLE t3(f1 INT, f2 VARCHAR(256))engine=innodb encrypted=yes;
+INSERT INTO t3 SELECT * FROM t1;
+# Restart the server with encryption
+# Wait until encryption threads have encrypted all tablespaces
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+NAME
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+NAME
+innodb_system
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+mysql/transaction_registry
+test/t1
+test/t2
+test/t3
+# Restart the server with innodb_encryption_rotate_key_age= 0
+create table t4 (f1 int not null)engine=innodb encrypted=NO;
+# Wait until encryption threads have encrypted all tablespaces
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+NAME
+test/t4
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+NAME
+innodb_system
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+mysql/transaction_registry
+test/t1
+test/t2
+test/t3
+# Disable encryption when innodb_encryption_rotate_key_age is 0
+set global innodb_encrypt_tables = OFF;
+# Wait until encryption threads to decrypt all unencrypted tablespaces
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+NAME
+innodb_system
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+mysql/transaction_registry
+test/t1
+test/t2
+test/t4
+# Display only encrypted create tables (t3)
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+NAME
+test/t3
+# Enable encryption when innodb_encryption_rotate_key_age is 0
+set global innodb_encrypt_tables = ON;
+# Wait until encryption threads to encrypt all unencrypted tablespaces
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+NAME
+test/t4
+# Display only unencrypted create tables (t4)
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+NAME
+innodb_system
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+mysql/transaction_registry
+test/t1
+test/t2
+test/t3
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+NAME
+test/t4
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+NAME
+innodb_system
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+mysql/transaction_registry
+test/t1
+test/t2
+test/t3
+DROP TABLE t4, t3, t2, t1;
diff --git a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
index 3167cee4b4b..dffabaf97f1 100644
--- a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
+++ b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
@@ -38,11 +38,6 @@ SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABL
--echo # should list tables t7-t9
SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 and NAME LIKE 'enctests%';
---error ER_WRONG_VALUE_FOR_VAR
-SET GLOBAL innodb_encrypt_tables=OFF;
---error ER_WRONG_VALUE_FOR_VAR
-SET GLOBAL innodb_encrypt_tables=ON;
-
--let $MYSQLD_DATADIR=`select @@datadir`
-- source include/shutdown_mysqld.inc
diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt
new file mode 100644
index 00000000000..6fa06402377
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt
@@ -0,0 +1,2 @@
+--innodb-tablespaces-encryption
+--innodb_encrypt_tables=ON
diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
new file mode 100644
index 00000000000..bc4c43e1ce8
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
@@ -0,0 +1,83 @@
+-- source include/have_innodb.inc
+-- source include/not_embedded.inc
+-- source include/have_example_key_management_plugin.inc
+
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(256))engine=innodb;
+INSERT INTO t1 VALUES(1, 'MariaDB'), (2, 'Robot'), (3, 'Science');
+INSERT INTO t1 SELECT * FROM t1;
+
+CREATE TABLE t2(f1 INT, f2 VARCHAR(256))engine=innodb;
+INSERT INTO t2 SELECT * FROM t1;
+
+CREATE TABLE t3(f1 INT, f2 VARCHAR(256))engine=innodb encrypted=yes;
+INSERT INTO t3 SELECT * FROM t1;
+
+--echo # Restart the server with encryption
+
+let $restart_noprint=2;
+let $restart_parameters= --innodb_encryption_threads=5 --innodb_encryption_rotate_key_age=16384;
+--source include/restart_mysqld.inc
+
+--echo # Wait until encryption threads have encrypted all tablespaces
+
+--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'`
+--let $wait_timeout= 600
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+--source include/wait_condition.inc
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+
+--echo # Restart the server with innodb_encryption_rotate_key_age= 0
+
+let $restart_parameters= --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=0;
+
+--source include/restart_mysqld.inc
+
+create table t4 (f1 int not null)engine=innodb encrypted=NO;
+
+--echo # Wait until encryption threads have encrypted all tablespaces
+
+--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
+--let $wait_timeout= 600
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+--source include/wait_condition.inc
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+
+--echo # Disable encryption when innodb_encryption_rotate_key_age is 0
+set global innodb_encrypt_tables = OFF;
+
+--echo # Wait until encryption threads to decrypt all unencrypted tablespaces
+
+--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
+--let $wait_timeout= 600
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING = 0;
+--source include/wait_condition.inc
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--echo # Display only encrypted create tables (t3)
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+
+--echo # Enable encryption when innodb_encryption_rotate_key_age is 0
+set global innodb_encrypt_tables = ON;
+
+--echo # Wait until encryption threads to encrypt all unencrypted tablespaces
+
+--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
+--let $wait_timeout= 600
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+--source include/wait_condition.inc
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--echo # Display only unencrypted create tables (t4)
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+
+--let $restart_parameters=
+-- source include/restart_mysqld.inc
+
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+DROP TABLE t4, t3, t2, t1;
diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03.result b/mysql-test/suite/funcs_1/r/innodb_trig_03.result
index 7666b86bc94..be235c2d4ae 100644
--- a/mysql-test/suite/funcs_1/r/innodb_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/innodb_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
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 90dabe044e8..aea34df6356 100644
--- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result
@@ -603,7 +603,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -656,7 +656,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -929,7 +929,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE HISTORY ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/funcs_1/r/is_column_privileges.result b/mysql-test/suite/funcs_1/r/is_column_privileges.result
index 033fb64f689..c835864e738 100644
--- a/mysql-test/suite/funcs_1/r/is_column_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_column_privileges.result
@@ -140,7 +140,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
'testuser3'@'localhost' def db_datadict CREATE TEMPORARY TABLES NO
'testuser3'@'localhost' def db_datadict CREATE VIEW NO
'testuser3'@'localhost' def db_datadict DELETE NO
-'testuser3'@'localhost' def db_datadict DELETE VERSIONING ROWS NO
+'testuser3'@'localhost' def db_datadict DELETE HISTORY NO
'testuser3'@'localhost' def db_datadict DROP NO
'testuser3'@'localhost' def db_datadict EVENT NO
'testuser3'@'localhost' def db_datadict EXECUTE NO
diff --git a/mysql-test/suite/funcs_1/r/is_schema_privileges.result b/mysql-test/suite/funcs_1/r/is_schema_privileges.result
index 1339639106f..3daac8b2c5f 100644
--- a/mysql-test/suite/funcs_1/r/is_schema_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_schema_privileges.result
@@ -68,7 +68,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE
''@'%' def test CREATE ROUTINE
''@'%' def test EVENT
''@'%' def test TRIGGER
-''@'%' def test DELETE VERSIONING ROWS
+''@'%' def test DELETE HISTORY
''@'%' def test\_% SELECT
''@'%' def test\_% INSERT
''@'%' def test\_% UPDATE
@@ -85,7 +85,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE
''@'%' def test\_% CREATE ROUTINE
''@'%' def test\_% EVENT
''@'%' def test\_% TRIGGER
-''@'%' def test\_% DELETE VERSIONING ROWS
+''@'%' def test\_% DELETE HISTORY
###############################################################################
# Testcase 3.2.15.2-3.2.15.4 INFORMATION_SCHEMA.SCHEMA_PRIVILEGES accessibility
###############################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result b/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
index 528a770e0eb..2b285395cff 100644
--- a/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
+++ b/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
@@ -16,7 +16,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
''@'%' def test CREATE TEMPORARY TABLES NO
''@'%' def test CREATE VIEW NO
''@'%' def test DELETE NO
-''@'%' def test DELETE VERSIONING ROWS NO
+''@'%' def test DELETE HISTORY NO
''@'%' def test DROP NO
''@'%' def test EVENT NO
''@'%' def test INDEX NO
diff --git a/mysql-test/suite/funcs_1/r/is_table_privileges.result b/mysql-test/suite/funcs_1/r/is_table_privileges.result
index c448241e14e..1d54ef75297 100644
--- a/mysql-test/suite/funcs_1/r/is_table_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_table_privileges.result
@@ -96,7 +96,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser2'@'localhost' def db_datadict tb1 CREATE YES
'testuser2'@'localhost' def db_datadict tb1 CREATE VIEW YES
'testuser2'@'localhost' def db_datadict tb1 DELETE YES
-'testuser2'@'localhost' def db_datadict tb1 DELETE VERSIONING ROWS YES
+'testuser2'@'localhost' def db_datadict tb1 DELETE HISTORY YES
'testuser2'@'localhost' def db_datadict tb1 DROP YES
'testuser2'@'localhost' def db_datadict tb1 INDEX YES
'testuser2'@'localhost' def db_datadict tb1 INSERT YES
@@ -132,7 +132,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser2'@'localhost' def db_datadict tb1 CREATE YES
'testuser2'@'localhost' def db_datadict tb1 CREATE VIEW YES
'testuser2'@'localhost' def db_datadict tb1 DELETE YES
-'testuser2'@'localhost' def db_datadict tb1 DELETE VERSIONING ROWS YES
+'testuser2'@'localhost' def db_datadict tb1 DELETE HISTORY YES
'testuser2'@'localhost' def db_datadict tb1 DROP YES
'testuser2'@'localhost' def db_datadict tb1 INDEX YES
'testuser2'@'localhost' def db_datadict tb1 INSERT YES
@@ -186,7 +186,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser1'@'localhost' def test t1_table CREATE NO
'testuser1'@'localhost' def test t1_table CREATE VIEW NO
'testuser1'@'localhost' def test t1_table DELETE NO
-'testuser1'@'localhost' def test t1_table DELETE VERSIONING ROWS NO
+'testuser1'@'localhost' def test t1_table DELETE HISTORY NO
'testuser1'@'localhost' def test t1_table DROP NO
'testuser1'@'localhost' def test t1_table INDEX NO
'testuser1'@'localhost' def test t1_table INSERT NO
@@ -199,7 +199,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser1'@'localhost' def test t1_view CREATE NO
'testuser1'@'localhost' def test t1_view CREATE VIEW NO
'testuser1'@'localhost' def test t1_view DELETE NO
-'testuser1'@'localhost' def test t1_view DELETE VERSIONING ROWS NO
+'testuser1'@'localhost' def test t1_view DELETE HISTORY NO
'testuser1'@'localhost' def test t1_view DROP NO
'testuser1'@'localhost' def test t1_view INDEX NO
'testuser1'@'localhost' def test t1_view INSERT NO
diff --git a/mysql-test/suite/funcs_1/r/is_triggers.result b/mysql-test/suite/funcs_1/r/is_triggers.result
index 1ea7263eb8f..e9b6b31451a 100644
--- a/mysql-test/suite/funcs_1/r/is_triggers.result
+++ b/mysql-test/suite/funcs_1/r/is_triggers.result
@@ -145,7 +145,7 @@ connect testuser2, localhost, testuser2, , db_datadict;
SHOW GRANTS FOR 'testuser2'@'localhost';
Grants for testuser2@localhost
GRANT USAGE ON *.* TO 'testuser2'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, DELETE VERSIONING ROWS ON `db_datadict`.`t1` TO 'testuser2'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, DELETE HISTORY ON `db_datadict`.`t1` TO 'testuser2'@'localhost'
# No TRIGGER Privilege --> no result for query
SELECT * FROM information_schema.triggers
WHERE trigger_name = 'trg1';
diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03.result b/mysql-test/suite/funcs_1/r/memory_trig_03.result
index b86315a1a7d..acab98b0cdc 100644
--- a/mysql-test/suite/funcs_1/r/memory_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/memory_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
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 ea0aaf0c86f..b1c017d368b 100644
--- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result
@@ -604,7 +604,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -657,7 +657,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -930,7 +930,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE HISTORY ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03.result b/mysql-test/suite/funcs_1/r/myisam_trig_03.result
index b86315a1a7d..acab98b0cdc 100644
--- a/mysql-test/suite/funcs_1/r/myisam_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/myisam_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE HISTORY ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE HISTORY ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
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 60e6031f0e2..8a42a54b1be 100644
--- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result
@@ -604,7 +604,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -657,7 +657,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE HISTORY ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -930,7 +930,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE HISTORY ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/innodb/r/page_reorganize.result b/mysql-test/suite/innodb/r/page_reorganize.result
new file mode 100644
index 00000000000..1059fc78531
--- /dev/null
+++ b/mysql-test/suite/innodb/r/page_reorganize.result
@@ -0,0 +1,27 @@
+#
+# Bug# 20005279 ASSERT !OTHER_LOCK, LOCK_MOVE_REORGANIZE_PAGE()
+#
+create table t1 (f1 int auto_increment primary key,
+f2 char(255)) engine=innodb;
+start transaction;
+commit;
+start transaction;
+select f1, f2 from t1 where f1 = 20 for update;
+f1 f2
+20 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+connect con1,localhost,root,,;
+select f1 from t1 where f1 = 20 for update;
+connection default;
+SET @save_dbug = @@debug_dbug;
+SET DEBUG_DBUG = '+d,do_page_reorganize,do_lock_reverse_page_reorganize';
+insert into t1(f2) values (repeat('+', 100));
+SET DEBUG = @save_dbug;
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+commit;
+connection con1;
+f1
+20
+disconnect con1;
+connection default;
+drop table t1;
diff --git a/mysql-test/suite/innodb/t/page_reorganize.test b/mysql-test/suite/innodb/t/page_reorganize.test
new file mode 100644
index 00000000000..7408353976d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/page_reorganize.test
@@ -0,0 +1,56 @@
+--source include/have_innodb.inc
+--source include/have_innodb_16k.inc
+--source include/have_debug.inc
+
+--source include/count_sessions.inc
+
+--echo #
+--echo # Bug# 20005279 ASSERT !OTHER_LOCK, LOCK_MOVE_REORGANIZE_PAGE()
+--echo #
+
+create table t1 (f1 int auto_increment primary key,
+ f2 char(255)) engine=innodb;
+
+let $inc = 50;
+
+start transaction;
+--disable_query_log
+
+while ($inc)
+{
+ insert into t1(f2) values (repeat('~', 50));
+ dec $inc;
+}
+
+--enable_query_log
+commit;
+
+start transaction;
+select f1, f2 from t1 where f1 = 20 for update;
+
+connect (con1,localhost,root,,);
+--send
+select f1 from t1 where f1 = 20 for update;
+
+connection default;
+
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where INFO = 'select f1 from t1 where f1 = 20 for update';
+
+--source include/wait_condition.inc
+
+SET @save_dbug = @@debug_dbug;
+SET DEBUG_DBUG = '+d,do_page_reorganize,do_lock_reverse_page_reorganize';
+insert into t1(f2) values (repeat('+', 100));
+SET DEBUG = @save_dbug;
+commit;
+
+connection con1;
+reap;
+disconnect con1;
+connection default;
+
+drop table t1;
+
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_2.result b/mysql-test/suite/innodb_zip/r/innochecksum_2.result
index 582bb42f0cb..bfd03c72f12 100644
--- a/mysql-test/suite/innodb_zip/r/innochecksum_2.result
+++ b/mysql-test/suite/innodb_zip/r/innochecksum_2.result
@@ -43,10 +43,12 @@ Copyright (c) YEAR, YEAR , Oracle, MariaDB Corporation Ab and others.
InnoDB offline file checksum utility.
Usage: innochecksum [-c] [-s <start page>] [-e <end page>] [-p <page>] [-i] [-v] [-a <allow mismatches>] [-n] [-C <strict-check>] [-w <write>] [-S] [-D <page type dump>] [-l <log>] [-l] [-m <merge pages>] <filename or [-]>
+See https://mariadb.com/kb/en/library/innochecksum/ for usage hints.
-?, --help Displays this help and exits.
-I, --info Synonym for --help.
-V, --version Displays version information and exits.
-v, --verbose Verbose (prints progress every 5 seconds).
+ https://mariadb.com/kb/en/library/creating-a-trace-file/
-c, --count Print the count of pages in the file and exits.
-s, --start-page=# Start on this page number (0 based).
-e, --end-page=# End at this page number (0 based).
diff --git a/mysql-test/suite/mariabackup/backup_grants.result b/mysql-test/suite/mariabackup/backup_grants.result
index d8869b7ac82..ed793e7ff1a 100644
--- a/mysql-test/suite/mariabackup/backup_grants.result
+++ b/mysql-test/suite/mariabackup/backup_grants.result
@@ -1,5 +1,6 @@
CREATE user backup@localhost;
FOUND 1 /missing required privilege RELOAD/ in backup.log
FOUND 1 /missing required privilege PROCESS/ in backup.log
+FOUND 1 /GRANT USAGE ON/ in backup.log
GRANT RELOAD, PROCESS on *.* to backup@localhost;
DROP USER backup@localhost;
diff --git a/mysql-test/suite/mariabackup/backup_grants.test b/mysql-test/suite/mariabackup/backup_grants.test
index 1c0c3f89346..eadeedd9b5f 100644
--- a/mysql-test/suite/mariabackup/backup_grants.test
+++ b/mysql-test/suite/mariabackup/backup_grants.test
@@ -18,7 +18,8 @@ let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log;
--source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= missing required privilege PROCESS
--source include/search_pattern_in_file.inc
-
+--let SEARCH_PATTERN= GRANT USAGE ON
+--source include/search_pattern_in_file.inc
# backup succeeds with RELOAD privilege
GRANT RELOAD, PROCESS on *.* to backup@localhost;
--disable_result_log
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index b63419a6e9f..02c2b872ebc 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -21,6 +21,16 @@ set global server_audit_incl_users=null;
set global server_audit_file_path='server_audit.log';
set global server_audit_output_type=file;
set global server_audit_logging=on;
+set global server_audit_incl_users= repeat("'root',", 10000);
+ERROR 42000: Variable 'server_audit_incl_users' can't be set to the value of ''root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','roo'
+show variables like 'server_audit_incl_users';
+Variable_name Value
+server_audit_incl_users
+set global server_audit_excl_users= repeat("'root',", 10000);
+ERROR 42000: Variable 'server_audit_excl_users' can't be set to the value of ''root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','root','roo'
+show variables like 'server_audit_excl_users';
+Variable_name Value
+server_audit_excl_users
connect con1,localhost,root,,mysql;
connection default;
disconnect con1;
@@ -202,6 +212,8 @@ select 2;
2
2
drop table t1;
+set global server_audit_logging= off;
+set global server_audit_logging= on;
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
select (1), (2), (3), (4);
@@ -251,6 +263,10 @@ uninstall plugin server_audit;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users= repeat("\'root\',", 10000)',ID
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'show variables like \'server_audit_incl_users\'',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_excl_users= repeat("\'root\',", 10000)',ID
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'show variables like \'server_audit_excl_users\'',0
TIME,HOSTNAME,root,localhost,ID,0,CONNECT,mysql,,0
TIME,HOSTNAME,root,localhost,ID,0,DISCONNECT,mysql,,0
TIME,HOSTNAME,no_such_user,localhost,ID,0,FAILED_CONNECT,,,ID
@@ -376,6 +392,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_logging= off',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 4af1ed883e3..f19c8f53b61 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -13,6 +13,14 @@ set global server_audit_incl_users=null;
set global server_audit_file_path='server_audit.log';
set global server_audit_output_type=file;
set global server_audit_logging=on;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set global server_audit_incl_users= repeat("'root',", 10000);
+show variables like 'server_audit_incl_users';
+--error ER_WRONG_VALUE_FOR_VAR
+set global server_audit_excl_users= repeat("'root',", 10000);
+show variables like 'server_audit_excl_users';
+
--sleep 2
connect (con1,localhost,root,,mysql);
connection default;
@@ -128,6 +136,9 @@ select * from t1;
select 2;
drop table t1;
+set global server_audit_logging= off;
+set global server_audit_logging= on;
+
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
diff --git a/mysql-test/suite/versioning/r/truncate_privilege.result b/mysql-test/suite/versioning/r/truncate_privilege.result
index e378407afde..3242c4557c5 100644
--- a/mysql-test/suite/versioning/r/truncate_privilege.result
+++ b/mysql-test/suite/versioning/r/truncate_privilege.result
@@ -11,7 +11,7 @@ show grants;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
delete history from mysqltest.t before system_time now();
-ERROR 42000: DELETE VERSIONING ROWS command denied to user 'mysqltest_1'@'localhost' for table 't'
+ERROR 42000: DELETE HISTORY command denied to user 'mysqltest_1'@'localhost' for table 't'
connection root;
grant delete history on mysqltest.* to mysqltest_1@localhost;
grant delete history on mysqltest.t to mysqltest_1@localhost;
@@ -19,15 +19,15 @@ connection user1;
show grants;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
-GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
+GRANT DELETE HISTORY ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE HISTORY ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
delete history from mysqltest.t before system_time now();
connection root;
grant all on *.* to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'localhost'
-GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
-GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
+GRANT DELETE HISTORY ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE HISTORY ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
drop user mysqltest_1@localhost;
drop database mysqltest;
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index bbba2f86e68..fe0878bdaa1 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.4"
+#define PLUGIN_STR_VERSION "1.4.5"
#define _my_thread_var loc_thread_var
@@ -333,6 +333,10 @@ static void update_file_rotations(MYSQL_THD thd, struct st_mysql_sys_var *var,
void *var_ptr, const void *save);
static void update_incl_users(MYSQL_THD thd, struct st_mysql_sys_var *var,
void *var_ptr, const void *save);
+static int check_incl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save,
+ struct st_mysql_value *value);
+static int check_excl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save,
+ struct st_mysql_value *value);
static void update_excl_users(MYSQL_THD thd, struct st_mysql_sys_var *var,
void *var_ptr, const void *save);
static void update_output_type(MYSQL_THD thd, struct st_mysql_sys_var *var,
@@ -352,10 +356,10 @@ static void rotate_log(MYSQL_THD thd, struct st_mysql_sys_var *var,
static MYSQL_SYSVAR_STR(incl_users, incl_users, PLUGIN_VAR_RQCMDARG,
"Comma separated list of users to monitor.",
- NULL, update_incl_users, NULL);
+ check_incl_users, update_incl_users, NULL);
static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG,
"Comma separated list of users to exclude from auditing.",
- NULL, update_excl_users, NULL);
+ check_excl_users, update_excl_users, NULL);
/* bits in the event filter. */
#define EVENT_CONNECT 1
#define EVENT_QUERY_ALL 2
@@ -1621,7 +1625,7 @@ static int log_statement_ex(const struct connection_info *cn,
}
if (query && !(events & EVENT_QUERY_ALL) &&
- (events & EVENT_QUERY))
+ (events & EVENT_QUERY && !cn->log_always))
{
const char *orig_query= query;
@@ -2555,9 +2559,10 @@ static void log_current_query(MYSQL_THD thd)
if (!ci_needs_setup(cn) && cn->query_length &&
FILTER(EVENT_QUERY) && do_log_user(cn->user))
{
+ cn->log_always= 1;
log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd),
cn->query, cn->query_length, 0, "QUERY");
- cn->log_always= 1;
+ cn->log_always= 0;
}
}
@@ -2646,16 +2651,56 @@ static void update_file_rotate_size(MYSQL_THD thd __attribute__((unused)),
}
+static int check_users(void *save, struct st_mysql_value *value,
+ size_t s, const char *name)
+{
+ const char *users;
+ int len= 0;
+
+ users= value->val_str(value, NULL, &len);
+ if ((size_t) len > s)
+ {
+ error_header();
+ fprintf(stderr,
+ "server_audit_%s_users value can't be longer than %zu characters.\n",
+ name, s);
+ return 1;
+ }
+ *((const char**)save)= users;
+ return 0;
+}
+
+static int check_incl_users(MYSQL_THD thd __attribute__((unused)),
+ struct st_mysql_sys_var *var __attribute__((unused)),
+ void *save, struct st_mysql_value *value)
+{
+ return check_users(save, value, sizeof(incl_user_buffer), "incl");
+}
+
+static int check_excl_users(MYSQL_THD thd __attribute__((unused)),
+ struct st_mysql_sys_var *var __attribute__((unused)),
+ void *save, struct st_mysql_value *value)
+{
+ return check_users(save, value, sizeof(excl_user_buffer), "excl");
+}
+
+
static void update_incl_users(MYSQL_THD thd,
struct st_mysql_sys_var *var __attribute__((unused)),
void *var_ptr __attribute__((unused)), const void *save)
{
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
+ size_t new_len= strlen(new_users) + 1;
if (!maria_55_started || !debug_server_started)
flogger_mutex_lock(&lock_operations);
mark_always_logged(thd);
- strncpy(incl_user_buffer, new_users, sizeof(incl_user_buffer)-1);
- incl_user_buffer[sizeof(incl_user_buffer)-1]= 0;
+
+ if (new_len > sizeof(incl_user_buffer))
+ new_len= sizeof(incl_user_buffer);
+
+ memcpy(incl_user_buffer, new_users, new_len - 1);
+ incl_user_buffer[new_len - 1]= 0;
+
incl_users= incl_user_buffer;
user_coll_fill(&incl_user_coll, incl_users, &excl_user_coll, 1);
error_header();
@@ -2670,11 +2715,17 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)),
void *var_ptr __attribute__((unused)), const void *save)
{
char *new_users= (*(char **) save) ? *(char **) save : empty_str;
+ size_t new_len= strlen(new_users) + 1;
if (!maria_55_started || !debug_server_started)
flogger_mutex_lock(&lock_operations);
mark_always_logged(thd);
- strncpy(excl_user_buffer, new_users, sizeof(excl_user_buffer)-1);
- excl_user_buffer[sizeof(excl_user_buffer)-1]= 0;
+
+ if (new_len > sizeof(excl_user_buffer))
+ new_len= sizeof(excl_user_buffer);
+
+ memcpy(excl_user_buffer, new_users, new_len - 1);
+ excl_user_buffer[new_len - 1]= 0;
+
excl_users= excl_user_buffer;
user_coll_fill(&excl_user_coll, excl_users, &incl_user_coll, 0);
error_header();
diff --git a/sql/item.cc b/sql/item.cc
index e511921b30b..72231497a22 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2018, Oracle and/or its affiliates.
- Copyright (c) 2010, 2018, MariaDB Corporation
+ Copyright (c) 2010, 2019, 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
@@ -265,6 +265,15 @@ longlong Item::val_int_unsigned_typecast_from_str()
}
+longlong Item::val_int_signed_typecast_from_int()
+{
+ longlong value= val_int();
+ if (!null_value && unsigned_flag && value < 0)
+ push_note_converted_to_negative_complement(current_thd);
+ return value;
+}
+
+
longlong Item::val_int_unsigned_typecast_from_int()
{
longlong value= val_int();
diff --git a/sql/item.h b/sql/item.h
index b2f66b5292c..ec474b81a08 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1247,6 +1247,13 @@ public:
}
longlong val_int_unsigned_typecast_from_int();
longlong val_int_unsigned_typecast_from_str();
+
+ /**
+ Get a value for CAST(x AS UNSIGNED).
+ Huge positive unsigned values are converted to negative complements.
+ */
+ longlong val_int_signed_typecast_from_int();
+
/*
This is just a shortcut to avoid the cast. You should still use
unsigned_flag to check the sign of the item.
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index e4063f9ef83..e1c8af98dd7 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -4134,7 +4134,19 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type)
}
str->append(STRING_WITH_LEN(" separator \'"));
str->append_for_single_quote(separator->ptr(), separator->length());
- str->append(STRING_WITH_LEN("\')"));
+ str->append(STRING_WITH_LEN("\'"));
+
+ if (limit_clause)
+ {
+ str->append(STRING_WITH_LEN(" limit "));
+ if (offset_limit)
+ {
+ offset_limit->print(str, query_type);
+ str->append(',');
+ }
+ row_limit->print(str, query_type);
+ }
+ str->append(STRING_WITH_LEN(")"));
}
diff --git a/sql/lock.cc b/sql/lock.cc
index fe745b49003..d53aad5a2ba 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -253,16 +253,11 @@ static void track_table_access(THD *thd, TABLE **tables, size_t count)
{
if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
{
- Transaction_state_tracker *tst= (Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
-
while (count--)
{
- TABLE *t= tables[count];
-
- if (t)
- tst->add_trx_state(thd, t->reginfo.lock_type,
- t->file->has_transaction_manager());
+ if (TABLE *t= tables[count])
+ thd->session_tracker.transaction_info.add_trx_state(thd,
+ t->reginfo.lock_type, t->file->has_transaction_manager());
}
}
}
diff --git a/sql/log.cc b/sql/log.cc
index 9f724534e6e..aa63736b796 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -7964,6 +7964,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
*/
for (current= queue; current != NULL; current= current->next)
{
+ set_current_thd(current->thd);
binlog_cache_mngr *cache_mngr= current->cache_mngr;
/*
@@ -7999,6 +8000,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
cache_mngr->delayed_error= false;
}
}
+ set_current_thd(leader->thd);
bool synced= 0;
if (unlikely(flush_and_sync(&synced)))
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bfa03aa57c1..dbe6055d387 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -889,6 +889,7 @@ PSI_mutex_key key_LOCK_relaylog_end_pos;
PSI_mutex_key key_LOCK_thread_id;
PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
+PSI_mutex_key key_LOCK_rpl_semi_sync_master_enabled;
PSI_mutex_key key_LOCK_binlog;
PSI_mutex_key key_LOCK_stats,
@@ -983,6 +984,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
{ &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0},
{ &key_LOCK_ack_receiver, "Ack_receiver::mutex", 0},
+ { &key_LOCK_rpl_semi_sync_master_enabled, "LOCK_rpl_semi_sync_master_enabled", 0},
{ &key_LOCK_binlog, "LOCK_binlog", 0}
};
@@ -2724,9 +2726,8 @@ static bool cache_thread(THD *thd)
Create new instrumentation for the new THD job,
and attach it to this running pthread.
*/
- PSI_thread *psi= PSI_CALL_new_thread(key_thread_one_connection,
- thd, thd->thread_id);
- PSI_CALL_set_thread(psi);
+ PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection,
+ thd, thd->thread_id));
/* reset abort flag for the thread */
thd->mysys_var->abort= 0;
@@ -5194,14 +5195,8 @@ static int init_server_components()
#endif
#ifndef EMBEDDED_LIBRARY
- {
- if (Session_tracker::server_boot_verify(system_charset_info))
- {
- sql_print_error("The variable session_track_system_variables has "
- "invalid values.");
- unireg_abort(1);
- }
- }
+ if (session_tracker_init())
+ return 1;
#endif //EMBEDDED_LIBRARY
/* we do want to exit if there are any other unknown options */
diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc
index 4e37e3af58d..f9fb4d9147d 100644
--- a/sql/semisync_master.cc
+++ b/sql/semisync_master.cc
@@ -352,7 +352,7 @@ Repl_semi_sync_master::Repl_semi_sync_master()
int Repl_semi_sync_master::init_object()
{
- int result;
+ int result= 0;
m_init_done = true;
@@ -362,6 +362,8 @@ int Repl_semi_sync_master::init_object()
set_wait_point(rpl_semi_sync_master_wait_point);
/* Mutex initialization can only be done after MY_INIT(). */
+ mysql_mutex_init(key_LOCK_rpl_semi_sync_master_enabled,
+ &LOCK_rpl_semi_sync_master_enabled, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_binlog,
&LOCK_binlog, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_binlog_send,
@@ -383,7 +385,7 @@ int Repl_semi_sync_master::init_object()
}
else
{
- result = disable_master();
+ disable_master();
}
return result;
@@ -421,7 +423,7 @@ int Repl_semi_sync_master::enable_master()
return result;
}
-int Repl_semi_sync_master::disable_master()
+void Repl_semi_sync_master::disable_master()
{
/* Must have the lock when we do enable of disable. */
lock();
@@ -446,14 +448,13 @@ int Repl_semi_sync_master::disable_master()
}
unlock();
-
- return 0;
}
void Repl_semi_sync_master::cleanup()
{
if (m_init_done)
{
+ mysql_mutex_destroy(&LOCK_rpl_semi_sync_master_enabled);
mysql_mutex_destroy(&LOCK_binlog);
mysql_cond_destroy(&COND_binlog_send);
m_init_done= 0;
diff --git a/sql/semisync_master.h b/sql/semisync_master.h
index de5e3240802..517175b5b06 100644
--- a/sql/semisync_master.h
+++ b/sql/semisync_master.h
@@ -23,6 +23,7 @@
#include "semisync_master_ack_receiver.h"
#ifdef HAVE_PSI_INTERFACE
+extern PSI_mutex_key key_LOCK_rpl_semi_sync_master_enabled;
extern PSI_mutex_key key_LOCK_binlog;
extern PSI_cond_key key_COND_binlog_send;
#endif
@@ -365,7 +366,6 @@ public:
*/
class Repl_semi_sync_master
:public Repl_semi_sync_base {
- private:
Active_tranx *m_active_tranxs; /* active transaction list: the list will
be cleared when semi-sync switches off. */
@@ -491,8 +491,8 @@ class Repl_semi_sync_master
/* Enable the object to enable semi-sync replication inside the master. */
int enable_master();
- /* Enable the object to enable semi-sync replication inside the master. */
- int disable_master();
+ /* Disable the object to disable semi-sync replication inside the master. */
+ void disable_master();
/* Add a semi-sync replication slave */
void add_slave();
@@ -619,6 +619,8 @@ class Repl_semi_sync_master
int before_reset_master();
void check_and_switch();
+
+ mysql_mutex_t LOCK_rpl_semi_sync_master_enabled;
};
enum rpl_semi_sync_master_wait_point_t {
diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc
index 0ef0b5229ca..e189fc5f631 100644
--- a/sql/semisync_master_ack_receiver.cc
+++ b/sql/semisync_master_ack_receiver.cc
@@ -185,8 +185,7 @@ static void init_net(NET *net, unsigned char *buff, unsigned int buff_len)
void Ack_receiver::run()
{
- // skip LOCK_global_system_variables due to the 3rd arg
- THD *thd= new THD(next_thread_id(), false, true);
+ THD *thd= new THD(next_thread_id());
NET net;
unsigned char net_buff[REPLY_MESSAGE_MAX_LENGTH];
diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc
index 0088f1b20de..1566c2d7ade 100644
--- a/sql/session_tracker.cc
+++ b/sql/session_tracker.cc
@@ -15,10 +15,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#ifndef EMBEDDED_LIBRARY
#include "sql_plugin.h"
-#include "session_tracker.h"
-
#include "hash.h"
#include "table.h"
#include "rpl_gtid.h"
@@ -35,264 +32,12 @@ void State_tracker::mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name)
}
-class Not_implemented_tracker : public State_tracker
-{
-public:
- bool enable(THD *thd)
- { return false; }
- bool update(THD *, set_var *)
- { return false; }
- bool store(THD *, String *)
- { return false; }
- void mark_as_changed(THD *, LEX_CSTRING *tracked_item_name)
- {}
-
-};
-
-/**
- Session_sysvars_tracker
-
- This is a tracker class that enables & manages the tracking of session
- system variables. It internally maintains a hash of user supplied variable
- references and a boolean field to store if the variable was changed by the
- last statement.
-*/
-
-class Session_sysvars_tracker : public State_tracker
-{
-private:
-
- struct sysvar_node_st {
- sys_var *m_svar;
- bool *test_load;
- bool m_changed;
- };
-
- class vars_list
- {
- private:
- /**
- Registered system variables. (@@session_track_system_variables)
- A hash to store the name of all the system variables specified by the
- user.
- */
- HASH m_registered_sysvars;
- /** Size of buffer for string representation */
- size_t buffer_length;
- myf m_mem_flag;
- /**
- If TRUE then we want to check all session variable.
- */
- bool track_all;
- void init()
- {
- my_hash_init(&m_registered_sysvars,
- &my_charset_bin,
- 4, 0, 0, (my_hash_get_key) sysvars_get_key,
- my_free, MYF(HASH_UNIQUE |
- ((m_mem_flag & MY_THREAD_SPECIFIC) ?
- HASH_THREAD_SPECIFIC : 0)));
- }
- void free_hash()
- {
- if (my_hash_inited(&m_registered_sysvars))
- {
- my_hash_free(&m_registered_sysvars);
- }
- }
-
- uchar* search(const sys_var *svar)
- {
- return (my_hash_search(&m_registered_sysvars, (const uchar *)&svar,
- sizeof(sys_var *)));
- }
-
- public:
- vars_list() :
- buffer_length(0)
- {
- m_mem_flag= current_thd ? MY_THREAD_SPECIFIC : 0;
- init();
- }
-
- size_t get_buffer_length()
- {
- DBUG_ASSERT(buffer_length != 0); // asked earlier then should
- return buffer_length;
- }
- ~vars_list()
- {
- /* free the allocated hash. */
- if (my_hash_inited(&m_registered_sysvars))
- {
- my_hash_free(&m_registered_sysvars);
- }
- }
-
- uchar* insert_or_search(sysvar_node_st *node, const sys_var *svar)
- {
- uchar *res;
- res= search(svar);
- if (!res)
- {
- if (track_all)
- {
- insert(node, svar, m_mem_flag);
- return search(svar);
- }
- }
- return res;
- }
-
- bool insert(sysvar_node_st *node, const sys_var *svar, myf mem_flag);
- void reinit();
- void reset();
- inline bool is_enabled()
- {
- return track_all || m_registered_sysvars.records;
- }
- void copy(vars_list* from, THD *thd);
- bool parse_var_list(THD *thd, LEX_STRING var_list, bool throw_error,
- CHARSET_INFO *char_set, bool take_mutex);
- bool construct_var_list(char *buf, size_t buf_len);
- bool store(THD *thd, String *buf);
- };
- /**
- Two objects of vars_list type are maintained to manage
- various operations.
- */
- vars_list *orig_list, *tool_list;
-
-public:
- Session_sysvars_tracker()
- {
- orig_list= new (std::nothrow) vars_list();
- tool_list= new (std::nothrow) vars_list();
- }
-
- ~Session_sysvars_tracker()
- {
- if (orig_list)
- delete orig_list;
- if (tool_list)
- delete tool_list;
- }
-
- size_t get_buffer_length()
- {
- return orig_list->get_buffer_length();
- }
- bool construct_var_list(char *buf, size_t buf_len)
- {
- return orig_list->construct_var_list(buf, buf_len);
- }
-
- /**
- Method used to check the validity of string provided
- for session_track_system_variables during the server
- startup.
- */
- static bool server_init_check(THD *thd, CHARSET_INFO *char_set,
- LEX_STRING var_list)
- {
- return check_var_list(thd, var_list, false, char_set, false);
- }
-
- static bool server_init_process(THD *thd, CHARSET_INFO *char_set,
- LEX_STRING var_list)
- {
- vars_list dummy;
- bool result;
- result= dummy.parse_var_list(thd, var_list, false, char_set, false);
- if (!result)
- dummy.construct_var_list(var_list.str, var_list.length + 1);
- return result;
- }
-
- void reset();
- bool enable(THD *thd);
- bool check_str(THD *thd, LEX_STRING *val);
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
- void mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name);
- /* callback */
- static uchar *sysvars_get_key(const char *entry, size_t *length,
- my_bool not_used __attribute__((unused)));
-
- // hash iterators
- static my_bool name_array_filler(void *ptr, void *data_ptr);
- static my_bool store_variable(void *ptr, void *data_ptr);
- static my_bool reset_variable(void *ptr, void *data_ptr);
-
- static bool check_var_list(THD *thd, LEX_STRING var_list, bool throw_error,
- CHARSET_INFO *char_set, bool take_mutex);
-};
-
-
-
-/**
- Current_schema_tracker,
-
- This is a tracker class that enables & manages the tracking of current
- schema for a particular connection.
-*/
-
-class Current_schema_tracker : public State_tracker
-{
-private:
- bool schema_track_inited;
- void reset();
-
-public:
-
- Current_schema_tracker()
- {
- schema_track_inited= false;
- }
-
- bool enable(THD *thd)
- { return update(thd, NULL); }
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
-};
-
-/*
- Session_state_change_tracker
-
- This is a boolean tracker class that will monitor any change that contributes
- to a session state change.
- Attributes that contribute to session state change include:
- - Successful change to System variables
- - User defined variables assignments
- - temporary tables created, altered or deleted
- - prepared statements added or removed
- - change in current database
- - change of current role
-*/
-
-class Session_state_change_tracker : public State_tracker
-{
-private:
-
- void reset();
-
-public:
- Session_state_change_tracker();
- bool enable(THD *thd)
- { return update(thd, NULL); };
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
- bool is_state_changed(THD*);
-};
-
-
/* To be used in expanding the buffer. */
static const unsigned int EXTRA_ALLOC= 1024;
void Session_sysvars_tracker::vars_list::reinit()
{
- buffer_length= 0;
track_all= 0;
if (m_registered_sysvars.records)
my_hash_reset(&m_registered_sysvars);
@@ -310,10 +55,8 @@ void Session_sysvars_tracker::vars_list::reinit()
void Session_sysvars_tracker::vars_list::copy(vars_list* from, THD *thd)
{
- reinit();
track_all= from->track_all;
free_hash();
- buffer_length= from->buffer_length;
m_registered_sysvars= from->m_registered_sysvars;
from->init();
}
@@ -321,26 +64,20 @@ void Session_sysvars_tracker::vars_list::copy(vars_list* from, THD *thd)
/**
Inserts the variable to be tracked into m_registered_sysvars hash.
- @param node Node to be inserted.
@param svar address of the system variable
@retval false success
@retval true error
*/
-bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
- const sys_var *svar,
- myf mem_flag)
+bool Session_sysvars_tracker::vars_list::insert(const sys_var *svar)
{
- if (!node)
- {
- if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
- MYF(MY_WME | mem_flag))))
- {
- reinit();
- return true;
- }
- }
+ sysvar_node_st *node;
+ if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
+ MYF(MY_WME |
+ (mysqld_server_initialized ?
+ MY_THREAD_SPECIFIC : 0)))))
+ return true;
node->m_svar= (sys_var *)svar;
node->test_load= node->m_svar->test_load;
@@ -351,7 +88,6 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
if (!search((sys_var *)svar))
{
//EOF (error is already reported)
- reinit();
return true;
}
}
@@ -373,7 +109,6 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
in case of invalid/duplicate values.
@param char_set [IN] charecter set information used for string
manipulations.
- @param take_mutex [IN] take LOCK_plugin
@return
true Error
@@ -382,39 +117,24 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
LEX_STRING var_list,
bool throw_error,
- CHARSET_INFO *char_set,
- bool take_mutex)
+ CHARSET_INFO *char_set)
{
const char separator= ',';
char *token, *lasts= NULL;
size_t rest= var_list.length;
- reinit();
if (!var_list.str || var_list.length == 0)
- {
- buffer_length= 1;
return false;
- }
if(!strcmp(var_list.str, "*"))
{
track_all= true;
- buffer_length= 2;
return false;
}
- buffer_length= var_list.length + 1;
token= var_list.str;
track_all= false;
- /*
- If Lock to the plugin mutex is not acquired here itself, it results
- in having to acquire it multiple times in find_sys_var_ex for each
- token value. Hence the mutex is handled here to avoid a performance
- overhead.
- */
- if (!thd || take_mutex)
- mysql_mutex_lock(&LOCK_plugin);
for (;;)
{
sys_var *svar;
@@ -438,11 +158,10 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
{
track_all= true;
}
- else if ((svar=
- find_sys_var_ex(thd, var.str, var.length, throw_error, true)))
+ else if ((svar= find_sys_var(thd, var.str, var.length, throw_error)))
{
- if (insert(NULL, svar, m_mem_flag) == TRUE)
- goto error;
+ if (insert(svar) == TRUE)
+ return true;
}
else if (throw_error && thd)
{
@@ -452,31 +171,20 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
"be ignored.", (int)var.length, token);
}
else
- goto error;
+ return true;
if (lasts)
token= lasts + 1;
else
break;
}
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
-
return false;
-
-error:
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
}
-bool Session_sysvars_tracker::check_var_list(THD *thd,
- LEX_STRING var_list,
- bool throw_error,
- CHARSET_INFO *char_set,
- bool take_mutex)
+bool sysvartrack_validate_value(THD *thd, const char *str, size_t len)
{
+ LEX_STRING var_list= { (char *) str, len };
const char separator= ',';
char *token, *lasts= NULL;
size_t rest= var_list.length;
@@ -489,14 +197,6 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
token= var_list.str;
- /*
- If Lock to the plugin mutex is not acquired here itself, it results
- in having to acquire it multiple times in find_sys_var_ex for each
- token value. Hence the mutex is handled here to avoid a performance
- overhead.
- */
- if (!thd || take_mutex)
- mysql_mutex_lock(&LOCK_plugin);
for (;;)
{
LEX_CSTRING var;
@@ -513,55 +213,19 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
var.length= rest;
/* Remove leading/trailing whitespace. */
- trim_whitespace(char_set, &var);
+ trim_whitespace(system_charset_info, &var);
- if(!strcmp(var.str, "*") &&
- !find_sys_var_ex(thd, var.str, var.length, throw_error, true))
- {
- if (throw_error && take_mutex && thd)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_VALUE_FOR_VAR,
- "%.*s is not a valid system variable and will"
- "be ignored.", (int)var.length, token);
- }
- else
- {
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
- }
- }
+ if (!strcmp(var.str, "*") && !find_sys_var(thd, var.str, var.length))
+ return true;
if (lasts)
token= lasts + 1;
else
break;
}
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
-
return false;
}
-struct name_array_filler_data
-{
- LEX_CSTRING **names;
- uint idx;
-
-};
-
-/** Collects variable references into array */
-my_bool Session_sysvars_tracker::name_array_filler(void *ptr,
- void *data_ptr)
-{
- Session_sysvars_tracker::sysvar_node_st *node=
- (Session_sysvars_tracker::sysvar_node_st *)ptr;
- name_array_filler_data *data= (struct name_array_filler_data *)data_ptr;
- if (*node->test_load)
- data->names[data->idx++]= &node->m_svar->name;
- return FALSE;
-}
/* Sorts variable references array */
static int name_array_sorter(const void *a, const void *b)
@@ -581,7 +245,8 @@ static int name_array_sorter(const void *a, const void *b)
bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
size_t buf_len)
{
- struct name_array_filler_data data;
+ LEX_CSTRING **names;
+ uint idx;
size_t left= buf_len;
size_t names_size= m_registered_sysvars.records * sizeof(LEX_CSTRING *);
const char separator= ',';
@@ -604,16 +269,19 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
return false;
}
- data.names= (LEX_CSTRING**)my_safe_alloca(names_size);
-
- if (unlikely(!data.names))
+ if (unlikely(!(names= (LEX_CSTRING**) my_safe_alloca(names_size))))
return true;
- data.idx= 0;
+ idx= 0;
mysql_mutex_lock(&LOCK_plugin);
- my_hash_iterate(&m_registered_sysvars, &name_array_filler, &data);
- DBUG_ASSERT(data.idx <= m_registered_sysvars.records);
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
+ {
+ sysvar_node_st *node= at(i);
+ if (*node->test_load)
+ names[idx++]= &node->m_svar->name;
+ }
+ DBUG_ASSERT(idx <= m_registered_sysvars.records);
/*
We check number of records again here because number of variables
@@ -626,17 +294,16 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
return false;
}
- my_qsort(data.names, data.idx, sizeof(LEX_CSTRING *),
- &name_array_sorter);
+ my_qsort(names, idx, sizeof(LEX_CSTRING*), &name_array_sorter);
- for(uint i= 0; i < data.idx; i++)
+ for(uint i= 0; i < idx; i++)
{
- LEX_CSTRING *nm= data.names[i];
+ LEX_CSTRING *nm= names[i];
size_t ln= nm->length + 1;
if (ln > left)
{
mysql_mutex_unlock(&LOCK_plugin);
- my_safe_afree(data.names, names_size);
+ my_safe_afree(names, names_size);
return true;
}
memcpy(buf, nm->str, nm->length);
@@ -647,58 +314,47 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
mysql_mutex_unlock(&LOCK_plugin);
buf--; buf[0]= '\0';
- my_safe_afree(data.names, names_size);
+ my_safe_afree(names, names_size);
return false;
}
-/**
- Enable session tracker by parsing global value of tracked variables.
- @param thd [IN] The thd handle.
+void Session_sysvars_tracker::init(THD *thd)
+{
+ mysql_mutex_assert_owner(&LOCK_global_system_variables);
+ DBUG_ASSERT(thd->variables.session_track_system_variables ==
+ global_system_variables.session_track_system_variables);
+ DBUG_ASSERT(global_system_variables.session_track_system_variables);
+ thd->variables.session_track_system_variables=
+ my_strdup(global_system_variables.session_track_system_variables,
+ MYF(MY_WME | MY_THREAD_SPECIFIC));
+}
- @retval true Error
- @retval false Success
-*/
-bool Session_sysvars_tracker::enable(THD *thd)
+void Session_sysvars_tracker::deinit(THD *thd)
{
- mysql_mutex_lock(&LOCK_plugin);
- LEX_STRING tmp;
- tmp.str= global_system_variables.session_track_system_variables;
- tmp.length= safe_strlen(tmp.str);
- if (tool_list->parse_var_list(thd, tmp,
- true, thd->charset(), false) == true)
- {
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
- }
- mysql_mutex_unlock(&LOCK_plugin);
- orig_list->copy(tool_list, thd);
- m_enabled= true;
-
- return false;
+ my_free(thd->variables.session_track_system_variables);
+ thd->variables.session_track_system_variables= 0;
}
/**
- Check system variable name(s).
-
- @note This function is called from the ON_CHECK() function of the
- session_track_system_variables' sys_var class.
+ Enable session tracker by parsing global value of tracked variables.
@param thd [IN] The thd handle.
- @param var [IN] A pointer to set_var holding the specified list of
- system variable names.
@retval true Error
@retval false Success
*/
-inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
+bool Session_sysvars_tracker::enable(THD *thd)
{
- return Session_sysvars_tracker::check_var_list(thd, *val, true,
- thd->charset(), true);
+ orig_list.reinit();
+ m_parsed= false;
+ m_enabled= thd->variables.session_track_system_variables &&
+ *thd->variables.session_track_system_variables;
+ return false;
}
@@ -708,6 +364,9 @@ inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
Session_sysvars_tracker::vars_list::copy updating the hash in orig_list
which represents the system variables to be tracked.
+ We are doing via tool list because there possible errors with memory
+ in this case value will be unchanged.
+
@note This function is called from the ON_UPDATE() function of the
session_track_system_variables' sys_var class.
@@ -719,37 +378,43 @@ inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
bool Session_sysvars_tracker::update(THD *thd, set_var *var)
{
- /*
- We are doing via tool list because there possible errors with memory
- in this case value will be unchanged.
- */
- tool_list->reinit();
- if (tool_list->parse_var_list(thd, var->save_result.string_value, true,
- thd->charset(), true))
+ vars_list tool_list;
+ void *copy= var->save_result.string_value.str ?
+ my_memdup(var->save_result.string_value.str,
+ var->save_result.string_value.length + 1,
+ MYF(MY_WME | MY_THREAD_SPECIFIC)) :
+ my_strdup("", MYF(MY_WME | MY_THREAD_SPECIFIC));
+
+ if (!copy)
return true;
- orig_list->copy(tool_list, thd);
- return false;
-}
+ if (tool_list.parse_var_list(thd, var->save_result.string_value, true,
+ thd->charset()))
+ {
+ my_free(copy);
+ return true;
+ }
+
+ my_free(thd->variables.session_track_system_variables);
+ thd->variables.session_track_system_variables= static_cast<char*>(copy);
-/*
- Function and structure to support storing variables from hash to the buffer.
-*/
+ m_parsed= true;
+ orig_list.copy(&tool_list, thd);
+ orig_list.construct_var_list(thd->variables.session_track_system_variables,
+ var->save_result.string_value.length + 1);
+ return false;
+}
-struct st_store_variable_param
-{
- THD *thd;
- String *buf;
-};
-my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
+bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
{
- Session_sysvars_tracker::sysvar_node_st *node=
- (Session_sysvars_tracker::sysvar_node_st *)ptr;
- if (node->m_changed)
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
{
- THD *thd= ((st_store_variable_param *)data_ptr)->thd;
- String *buf= ((st_store_variable_param *)data_ptr)->buf;
+ sysvar_node_st *node= at(i);
+
+ if (!node->m_changed)
+ continue;
+
char val_buf[SHOW_VAR_FUNC_BUFF_SIZE];
SHOW_VAR show;
CHARSET_INFO *charset;
@@ -758,7 +423,7 @@ my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
if (!*node->test_load)
{
mysql_mutex_unlock(&LOCK_plugin);
- return false;
+ continue;
}
sys_var *svar= node->m_svar;
bool is_plugin= svar->cast_pluginvar();
@@ -803,11 +468,6 @@ my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
return false;
}
-bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
-{
- st_store_variable_param data= {thd, buf};
- return my_hash_iterate(&m_registered_sysvars, &store_variable, &data);
-}
/**
Store the data for changed system variables in the specified buffer.
@@ -823,13 +483,13 @@ bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
bool Session_sysvars_tracker::store(THD *thd, String *buf)
{
- if (!orig_list->is_enabled())
+ if (!orig_list.is_enabled())
return false;
- if (orig_list->store(thd, buf))
+ if (orig_list.store(thd, buf))
return true;
- reset();
+ orig_list.reset();
return false;
}
@@ -844,14 +504,27 @@ bool Session_sysvars_tracker::store(THD *thd, String *buf)
void Session_sysvars_tracker::mark_as_changed(THD *thd,
LEX_CSTRING *var)
{
- sysvar_node_st *node= NULL;
+ sysvar_node_st *node;
sys_var *svar= (sys_var *)var;
+
+ if (!m_parsed)
+ {
+ DBUG_ASSERT(thd->variables.session_track_system_variables);
+ LEX_STRING tmp= { thd->variables.session_track_system_variables,
+ strlen(thd->variables.session_track_system_variables) };
+ if (orig_list.parse_var_list(thd, tmp, true, thd->charset()))
+ {
+ orig_list.reinit();
+ return;
+ }
+ m_parsed= true;
+ }
+
/*
Check if the specified system variable is being tracked, if so
mark it as changed and also set the class's m_changed flag.
*/
- if (orig_list->is_enabled() &&
- (node= (sysvar_node_st *) (orig_list->insert_or_search(node, svar))))
+ if (orig_list.is_enabled() && (node= orig_list.insert_or_search(svar)))
{
node->m_changed= true;
State_tracker::mark_as_changed(thd, var);
@@ -878,63 +551,41 @@ uchar *Session_sysvars_tracker::sysvars_get_key(const char *entry,
}
-/* Function to support resetting hash nodes for the variables */
-
-my_bool Session_sysvars_tracker::reset_variable(void *ptr,
- void *data_ptr)
-{
- ((Session_sysvars_tracker::sysvar_node_st *)ptr)->m_changed= false;
- return false;
-}
-
void Session_sysvars_tracker::vars_list::reset()
{
- my_hash_iterate(&m_registered_sysvars, &reset_variable, NULL);
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
+ at(i)->m_changed= false;
}
-/**
- Prepare/reset the m_registered_sysvars hash for next statement.
-*/
-void Session_sysvars_tracker::reset()
+bool sysvartrack_global_update(THD *thd, char *str, size_t len)
{
-
- orig_list->reset();
- m_changed= false;
+ LEX_STRING tmp= { str, len };
+ Session_sysvars_tracker::vars_list dummy;
+ if (!dummy.parse_var_list(thd, tmp, false, system_charset_info))
+ {
+ dummy.construct_var_list(str, len + 1);
+ return false;
+ }
+ return true;
}
-static Session_sysvars_tracker* sysvar_tracker(THD *thd)
-{
- return (Session_sysvars_tracker*)
- thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER);
-}
-bool sysvartrack_validate_value(THD *thd, const char *str, size_t len)
-{
- LEX_STRING tmp= {(char *)str, len};
- return Session_sysvars_tracker::server_init_check(thd, system_charset_info,
- tmp);
-}
-bool sysvartrack_reprint_value(THD *thd, char *str, size_t len)
+int session_tracker_init()
{
- LEX_STRING tmp= {str, len};
- return Session_sysvars_tracker::server_init_process(thd,
- system_charset_info,
- tmp);
-}
-bool sysvartrack_update(THD *thd, set_var *var)
-{
- return sysvar_tracker(thd)->update(thd, var);
-}
-size_t sysvartrack_value_len(THD *thd)
-{
- return sysvar_tracker(thd)->get_buffer_length();
-}
-bool sysvartrack_value_construct(THD *thd, char *val, size_t len)
-{
- return sysvar_tracker(thd)->construct_var_list(val, len);
+ DBUG_ASSERT(global_system_variables.session_track_system_variables);
+ if (sysvartrack_validate_value(0,
+ global_system_variables.session_track_system_variables,
+ strlen(global_system_variables.session_track_system_variables)))
+ {
+ sql_print_error("The variable session_track_system_variables has "
+ "invalid values.");
+ return 1;
+ }
+ return 0;
}
+
///////////////////////////////////////////////////////////////////////////////
/**
@@ -991,37 +642,12 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
/* Length and current schema name */
buf->q_net_store_data((const uchar *)thd->db.str, thd->db.length);
- reset();
-
return false;
}
-/**
- Reset the m_changed flag for next statement.
-
- @return void
-*/
-
-void Current_schema_tracker::reset()
-{
- m_changed= false;
-}
-
-
///////////////////////////////////////////////////////////////////////////////
-
-Transaction_state_tracker::Transaction_state_tracker()
-{
- m_enabled = false;
- tx_changed = TX_CHG_NONE;
- tx_curr_state =
- tx_reported_state= TX_EMPTY;
- tx_read_flags = TX_READ_INHERIT;
- tx_isol_level = TX_ISOL_INHERIT;
-}
-
/**
Enable/disable the tracker based on @@session_track_transaction_info.
@@ -1331,25 +957,14 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
}
}
- reset();
+ tx_reported_state= tx_curr_state;
+ tx_changed= TX_CHG_NONE;
return false;
}
/**
- Reset the m_changed flag for next statement.
-*/
-
-void Transaction_state_tracker::reset()
-{
- m_changed= false;
- tx_reported_state= tx_curr_state;
- tx_changed= TX_CHG_NONE;
-}
-
-
-/**
Helper function: turn table info into table access flag.
Accepts table lock type and engine type flag (transactional/
non-transactional), and returns the corresponding access flag
@@ -1518,11 +1133,6 @@ void Transaction_state_tracker::set_isol_level(THD *thd,
///////////////////////////////////////////////////////////////////////////////
-Session_state_change_tracker::Session_state_change_tracker()
-{
- m_changed= false;
-}
-
/**
@Enable/disable the tracker based on @@session_track_state_change value.
@@ -1560,106 +1170,15 @@ bool Session_state_change_tracker::store(THD *thd, String *buf)
/* Length of the overall entity (1 byte) */
buf->q_append('\1');
- DBUG_ASSERT(is_state_changed(thd));
+ DBUG_ASSERT(is_changed());
buf->q_append('1');
- reset();
-
return false;
}
-
-/**
- Reset the m_changed flag for next statement.
-*/
-
-void Session_state_change_tracker::reset()
-{
- m_changed= false;
-}
-
-
-/**
- Find if there is a session state change.
-*/
-
-bool Session_state_change_tracker::is_state_changed(THD *)
-{
- return m_changed;
-}
-
///////////////////////////////////////////////////////////////////////////////
/**
- @brief Initialize session tracker objects.
-*/
-
-Session_tracker::Session_tracker()
-{
- /* track data ID fit into one byte in net coding */
- compile_time_assert(SESSION_TRACK_always_at_the_end < 251);
- /* one tracker could serv several tracking data */
- compile_time_assert((uint)SESSION_TRACK_always_at_the_end >=
- (uint)SESSION_TRACKER_END);
-
- for (int i= 0; i < SESSION_TRACKER_END; i++)
- m_trackers[i]= NULL;
-}
-
-
-/**
- @brief Enables the tracker objects.
-
- @param thd [IN] The thread handle.
-
- @return void
-*/
-
-void Session_tracker::enable(THD *thd)
-{
- /*
- Originally and correctly this allocation was in the constructor and
- deallocation in the destructor, but in this case memory counting
- system works incorrectly (for example in INSERT DELAYED thread)
- */
- deinit();
- m_trackers[SESSION_SYSVARS_TRACKER]=
- new (std::nothrow) Session_sysvars_tracker();
- m_trackers[CURRENT_SCHEMA_TRACKER]=
- new (std::nothrow) Current_schema_tracker;
- m_trackers[SESSION_STATE_CHANGE_TRACKER]=
- new (std::nothrow) Session_state_change_tracker;
- m_trackers[SESSION_GTIDS_TRACKER]=
- new (std::nothrow) Not_implemented_tracker;
- m_trackers[TRANSACTION_INFO_TRACKER]=
- new (std::nothrow) Transaction_state_tracker;
-
- for (int i= 0; i < SESSION_TRACKER_END; i++)
- m_trackers[i]->enable(thd);
-}
-
-
-/**
- Method called during the server startup to verify the contents
- of @@session_track_system_variables.
-
- @retval false Success
- @retval true Failure
-*/
-
-bool Session_tracker::server_boot_verify(CHARSET_INFO *char_set)
-{
- bool result;
- LEX_STRING tmp;
- tmp.str= global_system_variables.session_track_system_variables;
- tmp.length= safe_strlen(tmp.str);
- result=
- Session_sysvars_tracker::server_init_check(NULL, char_set, tmp);
- return result;
-}
-
-
-/**
@brief Store all change information in the specified buffer.
@param thd [IN] The thd handle.
@@ -1671,6 +1190,12 @@ void Session_tracker::store(THD *thd, String *buf)
{
size_t start;
+ /* track data ID fit into one byte in net coding */
+ compile_time_assert(SESSION_TRACK_always_at_the_end < 251);
+ /* one tracker could serv several tracking data */
+ compile_time_assert((uint) SESSION_TRACK_always_at_the_end >=
+ (uint) SESSION_TRACKER_END);
+
/*
Probably most track result will fit in 251 byte so lets made it at
least efficient. We allocate 1 byte for length and then will move
@@ -1682,11 +1207,15 @@ void Session_tracker::store(THD *thd, String *buf)
/* Get total length. */
for (int i= 0; i < SESSION_TRACKER_END; i++)
{
- if (m_trackers[i]->is_changed() &&
- m_trackers[i]->store(thd, buf))
+ if (m_trackers[i]->is_changed())
{
- buf->length(start); // it is safer to have 0-length block in case of error
- return;
+ if (m_trackers[i]->store(thd, buf))
+ {
+ // it is safer to have 0-length block in case of error
+ buf->length(start);
+ return;
+ }
+ m_trackers[i]->reset_changed();
}
}
@@ -1706,5 +1235,3 @@ void Session_tracker::store(THD *thd, String *buf)
net_store_length(data - 1, length);
}
-
-#endif //EMBEDDED_LIBRARY
diff --git a/sql/session_tracker.h b/sql/session_tracker.h
index 684692aae0c..226b026d590 100644
--- a/sql/session_tracker.h
+++ b/sql/session_tracker.h
@@ -32,7 +32,6 @@ enum enum_session_tracker
SESSION_SYSVARS_TRACKER, /* Session system variables */
CURRENT_SCHEMA_TRACKER, /* Current schema */
SESSION_STATE_CHANGE_TRACKER,
- SESSION_GTIDS_TRACKER, /* Tracks GTIDs */
TRANSACTION_INFO_TRACKER, /* Transaction state */
SESSION_TRACKER_END /* must be the last */
};
@@ -67,17 +66,12 @@ protected:
*/
bool m_enabled;
+private:
/** Has the session state type changed ? */
bool m_changed;
public:
- /** Constructor */
- State_tracker() : m_enabled(false), m_changed(false)
- {}
-
- /** Destructor */
- virtual ~State_tracker()
- {}
+ virtual ~State_tracker() {}
/** Getters */
bool is_enabled() const
@@ -86,8 +80,20 @@ public:
bool is_changed() const
{ return m_changed; }
- /** Called in the constructor of THD*/
- virtual bool enable(THD *thd)= 0;
+ void reset_changed() { m_changed= false; }
+
+ /**
+ Called by THD::init() when new connection is being created
+
+ We may inherit m_changed from previous connection served by this THD if
+ connection was broken or client didn't have session tracking capability.
+ Thus we have to reset it here.
+ */
+ virtual bool enable(THD *thd)
+ {
+ reset_changed();
+ return update(thd, 0);
+ }
/** To be invoked when the tracker's system variable is updated (ON_UPDATE).*/
virtual bool update(THD *thd, set_var *var)= 0;
@@ -99,74 +105,156 @@ public:
virtual void mark_as_changed(THD *thd, LEX_CSTRING *name);
};
-bool sysvartrack_validate_value(THD *thd, const char *str, size_t len);
-bool sysvartrack_reprint_value(THD *thd, char *str, size_t len);
-bool sysvartrack_update(THD *thd, set_var *var);
-size_t sysvartrack_value_len(THD *thd);
-bool sysvartrack_value_construct(THD *thd, char *val, size_t len);
-
/**
- Session_tracker
+ Session_sysvars_tracker
- This class holds an object each for all tracker classes and provides
- methods necessary for systematic detection and generation of session
- state change information.
+ This is a tracker class that enables & manages the tracking of session
+ system variables. It internally maintains a hash of user supplied variable
+ references and a boolean field to store if the variable was changed by the
+ last statement.
*/
-class Session_tracker
+class Session_sysvars_tracker: public State_tracker
{
-private:
- State_tracker *m_trackers[SESSION_TRACKER_END];
+ struct sysvar_node_st {
+ sys_var *m_svar;
+ bool *test_load;
+ bool m_changed;
+ };
- /* The following two functions are private to disable copying. */
- Session_tracker(Session_tracker const &other)
- {
- DBUG_ASSERT(FALSE);
- }
- Session_tracker& operator= (Session_tracker const &rhs)
+ class vars_list
{
- DBUG_ASSERT(FALSE);
- return *this;
- }
+ /**
+ Registered system variables. (@@session_track_system_variables)
+ A hash to store the name of all the system variables specified by the
+ user.
+ */
+ HASH m_registered_sysvars;
+ /**
+ If TRUE then we want to check all session variable.
+ */
+ bool track_all;
+ void init()
+ {
+ my_hash_init(&m_registered_sysvars, &my_charset_bin, 0, 0, 0,
+ (my_hash_get_key) sysvars_get_key, my_free,
+ HASH_UNIQUE | (mysqld_server_initialized ?
+ HASH_THREAD_SPECIFIC : 0));
+ }
+ void free_hash()
+ {
+ DBUG_ASSERT(my_hash_inited(&m_registered_sysvars));
+ my_hash_free(&m_registered_sysvars);
+ }
-public:
+ sysvar_node_st *search(const sys_var *svar)
+ {
+ return reinterpret_cast<sysvar_node_st*>(
+ my_hash_search(&m_registered_sysvars,
+ reinterpret_cast<const uchar*>(&svar),
+ sizeof(sys_var*)));
+ }
- Session_tracker();
- ~Session_tracker()
- {
- deinit();
- }
+ sysvar_node_st *at(ulong i)
+ {
+ DBUG_ASSERT(i < m_registered_sysvars.records);
+ return reinterpret_cast<sysvar_node_st*>(
+ my_hash_element(&m_registered_sysvars, i));
+ }
+ public:
+ vars_list(): track_all(false) { init(); }
+ ~vars_list() { if (my_hash_inited(&m_registered_sysvars)) free_hash(); }
+ void deinit() { free_hash(); }
- /* trick to make happy memory accounting system */
- void deinit()
- {
- for (int i= 0; i < SESSION_TRACKER_END; i++)
+ sysvar_node_st *insert_or_search(const sys_var *svar)
{
- if (m_trackers[i])
- delete m_trackers[i];
- m_trackers[i]= NULL;
+ sysvar_node_st *res= search(svar);
+ if (!res)
+ {
+ if (track_all)
+ {
+ insert(svar);
+ return search(svar);
+ }
+ }
+ return res;
}
- }
- void enable(THD *thd);
- static bool server_boot_verify(CHARSET_INFO *char_set);
+ bool insert(const sys_var *svar);
+ void reinit();
+ void reset();
+ inline bool is_enabled()
+ {
+ return track_all || m_registered_sysvars.records;
+ }
+ void copy(vars_list* from, THD *thd);
+ bool parse_var_list(THD *thd, LEX_STRING var_list, bool throw_error,
+ CHARSET_INFO *char_set);
+ bool construct_var_list(char *buf, size_t buf_len);
+ bool store(THD *thd, String *buf);
+ };
+ /**
+ Two objects of vars_list type are maintained to manage
+ various operations.
+ */
+ vars_list orig_list;
+ bool m_parsed;
- /** Returns the pointer to the tracker object for the specified tracker. */
- inline State_tracker *get_tracker(enum_session_tracker tracker) const
- {
- return m_trackers[tracker];
- }
+public:
+ void init(THD *thd);
+ void deinit(THD *thd);
+ bool enable(THD *thd);
+ bool update(THD *thd, set_var *var);
+ bool store(THD *thd, String *buf);
+ void mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name);
+ void deinit() { orig_list.deinit(); }
+ /* callback */
+ static uchar *sysvars_get_key(const char *entry, size_t *length,
+ my_bool not_used __attribute__((unused)));
- inline void mark_as_changed(THD *thd, enum enum_session_tracker tracker,
- LEX_CSTRING *data)
- {
- if (m_trackers[tracker]->is_enabled())
- m_trackers[tracker]->mark_as_changed(thd, data);
- }
+ friend bool sysvartrack_global_update(THD *thd, char *str, size_t len);
+};
- void store(THD *thd, String *main_buf);
+bool sysvartrack_validate_value(THD *thd, const char *str, size_t len);
+bool sysvartrack_global_update(THD *thd, char *str, size_t len);
+
+
+/**
+ Current_schema_tracker,
+
+ This is a tracker class that enables & manages the tracking of current
+ schema for a particular connection.
+*/
+
+class Current_schema_tracker: public State_tracker
+{
+public:
+ bool update(THD *thd, set_var *var);
+ bool store(THD *thd, String *buf);
+};
+
+
+/*
+ Session_state_change_tracker
+
+ This is a boolean tracker class that will monitor any change that contributes
+ to a session state change.
+ Attributes that contribute to session state change include:
+ - Successful change to System variables
+ - User defined variables assignments
+ - temporary tables created, altered or deleted
+ - prepared statements added or removed
+ - change in current database
+ - change of current role
+*/
+
+class Session_state_change_tracker: public State_tracker
+{
+public:
+ bool update(THD *thd, set_var *var);
+ bool store(THD *thd, String *buf);
};
@@ -231,14 +319,21 @@ enum enum_session_track_transaction_info {
class Transaction_state_tracker : public State_tracker
{
-private:
/** Helper function: turn table info into table access flag */
enum_tx_state calc_trx_state(THD *thd, thr_lock_type l, bool has_trx);
public:
- /** Constructor */
- Transaction_state_tracker();
+
bool enable(THD *thd)
- { return update(thd, NULL); }
+ {
+ m_enabled= false;
+ tx_changed= TX_CHG_NONE;
+ tx_curr_state= TX_EMPTY;
+ tx_reported_state= TX_EMPTY;
+ tx_read_flags= TX_READ_INHERIT;
+ tx_isol_level= TX_ISOL_INHERIT;
+ return State_tracker::enable(thd);
+ }
+
bool update(THD *thd, set_var *var);
bool store(THD *thd, String *buf);
@@ -276,8 +371,6 @@ private:
/** isolation level */
enum enum_tx_isol_level tx_isol_level;
- void reset();
-
inline void update_change_flags(THD *thd)
{
tx_changed &= uint(~TX_CHG_STATE);
@@ -289,11 +382,67 @@ private:
#define TRANSACT_TRACKER(X) \
do { if (thd->variables.session_track_transaction_info > TX_TRACK_NONE) \
- {((Transaction_state_tracker *) \
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER)) \
- ->X; } } while(0)
+ thd->session_tracker.transaction_info.X; } while(0)
#define SESSION_TRACKER_CHANGED(A,B,C) \
thd->session_tracker.mark_as_changed(A,B,C)
+
+
+/**
+ Session_tracker
+
+ This class holds an object each for all tracker classes and provides
+ methods necessary for systematic detection and generation of session
+ state change information.
+*/
+
+class Session_tracker
+{
+ State_tracker *m_trackers[SESSION_TRACKER_END];
+
+ /* The following two functions are private to disable copying. */
+ Session_tracker(Session_tracker const &other)
+ {
+ DBUG_ASSERT(FALSE);
+ }
+ Session_tracker& operator= (Session_tracker const &rhs)
+ {
+ DBUG_ASSERT(FALSE);
+ return *this;
+ }
+
+public:
+ Current_schema_tracker current_schema;
+ Session_state_change_tracker state_change;
+ Transaction_state_tracker transaction_info;
+ Session_sysvars_tracker sysvars;
+
+ Session_tracker()
+ {
+ m_trackers[SESSION_SYSVARS_TRACKER]= &sysvars;
+ m_trackers[CURRENT_SCHEMA_TRACKER]= &current_schema;
+ m_trackers[SESSION_STATE_CHANGE_TRACKER]= &state_change;
+ m_trackers[TRANSACTION_INFO_TRACKER]= &transaction_info;
+ }
+
+ void enable(THD *thd)
+ {
+ for (int i= 0; i < SESSION_TRACKER_END; i++)
+ m_trackers[i]->enable(thd);
+ }
+
+ inline void mark_as_changed(THD *thd, enum enum_session_tracker tracker,
+ LEX_CSTRING *data)
+ {
+ if (m_trackers[tracker]->is_enabled())
+ m_trackers[tracker]->mark_as_changed(thd, data);
+ }
+
+
+ void store(THD *thd, String *main_buf);
+};
+
+
+int session_tracker_init();
#else
#define TRANSACT_TRACKER(X) do{}while(0)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index de9bda3d067..ae4e712c77d 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1016,13 +1016,13 @@ int set_var_collation_client::update(THD *thd)
/* Mark client collation variables as changed */
#ifndef EMBEDDED_LIBRARY
- if (thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->is_enabled())
+ if (thd->session_tracker.sysvars.is_enabled())
{
- thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->
+ thd->session_tracker.sysvars.
mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_client_ptr);
- thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->
+ thd->session_tracker.sysvars.
mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_results_ptr);
- thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->
+ thd->session_tracker.sysvars.
mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_connection_ptr);
}
thd->session_tracker.mark_as_changed(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
diff --git a/sql/set_var.h b/sql/set_var.h
index 8a82e07fd6b..5f9720f0d5a 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -407,7 +407,8 @@ extern SHOW_COMP_OPTION have_openssl;
SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted, enum enum_var_type type);
int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond);
-sys_var *find_sys_var(THD *thd, const char *str, size_t length=0);
+sys_var *find_sys_var(THD *thd, const char *str, size_t length= 0,
+ bool throw_error= false);
int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free);
#define SYSVAR_AUTOSIZE(VAR,VAL) \
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index cdda49c5796..ca9985c172e 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -30,6 +30,10 @@
#define SIGNAL_FMT "signal %d"
#endif
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
/*
We are handling signals/exceptions in this file.
Any global variables we read should be 'volatile sig_atomic_t'
@@ -44,6 +48,43 @@ extern volatile sig_atomic_t ld_assume_kernel_is_set;
extern const char *optimizer_switch_names[];
+static inline void output_core_info()
+{
+ /* proc is optional on some BSDs so it can't hurt to look */
+#ifdef HAVE_READLINK
+ char buff[PATH_MAX];
+ ssize_t len;
+ int fd;
+ if ((len= readlink("/proc/self/cwd", buff, sizeof(buff))) >= 0)
+ {
+ my_safe_printf_stderr("Writing a core file...\nWorking directory at %.*s\n",
+ (int) len, buff);
+ }
+ if ((fd= my_open("/proc/self/limits", O_RDONLY, MYF(0))) >= 0)
+ {
+ my_safe_printf_stderr("Resource Limits:\n");
+ while ((len= my_read(fd, (uchar*)buff, sizeof(buff), MYF(0))) > 0)
+ {
+ my_write_stderr(buff, len);
+ }
+ my_close(fd, MYF(0));
+ }
+#ifdef __linux__
+ if ((fd= my_open("/proc/sys/kernel/core_pattern", O_RDONLY, MYF(0))) >= 0)
+ {
+ len= my_read(fd, (uchar*)buff, sizeof(buff), MYF(0));
+ my_safe_printf_stderr("Core pattern: %.*s\n", (int) len, buff);
+ my_close(fd, MYF(0));
+ }
+#endif
+#else
+ char buff[80];
+ my_getwd(buff, sizeof(buff), 0);
+ my_safe_printf_stderr("Writing a core file at %s\n", buff);
+ fflush(stderr);
+#endif
+}
+
/**
* Handler for fatal signals on POSIX, exception handler on Windows.
*
@@ -295,13 +336,10 @@ extern "C" sig_handler handle_fatal_signal(int sig)
}
#endif
+ output_core_info();
#ifdef HAVE_WRITE_CORE
if (test_flags & TEST_CORE_ON_SIGNAL)
{
- char buff[80];
- my_getwd(buff, sizeof(buff), 0);
- my_safe_printf_stderr("Writing a core file at %s\n", buff);
- fflush(stderr);
my_write_core(sig);
}
#endif
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d8b5b7364a9..87cfb2b95bb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -8817,13 +8817,13 @@ static const char *command_array[]=
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
"CREATE USER", "EVENT", "TRIGGER", "CREATE TABLESPACE",
- "DELETE VERSIONING ROWS"
+ "DELETE HISTORY"
};
static uint command_lengths[]=
{
6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
- 14, 13, 11, 5, 7, 17, 22,
+ 14, 13, 11, 5, 7, 17, 14,
};
diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc
index b66d69334f0..61ca7c9a7af 100644
--- a/sql/sql_analyze_stmt.cc
+++ b/sql/sql_analyze_stmt.cc
@@ -45,7 +45,7 @@ void Filesort_tracker::print_json_members(Json_writer *writer)
else if (r_limit == 0)
writer->add_str(varied_str);
else
- writer->add_ll((longlong) rint(r_limit));
+ writer->add_ll(r_limit);
}
writer->add_member("r_used_priority_queue");
@@ -61,13 +61,13 @@ void Filesort_tracker::print_json_members(Json_writer *writer)
if (!get_r_loops())
writer->add_member("r_output_rows").add_null();
else
- writer->add_member("r_output_rows").add_ll((longlong) rint(r_output_rows /
- get_r_loops()));
+ writer->add_member("r_output_rows").add_ll(
+ (longlong) rint((double)r_output_rows / get_r_loops()));
if (sort_passes)
{
- writer->add_member("r_sort_passes").add_ll((longlong) rint(sort_passes /
- get_r_loops()));
+ writer->add_member("r_sort_passes").add_ll(
+ (longlong) rint((double)sort_passes / get_r_loops()));
}
if (sort_buffer_size != 0)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b346ebb92c1..b01edf6259b 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -600,7 +600,7 @@ extern "C" void thd_kill_timeout(THD* thd)
thd->awake(KILL_TIMEOUT);
}
-THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock)
+THD::THD(my_thread_id id, bool is_wsrep_applier)
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
/* statement id */ 0),
rli_fake(0), rgi_fake(0), rgi_slave(NULL),
@@ -808,7 +808,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock)
/* Call to init() below requires fully initialized Open_tables_state. */
reset_open_tables_state(this);
- init(skip_global_sys_var_lock);
+ init();
#if defined(ENABLED_PROFILING)
profiling.set_thd(this);
#endif
@@ -1216,11 +1216,10 @@ const Type_handler *THD::type_handler_for_date() const
Init common variables that has to be reset on start and on change_user
*/
-void THD::init(bool skip_lock)
+void THD::init()
{
DBUG_ENTER("thd::init");
- if (!skip_lock)
- mysql_mutex_lock(&LOCK_global_system_variables);
+ mysql_mutex_lock(&LOCK_global_system_variables);
plugin_thdvar_init(this);
/*
plugin_thd_var_init() sets variables= global_system_variables, which
@@ -1233,8 +1232,7 @@ void THD::init(bool skip_lock)
::strmake(default_master_connection_buff,
global_system_variables.default_master_connection.str,
variables.default_master_connection.length);
- if (!skip_lock)
- mysql_mutex_unlock(&LOCK_global_system_variables);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
user_time.val= start_time= start_time_sec_part= 0;
@@ -1723,7 +1721,7 @@ THD::~THD()
/* trick to make happy memory accounting system */
#ifndef EMBEDDED_LIBRARY
- session_tracker.deinit();
+ session_tracker.sysvars.deinit();
#endif //EMBEDDED_LIBRARY
if (status_var.local_memory_used != 0)
@@ -7151,12 +7149,12 @@ void THD::set_last_commit_gtid(rpl_gtid &gtid)
#endif
m_last_commit_gtid= gtid;
#ifndef EMBEDDED_LIBRARY
- if (changed_gtid &&
- session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->is_enabled())
+ if (changed_gtid && session_tracker.sysvars.is_enabled())
{
- session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->
+ DBUG_ASSERT(current_thd == this);
+ session_tracker.sysvars.
mark_as_changed(this, (LEX_CSTRING*)Sys_last_gtid_ptr);
- }
+ }
#endif
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index da21b9cb108..1266e1777ce 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3239,17 +3239,12 @@ public:
/**
@param id thread identifier
@param is_wsrep_applier thread type
- @param skip_lock instruct whether @c LOCK_global_system_variables
- is already locked, to not acquire it then.
*/
- THD(my_thread_id id, bool is_wsrep_applier= false, bool skip_lock= false);
+ THD(my_thread_id id, bool is_wsrep_applier= false);
~THD();
- /**
- @param skip_lock instruct whether @c LOCK_global_system_variables
- is already locked, to not acquire it then.
- */
- void init(bool skip_lock= false);
+
+ void init();
/*
Initialize memory roots necessary for query processing and (!)
pre-allocate memory for it. We can't do that in THD constructor because
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index e1a6420846d..b0544300f1d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -7640,8 +7640,7 @@ bool LEX::set_system_variable(THD *thd, enum_var_type var_type,
{
sys_var *tmp;
if (unlikely(check_reserved_words(name1)) ||
- unlikely(!(tmp= find_sys_var_ex(thd, name2->str, name2->length, true,
- false))))
+ unlikely(!(tmp= find_sys_var(thd, name2->str, name2->length, true))))
{
my_error(ER_UNKNOWN_STRUCTURED_VARIABLE, MYF(0),
(int) name1->length, name1->str);
@@ -8208,7 +8207,7 @@ int set_statement_var_if_exists(THD *thd, const char *var_name,
my_error(ER_SP_BADSTATEMENT, MYF(0), "[NO]WAIT");
return 1;
}
- if ((sysvar= find_sys_var_ex(thd, var_name, var_name_length, true, false)))
+ if ((sysvar= find_sys_var(thd, var_name, var_name_length, true)))
{
Item *item= new (thd->mem_root) Item_uint(thd, value);
set_var *var= new (thd->mem_root) set_var(thd, OPT_SESSION, sysvar,
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 4b23d87feb1..58c1dd3dfae 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -968,6 +968,7 @@ public:
bool union_needs_tmp_table();
void set_unique_exclude();
+ bool check_distinct_in_union();
friend struct LEX;
friend int subselect_union_engine::exec();
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 21767b4de96..82b4e85e6b3 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -2834,37 +2834,25 @@ static void update_func_double(THD *thd, struct st_mysql_sys_var *var,
System Variables support
****************************************************************************/
-sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
- bool throw_error, bool locked)
+sys_var *find_sys_var(THD *thd, const char *str, size_t length,
+ bool throw_error)
{
sys_var *var;
- sys_var_pluginvar *pi= NULL;
- plugin_ref plugin;
- DBUG_ENTER("find_sys_var_ex");
+ sys_var_pluginvar *pi;
+ DBUG_ENTER("find_sys_var");
DBUG_PRINT("enter", ("var '%.*s'", (int)length, str));
- if (!locked)
- mysql_mutex_lock(&LOCK_plugin);
mysql_prlock_rdlock(&LOCK_system_variables_hash);
if ((var= intern_find_sys_var(str, length)) &&
(pi= var->cast_pluginvar()))
{
- mysql_prlock_unlock(&LOCK_system_variables_hash);
- LEX *lex= thd ? thd->lex : 0;
- if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
+ mysql_mutex_lock(&LOCK_plugin);
+ if (!intern_plugin_lock(thd ? thd->lex : 0, plugin_int_to_ref(pi->plugin),
+ PLUGIN_IS_READY))
var= NULL; /* failed to lock it, it must be uninstalling */
- else
- if (!(plugin_state(plugin) & PLUGIN_IS_READY))
- {
- /* initialization not completed */
- var= NULL;
- intern_plugin_unlock(lex, plugin);
- }
- }
- else
- mysql_prlock_unlock(&LOCK_system_variables_hash);
- if (!locked)
mysql_mutex_unlock(&LOCK_plugin);
+ }
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (unlikely(!throw_error && !var))
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0),
@@ -2873,11 +2861,6 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
}
-sys_var *find_sys_var(THD *thd, const char *str, size_t length)
-{
- return find_sys_var_ex(thd, str, length, false, false);
-}
-
/*
called by register_var, construct_options and test_plugin_options.
Returns the 'bookmark' for the named variable.
@@ -3161,6 +3144,11 @@ void plugin_thdvar_init(THD *thd)
thd->variables.enforced_table_plugin= NULL;
cleanup_variables(&thd->variables);
+ /* This and all other variable cleanups are here for COM_CHANGE_USER :( */
+#ifndef EMBEDDED_LIBRARY
+ thd->session_tracker.sysvars.deinit(thd);
+#endif
+
thd->variables= global_system_variables;
/* we are going to allocate these lazily */
@@ -3182,6 +3170,9 @@ void plugin_thdvar_init(THD *thd)
intern_plugin_unlock(NULL, old_enforced_table_plugin);
mysql_mutex_unlock(&LOCK_plugin);
+#ifndef EMBEDDED_LIBRARY
+ thd->session_tracker.sysvars.init(thd);
+#endif
DBUG_VOID_RETURN;
}
@@ -3247,6 +3238,10 @@ void plugin_thdvar_cleanup(THD *thd)
plugin_ref *list;
DBUG_ENTER("plugin_thdvar_cleanup");
+#ifndef EMBEDDED_LIBRARY
+ thd->session_tracker.sysvars.deinit(thd);
+#endif
+
mysql_mutex_lock(&LOCK_plugin);
unlock_variables(thd, &thd->variables);
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 4e899e18f9b..01ec0563050 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -196,9 +196,6 @@ extern void sync_dynamic_session_variables(THD* thd, bool global_lock);
extern bool plugin_dl_foreach(THD *thd, const LEX_CSTRING *dl,
plugin_foreach_func *func, void *arg);
-sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
- bool throw_error, bool locked);
-
extern void sync_dynamic_session_variables(THD* thd, bool global_lock);
#endif
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4d904199efc..a0cde02be65 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2318,6 +2318,16 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
!(sql_mode & MODE_NO_FIELD_OPTIONS))
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
}
+
+ if (field->comment.length)
+ {
+ packet->append(STRING_WITH_LEN(" COMMENT "));
+ append_unescaped(packet, field->comment.str, field->comment.length);
+ }
+
+ append_create_options(thd, packet, field->option_list, check_options,
+ hton->field_options);
+
if (field->check_constraint)
{
StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
@@ -2327,13 +2337,6 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(")"));
}
- if (field->comment.length)
- {
- packet->append(STRING_WITH_LEN(" COMMENT "));
- append_unescaped(packet, field->comment.str, field->comment.length);
- }
- append_create_options(thd, packet, field->option_list, check_options,
- hton->field_options);
}
key_info= table->s->key_info;
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 9cd6c61891a..210e52887f1 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -278,7 +278,7 @@ public:
Field **nullable_fields() { return record0_field; }
void reset_extra_null_bitmap()
{
- size_t null_bytes= (trigger_table->s->stored_fields -
+ size_t null_bytes= (trigger_table->s->fields -
trigger_table->s->null_fields + 7)/8;
bzero(extra_null_bitmap, null_bytes);
}
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 032530deebc..94b0ab9a6c1 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -4490,7 +4490,7 @@ void Type_handler_temporal_result::Item_get_date(THD *thd, Item *item,
longlong Type_handler_real_result::
Item_val_int_signed_typecast(Item *item) const
{
- return item->val_int();
+ return item->val_int_signed_typecast_from_int();
}
longlong Type_handler_int_result::
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index e10c0af2e16..c32a6ee852f 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -2049,3 +2049,43 @@ void st_select_lex_unit::set_unique_exclude()
}
}
}
+
+/**
+ @brief
+ Check if the derived table is guaranteed to have distinct rows because of
+ UNION operations used to populate it.
+
+ @detail
+ UNION operation removes duplicate rows from its output. That is, a query like
+
+ select * from t1 UNION select * from t2
+
+ will not produce duplicate rows in its output, even if table t1 (and/or t2)
+ contain duplicate rows. EXCEPT and INTERSECT operations also have this
+ property.
+
+ On the other hand, UNION ALL operation doesn't remove duplicates. (The SQL
+ standard also defines EXCEPT ALL and INTERSECT ALL, but we don't support
+ them).
+
+ st_select_lex_unit computes its value left to right. That is, if there is
+ a st_select_lex_unit object describing
+
+ (select #1) OP1 (select #2) OP2 (select #3)
+
+ then ((select #1) OP1 (select #2)) is computed first, and OP2 is computed
+ second.
+
+ How can one tell if st_select_lex_unit is guaranteed to have distinct
+ output rows? This depends on whether the last operation was duplicate-
+ removing or not:
+ - UNION ALL is not duplicate-removing
+ - all other operations are duplicate-removing
+*/
+
+bool st_select_lex_unit::check_distinct_in_union()
+{
+ if (union_distinct && !union_distinct->next_select())
+ return true;
+ return false;
+}
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 14d5ae85462..2e92838ad3a 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -3206,6 +3206,8 @@ static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip
static bool fix_rpl_semi_sync_master_enabled(sys_var *self, THD *thd,
enum_var_type type)
{
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ mysql_mutex_lock(&repl_semisync_master.LOCK_rpl_semi_sync_master_enabled);
if (rpl_semi_sync_master_enabled)
{
if (repl_semisync_master.enable_master() != 0)
@@ -3218,11 +3220,11 @@ static bool fix_rpl_semi_sync_master_enabled(sys_var *self, THD *thd,
}
else
{
- if (repl_semisync_master.disable_master() != 0)
- rpl_semi_sync_master_enabled= true;
- if (!rpl_semi_sync_master_enabled)
- ack_receiver.stop();
+ repl_semisync_master.disable_master();
+ ack_receiver.stop();
}
+ mysql_mutex_unlock(&repl_semisync_master.LOCK_rpl_semi_sync_master_enabled);
+ mysql_mutex_lock(&LOCK_global_system_variables);
return false;
}
@@ -3806,14 +3808,12 @@ bool Sys_var_tx_read_only::session_update(THD *thd, set_var *var)
#ifndef EMBEDDED_LIBRARY
if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
{
- Transaction_state_tracker *tst= (Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
-
if (var->type == OPT_DEFAULT)
- tst->set_read_flags(thd,
+ thd->session_tracker.transaction_info.set_read_flags(thd,
thd->tx_read_only ? TX_READ_ONLY : TX_READ_WRITE);
else
- tst->set_read_flags(thd, TX_READ_INHERIT);
+ thd->session_tracker.transaction_info.set_read_flags(thd,
+ TX_READ_INHERIT);
}
#endif //EMBEDDED_LIBRARY
}
@@ -6255,8 +6255,7 @@ static bool update_session_track_schema(sys_var *self, THD *thd,
enum_var_type type)
{
DBUG_ENTER("update_session_track_schema");
- DBUG_RETURN(thd->session_tracker.get_tracker(CURRENT_SCHEMA_TRACKER)->
- update(thd, NULL));
+ DBUG_RETURN(thd->session_tracker.current_schema.update(thd, NULL));
}
static Sys_var_mybool Sys_session_track_schema(
@@ -6273,8 +6272,7 @@ static bool update_session_track_tx_info(sys_var *self, THD *thd,
enum_var_type type)
{
DBUG_ENTER("update_session_track_tx_info");
- DBUG_RETURN(thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER)->
- update(thd, NULL));
+ DBUG_RETURN(thd->session_tracker.transaction_info.update(thd, NULL));
}
static const char *session_track_transaction_info_names[]=
@@ -6299,8 +6297,7 @@ static bool update_session_track_state_change(sys_var *self, THD *thd,
enum_var_type type)
{
DBUG_ENTER("update_session_track_state_change");
- DBUG_RETURN(thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->
- update(thd, NULL));
+ DBUG_RETURN(thd->session_tracker.state_change.update(thd, NULL));
}
static Sys_var_mybool Sys_session_track_state_change(
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index 398dbb98455..440890bccfd 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -615,7 +615,7 @@ public:
char *new_val= global_update_prepare(thd, var);
if (new_val)
{
- if (sysvartrack_reprint_value(thd, new_val,
+ if (sysvartrack_global_update(thd, new_val,
var->save_result.string_value.length))
new_val= 0;
}
@@ -623,9 +623,7 @@ public:
return (new_val == 0 && var->save_result.string_value.str != 0);
}
bool session_update(THD *thd, set_var *var)
- {
- return sysvartrack_update(thd, var);
- }
+ { return thd->session_tracker.sysvars.update(thd, var); }
void session_save_default(THD *thd, set_var *var)
{
var->save_result.string_value.str= global_var(char*);
@@ -643,19 +641,6 @@ public:
DBUG_ASSERT(res == 0);
}
}
- uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
- {
- DBUG_ASSERT(thd != NULL);
- size_t len= sysvartrack_value_len(thd);
- char *res= (char *)thd->alloc(len + sizeof(char *));
- if (res)
- {
- char *buf= res + sizeof(char *);
- *((char**) res)= buf;
- sysvartrack_value_construct(thd, buf, len);
- }
- return (uchar *)res;
- }
};
#endif //EMBEDDED_LIBRARY
@@ -2229,14 +2214,6 @@ public:
return TRUE;
if (var->type == OPT_DEFAULT || !thd->in_active_multi_stmt_transaction())
{
-#ifndef EMBEDDED_LIBRARY
- Transaction_state_tracker *tst= NULL;
-
- if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
- tst= (Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
-#endif //EMBEDDED_LIBRARY
-
thd->tx_isolation= (enum_tx_isolation) var->save_result.ulonglong_value;
#ifndef EMBEDDED_LIBRARY
@@ -2260,13 +2237,11 @@ public:
DBUG_ASSERT(0);
return TRUE;
}
- if (tst)
- tst->set_isol_level(thd, l);
- }
- else if (tst)
- {
- tst->set_isol_level(thd, TX_ISOL_INHERIT);
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.set_isol_level(thd, l);
}
+ else if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.set_isol_level(thd, TX_ISOL_INHERIT);
#endif //EMBEDDED_LIBRARY
}
return FALSE;
diff --git a/sql/table.cc b/sql/table.cc
index 016fe91c805..9567ed722f1 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -7639,6 +7639,26 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
key_part_info++;
}
+ /*
+ For the case when there is a derived table that would give distinct rows,
+ the index statistics are passed to the join optimizer to tell that a ref
+ access to all the fields of the derived table will produce only one row.
+ */
+
+ st_select_lex_unit* derived= pos_in_table_list ?
+ pos_in_table_list->derived: NULL;
+ if (derived)
+ {
+ st_select_lex* first= derived->first_select();
+ uint select_list_items= first->get_item_list()->elements;
+ if (key_parts == select_list_items)
+ {
+ if ((!first->is_part_of_union() && (first->options & SELECT_DISTINCT)) ||
+ derived->check_distinct_in_union())
+ keyinfo->rec_per_key[key_parts - 1]= 1;
+ }
+ }
+
set_if_bigger(s->max_key_length, keyinfo->key_length);
s->keys++;
return FALSE;
diff --git a/sql/transaction.cc b/sql/transaction.cc
index bb8aaabbcb9..2887ae763df 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -35,10 +35,7 @@ void trans_track_end_trx(THD *thd)
{
#ifndef EMBEDDED_LIBRARY
if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
- {
- ((Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER))->end_trx(thd);
- }
+ thd->session_tracker.transaction_info.end_trx(thd);
#endif //EMBEDDED_LIBRARY
}
@@ -52,11 +49,8 @@ void trans_reset_one_shot_chistics(THD *thd)
#ifndef EMBEDDED_LIBRARY
if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
{
- Transaction_state_tracker *tst= (Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
-
- tst->set_read_flags(thd, TX_READ_INHERIT);
- tst->set_isol_level(thd, TX_ISOL_INHERIT);
+ thd->session_tracker.transaction_info.set_read_flags(thd, TX_READ_INHERIT);
+ thd->session_tracker.transaction_info.set_isol_level(thd, TX_ISOL_INHERIT);
}
#endif //EMBEDDED_LIBRARY
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
@@ -101,20 +95,11 @@ static bool trans_check(THD *thd)
bool trans_begin(THD *thd, uint flags)
{
int res= FALSE;
-#ifndef EMBEDDED_LIBRARY
- Transaction_state_tracker *tst= NULL;
-#endif //EMBEDDED_LIBRARY
DBUG_ENTER("trans_begin");
if (trans_check(thd))
DBUG_RETURN(TRUE);
-#ifndef EMBEDDED_LIBRARY
- if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
- tst= (Transaction_state_tracker *)
- thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
-#endif //EMBEDDED_LIBRARY
-
thd->locked_tables_list.unlock_locked_tables(thd);
DBUG_ASSERT(!thd->locked_tables_mode);
@@ -162,8 +147,8 @@ bool trans_begin(THD *thd, uint flags)
{
thd->tx_read_only= true;
#ifndef EMBEDDED_LIBRARY
- if (tst)
- tst->set_read_flags(thd, TX_READ_ONLY);
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.set_read_flags(thd, TX_READ_ONLY);
#endif //EMBEDDED_LIBRARY
}
else if (flags & MYSQL_START_TRANS_OPT_READ_WRITE)
@@ -187,8 +172,8 @@ bool trans_begin(THD *thd, uint flags)
just from the session's default.
*/
#ifndef EMBEDDED_LIBRARY
- if (tst)
- tst->set_read_flags(thd, TX_READ_WRITE);
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.set_read_flags(thd, TX_READ_WRITE);
#endif //EMBEDDED_LIBRARY
}
@@ -210,16 +195,16 @@ bool trans_begin(THD *thd, uint flags)
DBUG_PRINT("info", ("setting SERVER_STATUS_IN_TRANS"));
#ifndef EMBEDDED_LIBRARY
- if (tst)
- tst->add_trx_state(thd, TX_EXPLICIT);
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.add_trx_state(thd, TX_EXPLICIT);
#endif //EMBEDDED_LIBRARY
/* ha_start_consistent_snapshot() relies on OPTION_BEGIN flag set. */
if (flags & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
{
#ifndef EMBEDDED_LIBRARY
- if (tst)
- tst->add_trx_state(thd, TX_WITH_SNAPSHOT);
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ thd->session_tracker.transaction_info.add_trx_state(thd, TX_WITH_SNAPSHOT);
#endif //EMBEDDED_LIBRARY
res= ha_start_consistent_snapshot(thd);
}
diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc
index 14b294c4214..42856862db3 100644
--- a/sql/wsrep_server_service.cc
+++ b/sql/wsrep_server_service.cc
@@ -46,7 +46,7 @@ wsrep::storage_service* Wsrep_server_service::storage_service(
{
Wsrep_client_service& cs=
static_cast<Wsrep_client_service&>(client_service);
- THD* thd= new THD(next_thread_id(), true, true);
+ THD* thd= new THD(next_thread_id(), true);
init_service_thd(thd, cs.m_thd->thread_stack);
WSREP_DEBUG("Created storage service with thread id %llu",
thd->thread_id);
@@ -58,7 +58,7 @@ wsrep::storage_service* Wsrep_server_service::storage_service(
{
Wsrep_high_priority_service& hps=
static_cast<Wsrep_high_priority_service&>(high_priority_service);
- THD* thd= new THD(next_thread_id(), true, true);
+ THD* thd= new THD(next_thread_id(), true);
init_service_thd(thd, hps.m_thd->thread_stack);
WSREP_DEBUG("Created high priority storage service with thread id %llu",
thd->thread_id);
@@ -81,7 +81,7 @@ Wsrep_server_service::streaming_applier_service(
{
Wsrep_client_service& orig_cs=
static_cast<Wsrep_client_service&>(orig_client_service);
- THD* thd= new THD(next_thread_id(), true, true);
+ THD* thd= new THD(next_thread_id(), true);
init_service_thd(thd, orig_cs.m_thd->thread_stack);
WSREP_DEBUG("Created streaming applier service in local context with "
"thread id %llu", thd->thread_id);
@@ -94,7 +94,7 @@ Wsrep_server_service::streaming_applier_service(
{
Wsrep_high_priority_service&
orig_hps(static_cast<Wsrep_high_priority_service&>(orig_high_priority_service));
- THD* thd= new THD(next_thread_id(), true, true);
+ THD* thd= new THD(next_thread_id(), true);
init_service_thd(thd, orig_hps.m_thd->thread_stack);
WSREP_DEBUG("Created streaming applier service in high priority "
"context with thread id %llu", thd->thread_id);
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 3b784494fda..a41345b43ab 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -171,13 +171,13 @@ buf_buddy_get(
struct CheckZipFree {
CheckZipFree(ulint i) : m_i(i) {}
- void operator()(const buf_buddy_free_t* elem) const
+ void operator()(const buf_buddy_free_t* elem) const
{
- ut_a(buf_buddy_stamp_is_free(elem));
- ut_a(elem->stamp.size <= m_i);
+ ut_ad(buf_buddy_stamp_is_free(elem));
+ ut_ad(elem->stamp.size <= m_i);
}
- ulint m_i;
+ const ulint m_i;
};
/** Validate a buddy list.
@@ -189,8 +189,7 @@ buf_buddy_list_validate(
const buf_pool_t* buf_pool,
ulint i)
{
- CheckZipFree check(i);
- ut_list_validate(buf_pool->zip_free[i], check);
+ ut_list_validate(buf_pool->zip_free[i], CheckZipFree(i));
}
/**********************************************************************//**
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 744b0cb5060..fb3d4d96003 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -325,7 +325,7 @@ too_small:
mtr_commit(&mtr);
/* Flush the modified pages to disk and make a checkpoint */
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_make_checkpoint_at(LSN_MAX);
/* Remove doublewrite pages from LRU */
buf_pool_invalidate();
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 9631102f455..6e3d1fa7356 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -3528,7 +3528,7 @@ buf_flush_request_force(
/** Functor to validate the flush list. */
struct Check {
- void operator()(const buf_page_t* elem)
+ void operator()(const buf_page_t* elem) const
{
ut_a(elem->in_flush_list);
}
@@ -3545,11 +3545,10 @@ buf_flush_validate_low(
{
buf_page_t* bpage;
const ib_rbt_node_t* rnode = NULL;
- Check check;
ut_ad(buf_flush_list_mutex_own(buf_pool));
- ut_list_validate(buf_pool->flush_list, check);
+ ut_list_validate(buf_pool->flush_list, Check());
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc
index 2629e753b5c..8b1966443c9 100644
--- a/storage/innobase/data/data0data.cc
+++ b/storage/innobase/data/data0data.cc
@@ -37,7 +37,7 @@ Created 5/30/1994 Heikki Tuuri
/** Dummy variable to catch access to uninitialized fields. In the
debug version, dtuple_create() will make all fields of dtuple_t point
to data_error. */
-byte data_error;
+ut_d(byte data_error);
#endif /* UNIV_DEBUG */
/** Trim the tail of an index tuple before insert or update.
@@ -455,7 +455,7 @@ dfield_print_also_hex(
break;
}
- data = static_cast<byte*>(dfield_get_data(dfield));
+ data = static_cast<const byte*>(dfield_get_data(dfield));
/* fall through */
case DATA_BINARY:
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 7a6d21dba13..b242b57714f 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -417,45 +417,6 @@ fil_space_crypt_t::write_page0(
}
/******************************************************************
-Set crypt data for a tablespace
-@param[in,out] space Tablespace
-@param[in,out] crypt_data Crypt data to be set
-@return crypt_data in tablespace */
-static
-fil_space_crypt_t*
-fil_space_set_crypt_data(
- fil_space_t* space,
- fil_space_crypt_t* crypt_data)
-{
- fil_space_crypt_t* free_crypt_data = NULL;
- fil_space_crypt_t* ret_crypt_data = NULL;
-
- /* Provided space is protected using fil_space_acquire()
- from concurrent operations. */
- if (space->crypt_data != NULL) {
- /* There is already crypt data present,
- merge new crypt_data */
- fil_space_merge_crypt_data(space->crypt_data,
- crypt_data);
- ret_crypt_data = space->crypt_data;
- free_crypt_data = crypt_data;
- } else {
- space->crypt_data = crypt_data;
- ret_crypt_data = space->crypt_data;
- }
-
- if (free_crypt_data != NULL) {
- /* there was already crypt data present and the new crypt
- * data provided as argument to this function has been merged
- * into that => free new crypt data
- */
- fil_space_destroy_crypt_data(&free_crypt_data);
- }
-
- return ret_crypt_data;
-}
-
-/******************************************************************
Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry
@param[in] ptr Log entry start
@param[in] end_ptr Log entry end
@@ -512,26 +473,36 @@ fil_parse_write_crypt_data(
return NULL;
}
- fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(encryption, key_id);
- /* Need to overwrite these as above will initialize fields. */
+ mutex_enter(&fil_system.mutex);
+
+ fil_space_t* space = fil_space_get_by_id(space_id);
+
+ if (!space) {
+ mutex_exit(&fil_system.mutex);
+ return ptr + len;
+ }
+
+ fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(
+ encryption, key_id);
+
crypt_data->page0_offset = offset;
crypt_data->min_key_version = min_key_version;
- crypt_data->encryption = encryption;
crypt_data->type = type;
memcpy(crypt_data->iv, ptr, len);
ptr += len;
- /* update fil_space memory cache with crypt_data */
- if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- space->release();
- /* Check is used key found from encryption plugin */
- if (crypt_data->should_encrypt()
- && !crypt_data->is_key_found()) {
- *err = DB_DECRYPTION_FAILED;
- }
- } else {
+ if (space->crypt_data) {
+ fil_space_merge_crypt_data(space->crypt_data, crypt_data);
fil_space_destroy_crypt_data(&crypt_data);
+ crypt_data = space->crypt_data;
+ } else {
+ space->crypt_data = crypt_data;
+ }
+
+ mutex_exit(&fil_system.mutex);
+
+ if (crypt_data->should_encrypt() && !crypt_data->is_key_found()) {
+ *err = DB_DECRYPTION_FAILED;
}
return ptr;
@@ -1138,11 +1109,15 @@ fil_crypt_needs_rotation(
if (crypt_data->encryption == FIL_ENCRYPTION_DEFAULT
&& crypt_data->type == CRYPT_SCHEME_1
- && srv_encrypt_tables == 0 ) {
+ && !srv_encrypt_tables) {
/* This is rotation encrypted => unencrypted */
return true;
}
+ if (rotate_key_age == 0) {
+ return false;
+ }
+
/* this is rotation encrypted => encrypted,
* only reencrypt if key is sufficiently old */
if (key_version + rotate_key_age < latest_key_version) {
@@ -1225,7 +1200,8 @@ fil_crypt_start_encrypting_space(
* crypt data in page 0 */
/* 1 - create crypt data */
- crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ crypt_data = fil_space_create_crypt_data(
+ FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
if (crypt_data == NULL) {
mutex_exit(&fil_crypt_threads_mutex);
@@ -1238,9 +1214,9 @@ fil_crypt_start_encrypting_space(
crypt_data->rotate_state.starting = true;
crypt_data->rotate_state.active_threads = 1;
- mutex_enter(&crypt_data->mutex);
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- mutex_exit(&crypt_data->mutex);
+ mutex_enter(&fil_system.mutex);
+ space->crypt_data = crypt_data;
+ mutex_exit(&fil_system.mutex);
fil_crypt_start_converting = true;
mutex_exit(&fil_crypt_threads_mutex);
@@ -2505,6 +2481,64 @@ fil_crypt_set_thread_cnt(
}
}
+/** Initialize the tablespace rotation_list
+if innodb_encryption_rotate_key_age=0. */
+static void fil_crypt_rotation_list_fill()
+{
+ ut_ad(mutex_own(&fil_system.mutex));
+
+ for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
+ if (space->purpose != FIL_TYPE_TABLESPACE
+ || space->is_in_rotation_list()
+ || space->is_stopping()
+ || UT_LIST_GET_LEN(space->chain) == 0) {
+ continue;
+ }
+
+ /* Ensure that crypt_data has been initialized. */
+ if (!space->size) {
+ /* Protect the tablespace while we may
+ release fil_system.mutex. */
+ space->n_pending_ops++;
+ fil_space_t* s= fil_system.read_page0(
+ space->id);
+ ut_ad(!s || s == space);
+ space->n_pending_ops--;
+ if (!space->size) {
+ /* Page 0 was not loaded.
+ Skip this tablespace. */
+ continue;
+ }
+ }
+
+ /* Skip ENCRYPTION!=DEFAULT tablespaces. */
+ if (space->crypt_data
+ && !space->crypt_data->is_default_encryption()) {
+ continue;
+ }
+
+ if (srv_encrypt_tables) {
+ /* Skip encrypted tablespaces if
+ innodb_encrypt_tables!=OFF */
+ if (space->crypt_data
+ && space->crypt_data->min_key_version) {
+ continue;
+ }
+ } else {
+ /* Skip unencrypted tablespaces if
+ innodb_encrypt_tables=OFF */
+ if (!space->crypt_data
+ || !space->crypt_data->min_key_version) {
+ continue;
+ }
+ }
+
+ UT_LIST_ADD_LAST(fil_system.rotation_list, space);
+ }
+}
+
/*********************************************************************
Adjust max key age
@param[in] val New max key age */
@@ -2513,7 +2547,12 @@ void
fil_crypt_set_rotate_key_age(
uint val)
{
+ mutex_enter(&fil_system.mutex);
srv_fil_crypt_rotate_key_age = val;
+ if (val == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+ mutex_exit(&fil_system.mutex);
os_event_set(fil_crypt_threads_event);
}
@@ -2537,7 +2576,16 @@ void
fil_crypt_set_encrypt_tables(
uint val)
{
+ mutex_enter(&fil_system.mutex);
+
srv_encrypt_tables = val;
+
+ if (srv_fil_crypt_rotate_key_age == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+
+ mutex_exit(&fil_system.mutex);
+
os_event_set(fil_crypt_threads_event);
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 1f13e2abfcc..f02f304a858 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -327,6 +327,7 @@ fil_space_get_by_id(
{
fil_space_t* space;
+ ut_ad(fil_system.is_initialised());
ut_ad(mutex_own(&fil_system.mutex));
HASH_SEARCH(hash, fil_system.spaces, id,
@@ -1358,6 +1359,47 @@ fil_assign_new_space_id(
return(success);
}
+/** Trigger a call to fil_node_t::read_page0()
+@param[in] id tablespace identifier
+@return tablespace
+@retval NULL if the tablespace does not exist or cannot be read */
+fil_space_t* fil_system_t::read_page0(ulint id)
+{
+ mutex_exit(&mutex);
+
+ ut_ad(id != 0);
+
+ /* It is possible that the tablespace is dropped while we are
+ not holding the mutex. */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ fil_space_t* space = fil_space_get_by_id(id);
+
+ if (space == NULL || UT_LIST_GET_LEN(space->chain) == 0) {
+ return(NULL);
+ }
+
+ /* The following code must change when InnoDB supports
+ multiple datafiles per tablespace. */
+ ut_a(1 == UT_LIST_GET_LEN(space->chain));
+
+ fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
+
+ /* It must be a single-table tablespace and we have not opened
+ the file yet; the following calls will open it and update the
+ size fields */
+
+ if (!fil_node_prepare_for_io(node, space)) {
+ /* The single-table tablespace can't be opened,
+ because the ibd file is missing. */
+ return(NULL);
+ }
+
+ fil_node_complete_io(node, IORequestRead);
+
+ return space;
+}
+
/*******************************************************************//**
Returns a pointer to the fil_space_t that is in the memory cache
associated with a space id. The caller must lock fil_system.mutex.
@@ -1368,12 +1410,7 @@ fil_space_get_space(
/*================*/
ulint id) /*!< in: space id */
{
- fil_space_t* space;
- fil_node_t* node;
-
- ut_ad(fil_system.is_initialised());
-
- space = fil_space_get_by_id(id);
+ fil_space_t* space = fil_space_get_by_id(id);
if (space == NULL || space->size != 0) {
return(space);
}
@@ -1384,41 +1421,7 @@ fil_space_get_space(
case FIL_TYPE_TEMPORARY:
case FIL_TYPE_TABLESPACE:
case FIL_TYPE_IMPORT:
- ut_a(id != 0);
-
- mutex_exit(&fil_system.mutex);
-
- /* It is possible that the space gets evicted at this point
- before the fil_mutex_enter_and_prepare_for_io() acquires
- the fil_system.mutex. Check for this after completing the
- call to fil_mutex_enter_and_prepare_for_io(). */
- fil_mutex_enter_and_prepare_for_io(id);
-
- /* We are still holding the fil_system.mutex. Check if
- the space is still in memory cache. */
- space = fil_space_get_by_id(id);
-
- if (space == NULL || UT_LIST_GET_LEN(space->chain) == 0) {
- return(NULL);
- }
-
- /* The following code must change when InnoDB supports
- multiple datafiles per tablespace. */
- ut_a(1 == UT_LIST_GET_LEN(space->chain));
-
- node = UT_LIST_GET_FIRST(space->chain);
-
- /* It must be a single-table tablespace and we have not opened
- the file yet; the following calls will open it and update the
- size fields */
-
- if (!fil_node_prepare_for_io(node, space)) {
- /* The single-table tablespace can't be opened,
- because the ibd file is missing. */
- return(NULL);
- }
-
- fil_node_complete_io(node, IORequestRead);
+ space = fil_system.read_page0(id);
}
return(space);
@@ -4587,7 +4590,7 @@ fil_validate(void)
ut_a(fil_system.n_open == n_open);
- UT_LIST_CHECK(fil_system.LRU);
+ ut_list_validate(fil_system.LRU);
for (fil_node = UT_LIST_GET_FIRST(fil_system.LRU);
fil_node != 0;
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index d55cafa8ff2..128518d7433 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -3331,12 +3331,11 @@ fts_fetch_doc_from_tuple(
const dict_field_t* ifield;
const dict_col_t* col;
ulint pos;
- dfield_t* field;
ifield = dict_index_get_nth_field(index, i);
col = dict_field_get_col(ifield);
pos = dict_col_get_no(col);
- field = dtuple_get_nth_field(tuple, pos);
+ const dfield_t* field = dtuple_get_nth_field(tuple, pos);
if (!get_doc->index_cache->charset) {
get_doc->index_cache->charset = fts_get_charset(
diff --git a/storage/innobase/gis/gis0geo.cc b/storage/innobase/gis/gis0geo.cc
index 71d637d62d5..fabe39834f7 100644
--- a/storage/innobase/gis/gis0geo.cc
+++ b/storage/innobase/gis/gis0geo.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, 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
@@ -69,9 +70,9 @@ static
int
rtree_add_point_to_mbr(
/*===================*/
- uchar** wkb, /*!< in: pointer to wkb,
+ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored */
- uchar* end, /*!< in: end of wkb. */
+ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr, which
must be of length n_dims * 2. */
@@ -108,9 +109,9 @@ static
int
rtree_get_point_mbr(
/*================*/
- uchar** wkb, /*!< in: pointer to wkb,
+ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */
- uchar* end, /*!< in: end of wkb. */
+ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
@@ -126,9 +127,9 @@ static
int
rtree_get_linestring_mbr(
/*=====================*/
- uchar** wkb, /*!< in: pointer to wkb,
+ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */
- uchar* end, /*!< in: end of wkb. */
+ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
@@ -155,9 +156,9 @@ static
int
rtree_get_polygon_mbr(
/*==================*/
- uchar** wkb, /*!< in: pointer to wkb,
+ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */
- uchar* end, /*!< in: end of wkb. */
+ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
@@ -190,9 +191,9 @@ static
int
rtree_get_geometry_mbr(
/*===================*/
- uchar** wkb, /*!< in: pointer to wkb,
+ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */
- uchar* end, /*!< in: end of wkb. */
+ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr, /*!< in/out: mbr. */
int top) /*!< in: if it is the top,
@@ -287,7 +288,7 @@ stored in "well-known binary representation" (wkb) format.
int
rtree_mbr_from_wkb(
/*===============*/
- uchar* wkb, /*!< in: wkb */
+ const uchar* wkb, /*!< in: wkb */
uint size, /*!< in: size of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr, which must
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index d77e29d308e..3f9812928a4 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2019, 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
@@ -66,7 +66,7 @@ rtr_page_split_initialize_nodes(
page_t* page;
ulint n_uniq;
ulint len;
- byte* source_cur;
+ const byte* source_cur;
block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
@@ -106,7 +106,7 @@ rtr_page_split_initialize_nodes(
}
/* Put the insert key to node list */
- source_cur = static_cast<byte*>(dfield_get_data(
+ source_cur = static_cast<const byte*>(dfield_get_data(
dtuple_get_nth_field(tuple, 0)));
cur->coords = reserve_coords(buf_pos, SPDIMS);
rec = (byte*) mem_heap_alloc(
@@ -1855,11 +1855,10 @@ rtr_estimate_n_rows_in_range(
/* Read mbr from tuple. */
rtr_mbr_t range_mbr;
double range_area;
- const byte* range_mbr_ptr;
const dfield_t* dtuple_field = dtuple_get_nth_field(tuple, 0);
ut_ad(dfield_get_len(dtuple_field) >= DATA_MBR_LEN);
- range_mbr_ptr = reinterpret_cast<const byte*>(
+ const byte* range_mbr_ptr = reinterpret_cast<const byte*>(
dfield_get_data(dtuple_field));
rtr_read_mbr(range_mbr_ptr, &range_mbr);
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 84d07b5ac52..913a299c118 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -1627,15 +1627,13 @@ rtr_get_mbr_from_tuple(
{
const dfield_t* dtuple_field;
ulint dtuple_f_len;
- byte* data;
dtuple_field = dtuple_get_nth_field(dtuple, 0);
dtuple_f_len = dfield_get_len(dtuple_field);
ut_a(dtuple_f_len >= 4 * sizeof(double));
- data = static_cast<byte*>(dfield_get_data(dtuple_field));
-
- rtr_read_mbr(data, mbr);
+ rtr_read_mbr(static_cast<const byte*>(dfield_get_data(dtuple_field)),
+ mbr);
}
/****************************************************************//**
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index dd79dceed0b..04fdb0ff3b2 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6159,9 +6159,9 @@ no_such_table:
<< n_cols << " user"
" defined columns in InnoDB, but " << n_fields
<< " columns in MariaDB. Please check"
- " INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN
- "innodb-troubleshooting.html for how to resolve the"
- " issue.";
+ " INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and"
+ " https://mariadb.com/kb/en/innodb-data-dictionary-troubleshooting/"
+ " for how to resolve the issue.";
/* Mark this table as corrupted, so the drop table
or force recovery can still use it, but not others. */
@@ -18348,7 +18348,7 @@ checkpoint_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
+ (log_sys.append_on_checkpoint != NULL
? log_sys.append_on_checkpoint->size() : 0)
< log_sys.lsn) {
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_make_checkpoint_at(LSN_MAX);
fil_flush_file_spaces(FIL_TYPE_LOG);
}
@@ -20683,7 +20683,7 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage)
to store the value in passed in "my_rec" */
dfield_t*
innobase_get_computed_value(
- const dtuple_t* row,
+ dtuple_t* row,
const dict_v_col_t* col,
const dict_index_t* index,
mem_heap_t** local_heap,
@@ -21013,11 +21013,11 @@ ib_errf(
/* Keep the first 16 characters as-is, since the url is sometimes used
as an offset from this.*/
const char* TROUBLESHOOTING_MSG =
- "Please refer to " REFMAN "innodb-troubleshooting.html"
+ "Please refer to https://mariadb.com/kb/en/innodb-troubleshooting/"
" for how to resolve the issue.";
const char* TROUBLESHOOT_DATADICT_MSG =
- "Please refer to " REFMAN "innodb-troubleshooting-datadict.html"
+ "Please refer to https://mariadb.com/kb/en/innodb-data-dictionary-troubleshooting/"
" for how to resolve the issue.";
const char* BUG_REPORT_MSG =
@@ -21028,9 +21028,6 @@ const char* FORCE_RECOVERY_MSG =
"https://mariadb.com/kb/en/library/innodb-recovery-modes/"
" for information about forcing recovery.";
-const char* ERROR_CREATING_MSG =
- "Please refer to " REFMAN "error-creating-innodb.html";
-
const char* OPERATING_SYSTEM_ERROR_MSG =
"Some operating system error numbers are described at"
" https://mariadb.com/kb/en/library/operating-system-error-codes/";
@@ -21314,16 +21311,6 @@ innodb_encrypt_tables_validate(
return 1;
}
- if (!srv_fil_crypt_rotate_key_age) {
- const char *msg = (encrypt_tables ? "enable" : "disable");
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- HA_ERR_UNSUPPORTED,
- "InnoDB: cannot %s encryption, "
- "innodb_encryption_rotate_key_age=0"
- " i.e. key rotation disabled", msg);
- return 1;
- }
-
return 0;
}
@@ -21418,8 +21405,7 @@ ib_push_frm_error(
" Have you mixed up "
".frm files from different "
"installations? See "
- REFMAN
- "innodb-troubleshooting.html\n",
+ "https://mariadb.com/kb/en/innodb-troubleshooting/\n",
ib_table->name.m_name);
if (push_warning) {
@@ -21462,8 +21448,7 @@ ib_push_frm_error(
" Have you mixed up "
".frm files from different "
"installations? See "
- REFMAN
- "innodb-troubleshooting.html\n",
+ "https://mariadb.com/kb/en/innodb-troubleshooting/\n",
ib_table->name.m_name, n_keys,
table->s->keys);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 729208dd04c..403dae8334d 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -10989,7 +10989,6 @@ ha_innobase::commit_inplace_alter_table(
and the .frm files must be swapped manually by
the administrator. No loss of data. */
DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit",
- log_make_checkpoint_at(LSN_MAX, TRUE);
log_buffer_flush_to_disk();
DBUG_SUICIDE(););
}
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index db9aa9d66fb..c6f693b1dc2 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -2500,8 +2500,7 @@ struct CheckInLRUList {
static void validate(const buf_pool_t* buf_pool)
{
- CheckInLRUList check;
- ut_list_validate(buf_pool->LRU, check);
+ ut_list_validate(buf_pool->LRU, CheckInLRUList());
}
};
@@ -2514,8 +2513,7 @@ struct CheckInFreeList {
static void validate(const buf_pool_t* buf_pool)
{
- CheckInFreeList check;
- ut_list_validate(buf_pool->free, check);
+ ut_list_validate(buf_pool->free, CheckInFreeList());
}
};
@@ -2528,8 +2526,8 @@ struct CheckUnzipLRUAndLRUList {
static void validate(const buf_pool_t* buf_pool)
{
- CheckUnzipLRUAndLRUList check;
- ut_list_validate(buf_pool->unzip_LRU, check);
+ ut_list_validate(buf_pool->unzip_LRU,
+ CheckUnzipLRUAndLRUList());
}
};
#endif /* UNIV_DEBUG || defined UNIV_BUF_DEBUG */
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 8505505270b..f4f3b3622c5 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -31,6 +31,7 @@ Created 5/30/1994 Heikki Tuuri
#include "data0type.h"
#include "mem0mem.h"
#include "dict0types.h"
+#include "btr0types.h"
#include <ostream>
@@ -39,29 +40,11 @@ index record which needs external storage of data fields */
struct big_rec_t;
struct upd_t;
-#ifdef UNIV_DEBUG
-/*********************************************************************//**
-Gets pointer to the type struct of SQL data field.
-@return pointer to the type struct */
-UNIV_INLINE
-dtype_t*
-dfield_get_type(
-/*============*/
- const dfield_t* field) /*!< in: SQL data field */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Gets pointer to the data in a field.
-@return pointer to data */
-UNIV_INLINE
-void*
-dfield_get_data(
-/*============*/
- const dfield_t* field) /*!< in: field */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-#else /* UNIV_DEBUG */
-# define dfield_get_type(field) (&(field)->type)
-# define dfield_get_data(field) ((field)->data)
-#endif /* UNIV_DEBUG */
+/** Dummy variable to catch access to uninitialized fields. In the
+debug version, dtuple_create() will make all fields of dtuple_t point
+to data_error. */
+ut_d(extern byte data_error);
+
/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
@@ -72,15 +55,6 @@ dfield_set_type(
const dtype_t* type); /*!< in: pointer to data type struct */
/*********************************************************************//**
-Gets length of field data.
-@return length of data; UNIV_SQL_NULL if SQL null data */
-UNIV_INLINE
-ulint
-dfield_get_len(
-/*===========*/
- const dfield_t* field) /*!< in: field */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
@@ -89,32 +63,6 @@ dfield_set_len(
dfield_t* field, /*!< in: field */
ulint len) /*!< in: length or UNIV_SQL_NULL */
MY_ATTRIBUTE((nonnull));
-/*********************************************************************//**
-Determines if a field is SQL NULL
-@return nonzero if SQL null data */
-UNIV_INLINE
-ulint
-dfield_is_null(
-/*===========*/
- const dfield_t* field) /*!< in: field */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Determines if a field is externally stored
-@return nonzero if externally stored */
-UNIV_INLINE
-ulint
-dfield_is_ext(
-/*==========*/
- const dfield_t* field) /*!< in: field */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Sets the "external storage" flag */
-UNIV_INLINE
-void
-dfield_set_ext(
-/*===========*/
- dfield_t* field) /*!< in/out: field */
- MY_ATTRIBUTE((nonnull));
/** Gets spatial status for "external storage"
@param[in,out] field field */
@@ -221,46 +169,7 @@ dfield_data_is_binary_equal(
ulint len, /*!< in: data length or UNIV_SQL_NULL */
const byte* data) /*!< in: data */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Gets number of fields in a data tuple.
-@return number of fields */
-UNIV_INLINE
-ulint
-dtuple_get_n_fields(
-/*================*/
- const dtuple_t* tuple) /*!< in: tuple */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/** Gets number of virtual fields in a data tuple.
-@param[in] tuple dtuple to check
-@return number of fields */
-UNIV_INLINE
-ulint
-dtuple_get_n_v_fields(
- const dtuple_t* tuple);
-#ifdef UNIV_DEBUG
-/** Gets nth field of a tuple.
-@param[in] tuple tuple
-@param[in] n index of field
-@return nth field */
-UNIV_INLINE
-dfield_t*
-dtuple_get_nth_field(
- const dtuple_t* tuple,
- ulint n);
-/** Gets nth virtual field of a tuple.
-@param[in] tuple tuple
-@oaran[in] n the nth field to get
-@return nth field */
-UNIV_INLINE
-dfield_t*
-dtuple_get_nth_v_field(
- const dtuple_t* tuple,
- ulint n);
-#else /* UNIV_DEBUG */
-# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
-# define dtuple_get_nth_v_field(tuple, n) ((tuple)->fields + (tuple)->n_fields + (n))
-#endif /* UNIV_DEBUG */
/*********************************************************************//**
Gets info bits in a data tuple.
@return info bits */
@@ -338,19 +247,12 @@ dtuple_create(
/** Initialize the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields */
-UNIV_INLINE
-void
-dtuple_init_v_fld(
- const dtuple_t* vrow);
+UNIV_INLINE void dtuple_init_v_fld(dtuple_t* vrow);
/** Duplicate the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields
@param[in] heap heap memory to use */
-UNIV_INLINE
-void
-dtuple_dup_v_fld(
- const dtuple_t* vrow,
- mem_heap_t* heap);
+UNIV_INLINE void dtuple_dup_v_fld(dtuple_t* vrow, mem_heap_t* heap);
/** Creates a data tuple with possible virtual columns to a memory heap.
@param[in] heap memory heap where the tuple is created
@@ -672,6 +574,73 @@ struct dtuple_t {
bool is_metadata() const { return is_metadata(info_bits); }
};
+inline ulint dtuple_get_n_fields(const dtuple_t* tuple)
+{ return tuple->n_fields; }
+inline dtype_t* dfield_get_type(dfield_t* field) { return &field->type; }
+inline const dtype_t* dfield_get_type(const dfield_t* field)
+{ return &field->type; }
+inline void* dfield_get_data(dfield_t* field)
+{
+ ut_ad(field->len == UNIV_SQL_NULL || field->data != &data_error);
+ return field->data;
+}
+inline const void* dfield_get_data(const dfield_t* field)
+{
+ ut_ad(field->len == UNIV_SQL_NULL || field->data != &data_error);
+ return field->data;
+}
+inline ulint dfield_get_len(const dfield_t* field) {
+ ut_ad(field->len == UNIV_SQL_NULL || field->data != &data_error);
+ ut_ad(field->len != UNIV_SQL_DEFAULT);
+ return field->len;
+}
+inline bool dfield_is_null(const dfield_t* field)
+{ return field->len == UNIV_SQL_NULL; }
+/** @return whether a column is to be stored off-page */
+inline bool dfield_is_ext(const dfield_t* field)
+{
+ ut_ad(!field->ext || field->len >= BTR_EXTERN_FIELD_REF_SIZE);
+ return static_cast<bool>(field->ext);
+}
+/** Set the "external storage" flag */
+inline void dfield_set_ext(dfield_t* field) { field->ext = 1; }
+
+/** Gets number of virtual fields in a data tuple.
+@param[in] tuple dtuple to check
+@return number of fields */
+inline ulint
+dtuple_get_n_v_fields(const dtuple_t* tuple) { return tuple->n_v_fields; }
+
+inline const dfield_t* dtuple_get_nth_field(const dtuple_t* tuple, ulint n)
+{
+ ut_ad(n < tuple->n_fields);
+ return &tuple->fields[n];
+}
+inline dfield_t* dtuple_get_nth_field(dtuple_t* tuple, ulint n)
+{
+ ut_ad(n < tuple->n_fields);
+ return &tuple->fields[n];
+}
+
+/** Get a virtual column in a table row or an extended clustered index record.
+@param[in] tuple tuple
+@oaran[in] n the nth virtual field to get
+@return nth virtual field */
+inline const dfield_t* dtuple_get_nth_v_field(const dtuple_t* tuple, ulint n)
+{
+ ut_ad(n < tuple->n_v_fields);
+ return &tuple->v_fields[n];
+}
+/** Get a virtual column in a table row or an extended clustered index record.
+@param[in] tuple tuple
+@oaran[in] n the nth virtual field to get
+@return nth virtual field */
+inline dfield_t* dtuple_get_nth_v_field(dtuple_t* tuple, ulint n)
+{
+ ut_ad(n < tuple->n_v_fields);
+ return &tuple->v_fields[n];
+}
+
/** A slot for a field in a big rec vector */
struct big_rec_field_t {
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index 2d5a9810025..0f13c9398c9 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -24,28 +24,7 @@ SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
*************************************************************************/
-#include "mem0mem.h"
#include "ut0rnd.h"
-#include "btr0types.h"
-
-#ifdef UNIV_DEBUG
-/** Dummy variable to catch access to uninitialized fields. In the
-debug version, dtuple_create() will make all fields of dtuple_t point
-to data_error. */
-extern byte data_error;
-
-/*********************************************************************//**
-Gets pointer to the type struct of SQL data field.
-@return pointer to the type struct */
-UNIV_INLINE
-dtype_t*
-dfield_get_type(
-/*============*/
- const dfield_t* field) /*!< in: SQL data field */
-{
- return((dtype_t*) &(field->type));
-}
-#endif /* UNIV_DEBUG */
/*********************************************************************//**
Sets the type struct of SQL data field. */
@@ -62,39 +41,6 @@ dfield_set_type(
field->type = *type;
}
-#ifdef UNIV_DEBUG
-/*********************************************************************//**
-Gets pointer to the data in a field.
-@return pointer to data */
-UNIV_INLINE
-void*
-dfield_get_data(
-/*============*/
- const dfield_t* field) /*!< in: field */
-{
- ut_ad((field->len == UNIV_SQL_NULL)
- || (field->data != &data_error));
-
- return((void*) field->data);
-}
-#endif /* UNIV_DEBUG */
-
-/*********************************************************************//**
-Gets length of field data.
-@return length of data; UNIV_SQL_NULL if SQL null data */
-UNIV_INLINE
-ulint
-dfield_get_len(
-/*===========*/
- const dfield_t* field) /*!< in: field */
-{
- ut_ad((field->len == UNIV_SQL_NULL)
- || (field->data != &data_error));
- ut_ad(field->len != UNIV_SQL_DEFAULT);
-
- return(field->len);
-}
-
/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
@@ -113,42 +59,6 @@ dfield_set_len(
field->len = static_cast<unsigned int>(len);
}
-/*********************************************************************//**
-Determines if a field is SQL NULL
-@return nonzero if SQL null data */
-UNIV_INLINE
-ulint
-dfield_is_null(
-/*===========*/
- const dfield_t* field) /*!< in: field */
-{
- return(field->len == UNIV_SQL_NULL);
-}
-
-/*********************************************************************//**
-Determines if a field is externally stored
-@return nonzero if externally stored */
-UNIV_INLINE
-ulint
-dfield_is_ext(
-/*==========*/
- const dfield_t* field) /*!< in: field */
-{
- ut_ad(!field->ext || field->len >= BTR_EXTERN_FIELD_REF_SIZE);
- return(field->ext);
-}
-
-/*********************************************************************//**
-Sets the "external storage" flag */
-UNIV_INLINE
-void
-dfield_set_ext(
-/*===========*/
- dfield_t* field) /*!< in/out: field */
-{
- field->ext = 1;
-}
-
/** Gets spatial status for "external storage"
@param[in,out] field field */
UNIV_INLINE
@@ -369,63 +279,6 @@ dtuple_set_n_fields_cmp(
tuple->n_fields_cmp = n_fields_cmp;
}
-/*********************************************************************//**
-Gets number of fields in a data tuple.
-@return number of fields */
-UNIV_INLINE
-ulint
-dtuple_get_n_fields(
-/*================*/
- const dtuple_t* tuple) /*!< in: tuple */
-{
- return(tuple->n_fields);
-}
-
-/** Gets the number of virtual fields in a data tuple.
-@param[in] tuple dtuple to check
-@return number of fields */
-UNIV_INLINE
-ulint
-dtuple_get_n_v_fields(
- const dtuple_t* tuple)
-{
- ut_ad(tuple);
-
- return(tuple->n_v_fields);
-}
-#ifdef UNIV_DEBUG
-/** Gets nth field of a tuple.
-@param[in] tuple tuple
-@param[in] n index of field
-@return nth field */
-UNIV_INLINE
-dfield_t*
-dtuple_get_nth_field(
- const dtuple_t* tuple,
- ulint n)
-{
- ut_ad(tuple);
- ut_ad(n < tuple->n_fields);
-
- return((dfield_t*) tuple->fields + n);
-}
-/** Gets nth virtual field of a tuple.
-@param[in] tuple tuple
-@oaran[in] n the nth field to get
-@return nth field */
-UNIV_INLINE
-dfield_t*
-dtuple_get_nth_v_field(
- const dtuple_t* tuple,
- ulint n)
-{
- ut_ad(tuple);
- ut_ad(n < tuple->n_v_fields);
-
- return(static_cast<dfield_t*>(tuple->v_fields + n));
-}
-#endif /* UNIV_DEBUG */
-
/** Creates a data tuple from an already allocated chunk of memory.
The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields).
The default value for number of fields used in record comparisons
@@ -490,12 +343,10 @@ dtuple_create_from_mem(
/** Duplicate the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields
-@param[in] heap heap memory to use */
+@param[in,out] heap heap memory to use */
UNIV_INLINE
void
-dtuple_dup_v_fld(
- const dtuple_t* vrow,
- mem_heap_t* heap)
+dtuple_dup_v_fld(dtuple_t* vrow, mem_heap_t* heap)
{
for (ulint i = 0; i < vrow->n_v_fields; i++) {
dfield_t* dfield = dtuple_get_nth_v_field(vrow, i);
@@ -507,8 +358,7 @@ dtuple_dup_v_fld(
@param[in,out] vrow dtuple contains the virtual fields */
UNIV_INLINE
void
-dtuple_init_v_fld(
- const dtuple_t* vrow)
+dtuple_init_v_fld(dtuple_t* vrow)
{
for (ulint i = 0; i < vrow->n_v_fields; i++) {
dfield_t* dfield = dtuple_get_nth_v_field(vrow, i);
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index b06cb15e64a..bfbe3a3578f 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -959,6 +959,12 @@ public:
/*!< whether fil_space_create()
has issued a warning about
potential space_id reuse */
+
+ /** Trigger a call to fil_node_t::read_page0()
+ @param[in] id tablespace identifier
+ @return tablespace
+ @retval NULL if the tablespace does not exist or cannot be read */
+ fil_space_t* read_page0(ulint id);
};
/** The tablespace memory cache. */
diff --git a/storage/innobase/include/gis0geo.h b/storage/innobase/include/gis0geo.h
index 08895af545e..9a5d426cd7c 100644
--- a/storage/innobase/include/gis0geo.h
+++ b/storage/innobase/include/gis0geo.h
@@ -1,5 +1,6 @@
/*****************************************************************************
Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2019, 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
@@ -73,7 +74,7 @@ stored in "well-known binary representation" (wkb) format.
int
rtree_mbr_from_wkb(
/*===============*/
- uchar* wkb, /*!< in: pointer to wkb. */
+ const uchar* wkb, /*!< in: pointer to wkb. */
uint size, /*!< in: size of wkb. */
uint n_dims, /*!< in: dimensions. */
double* mbr); /*!< in/out: mbr. */
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index ee60bdbf597..96c30c7f757 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -431,7 +431,6 @@ extern const char* TROUBLESHOOTING_MSG;
extern const char* TROUBLESHOOT_DATADICT_MSG;
extern const char* BUG_REPORT_MSG;
extern const char* FORCE_RECOVERY_MSG;
-extern const char* ERROR_CREATING_MSG;
extern const char* OPERATING_SYSTEM_ERROR_MSG;
extern const char* FOREIGN_KEY_CONSTRAINTS_MSG;
extern const char* SET_TRANSACTION_MSG;
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index e088f248681..2fb026849c1 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -190,23 +190,13 @@ blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
log files. Use log_make_checkpoint_at() to flush also the pool.
@param[in] sync whether to wait for the write to complete
-@param[in] write_always force a write even if no log
-has been generated since the latest checkpoint
@return true if success, false if a checkpoint write was already running */
-bool
-log_checkpoint(
- bool sync,
- bool write_always);
+bool log_checkpoint(bool sync);
/** Make a checkpoint at or after a specified LSN.
@param[in] lsn the log sequence number, or LSN_MAX
-for the latest LSN
-@param[in] write_always force a write even if no log
-has been generated since the latest checkpoint */
-void
-log_make_checkpoint_at(
- lsn_t lsn,
- bool write_always);
+for the latest LSN */
+void log_make_checkpoint_at(lsn_t lsn);
/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index 5d5ccac885a..9c1c6a3c38b 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -69,16 +69,6 @@ Initiates the rollback of active transactions. */
void
recv_recovery_rollback_active(void);
/*===============================*/
-/******************************************************//**
-Resets the logs. The contents of log files will be lost! */
-void
-recv_reset_logs(
-/*============*/
- lsn_t lsn); /*!< in: reset to this lsn
- rounded up to be divisible by
- OS_FILE_LOG_BLOCK_SIZE, after
- which we add
- LOG_BLOCK_HDR_SIZE */
/** Clean up after recv_sys_init() */
void
recv_sys_close();
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index 641323e7d41..49d127499f7 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -165,7 +165,9 @@ page_header_set_field(
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
+#if 0 /* FIXME: MDEV-19344 hits this */
ut_ad(field != PAGE_N_RECS || val);
+#endif
ut_ad(field == PAGE_N_HEAP || val < srv_page_size);
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < srv_page_size);
diff --git a/storage/innobase/include/rem0cmp.ic b/storage/innobase/include/rem0cmp.ic
index 290c1455f27..9ba61ca1f94 100644
--- a/storage/innobase/include/rem0cmp.ic
+++ b/storage/innobase/include/rem0cmp.ic
@@ -127,10 +127,10 @@ cmp_dfield_dfield_like_prefix(
if (CHARSET_INFO* cs = get_charset(cs_num, MYF(MY_WME))) {
return(cs->coll->strnncoll(
cs,
- static_cast<uchar*>(
+ static_cast<const uchar*>(
dfield_get_data(dfield1)),
dfield_get_len(dfield1),
- static_cast<uchar*>(
+ static_cast<const uchar*>(
dfield_get_data(dfield2)),
dfield_get_len(dfield2),
1));
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 9d8b425fbba..94307146e9e 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -892,7 +892,7 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage);
@return the field filled with computed value */
dfield_t*
innobase_get_computed_value(
- const dtuple_t* row,
+ dtuple_t* row,
const dict_v_col_t* col,
const dict_index_t* index,
mem_heap_t** local_heap,
diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h
index dd438c366a8..6e3dd394d76 100644
--- a/storage/innobase/include/row0vers.h
+++ b/storage/innobase/include/row0vers.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -110,7 +110,7 @@ row_vers_build_for_consistent_read(
if the history is missing or the record
does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t**vrow); /*!< out: reports virtual column info if any */
+ dtuple_t** vrow); /*!< out: reports virtual column info if any */
/*****************************************************************//**
Constructs the last committed version of a clustered index record,
@@ -136,7 +136,7 @@ row_vers_build_for_semi_consistent_read(
const rec_t** old_vers,/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t**vrow); /*!< out: holds virtual column info if any
+ dtuple_t** vrow); /*!< out: holds virtual column info if any
is updated in the view */
#endif
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index bf8835f189f..dd164b7f973 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -234,7 +234,7 @@ trx_undo_prev_version_build(
dtuple if it is not yet created. This heap
diffs from "heap" above in that it could be
prebuilt->old_vers_heap for selection */
- const dtuple_t**vrow, /*!< out: virtual column info, if any */
+ dtuple_t** vrow, /*!< out: virtual column info, if any */
ulint v_status);
/*!< in: status determine if it is going
into this function by purge thread or not.
@@ -280,7 +280,7 @@ void
trx_undo_read_v_cols(
const dict_table_t* table,
const byte* ptr,
- const dtuple_t* row,
+ dtuple_t* row,
bool in_purge);
/** Read virtual column index from undo log if the undo log contains such
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 277e5842ff6..149d0122576 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -53,8 +53,6 @@ component, i.e. we show M.N.P as M.N */
IB_TO_STR(MYSQL_VERSION_MINOR) "." \
IB_TO_STR(MYSQL_VERSION_PATCH)
-#define REFMAN "http://dev.mysql.com/doc/refman/5.7/en/"
-
/** How far ahead should we tell the service manager the timeout
(time in seconds) */
#define INNODB_EXTEND_TIMEOUT_INTERVAL 30
diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h
index f62d3744b96..986f73ea17c 100644
--- a/storage/innobase/include/ut0lst.h
+++ b/storage/innobase/include/ut0lst.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, 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
@@ -426,24 +427,19 @@ Gets the last node in a two-way list.
@return last node, or NULL if the list is empty */
#define UT_LIST_GET_LAST(BASE) (BASE).end
-struct NullValidate { void operator()(const void*) { } };
+struct NullValidate { void operator()(const void*) const {} };
-/********************************************************************//**
-Iterate over all the elements and call the functor for each element.
+/** Iterate over all the elements and call the functor for each element.
@param[in] list base node (not a pointer to it)
@param[in,out] functor Functor that is called for each element in the list */
template <typename List, class Functor>
-void
-ut_list_map(
- const List& list,
- Functor& functor)
+inline void ut_list_map(const List& list, Functor& functor)
{
- ulint count = 0;
+ ulint count = 0;
UT_LIST_IS_INITIALISED(list);
- for (typename List::elem_type* elem = list.start;
- elem != 0;
+ for (typename List::elem_type* elem = list.start; elem;
elem = (elem->*list.node).next, ++count) {
functor(elem);
@@ -452,32 +448,50 @@ ut_list_map(
ut_a(count == list.count);
}
-template <typename List>
-void
-ut_list_reverse(List& list)
+/** Iterate over all the elements and call the functor for each element.
+@param[in] list base node (not a pointer to it)
+@param[in] functor Functor that is called for each element in the list */
+template <typename List, class Functor>
+inline void ut_list_map(const List& list, const Functor& functor)
{
+ ulint count = 0;
+
UT_LIST_IS_INITIALISED(list);
- for (typename List::elem_type* elem = list.start;
+ for (typename List::elem_type* elem = list.start; elem;
+ elem = (elem->*list.node).next, ++count) {
+
+ functor(elem);
+ }
+
+ ut_a(count == list.count);
+}
+
+/** Check the consistency of a doubly linked list.
+@param[in] list base node (not a pointer to it)
+@param[in,out] functor Functor that is called for each element in the list */
+template <typename List, class Functor>
+void ut_list_validate(const List& list, Functor& functor)
+{
+ ut_list_map(list, functor);
+
+ /* Validate the list backwards. */
+ ulint count = 0;
+
+ for (typename List::elem_type* elem = list.end;
elem != 0;
elem = (elem->*list.node).prev) {
- (elem->*list.node).reverse();
+ ++count;
}
- list.reverse();
+ ut_a(count == list.count);
}
-#define UT_LIST_REVERSE(LIST) ut_list_reverse(LIST)
-
-/********************************************************************//**
-Checks the consistency of a two-way list.
-@param[in] list base node (not a pointer to it)
-@param[in,out] functor Functor that is called for each element in the list */
+/** Check the consistency of a doubly linked list.
+@param[in] list base node (not a pointer to it)
+@param[in] functor Functor that is called for each element in the list */
template <typename List, class Functor>
-void
-ut_list_validate(
- const List& list,
- Functor& functor)
+inline void ut_list_validate(const List& list, const Functor& functor)
{
ut_list_map(list, functor);
@@ -493,12 +507,42 @@ ut_list_validate(
ut_a(count == list.count);
}
-/** Check the consistency of a two-way list.
-@param[in] LIST base node reference */
-#define UT_LIST_CHECK(LIST) do { \
- NullValidate nullV; \
- ut_list_validate(LIST, nullV); \
-} while (0)
+template <typename List>
+inline void ut_list_validate(const List& list)
+{
+ ut_list_validate(list, NullValidate());
+}
+
+#ifdef UNIV_DEBUG
+template <typename List>
+inline void ut_list_reverse(List& list)
+{
+ UT_LIST_IS_INITIALISED(list);
+
+ for (typename List::elem_type* elem = list.start;
+ elem != 0;
+ elem = (elem->*list.node).prev) {
+ (elem->*list.node).reverse();
+ }
+
+ list.reverse();
+}
+
+/** Check if the given element exists in the list.
+@param[in,out] list the list object
+@param[in] elem the element of the list which will be checked */
+template <typename List>
+inline bool ut_list_exists(const List& list, typename List::elem_type* elem)
+{
+ for (typename List::elem_type* e1 = UT_LIST_GET_FIRST(list); e1;
+ e1 = (e1->*list.node).next) {
+ if (elem == e1) {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
/** Move the given element to the beginning of the list.
@param[in,out] list the list object
@@ -519,28 +563,6 @@ ut_list_move_to_front(
}
#ifdef UNIV_DEBUG
-/** Check if the given element exists in the list.
-@param[in,out] list the list object
-@param[in] elem the element of the list which will be checked */
-template <typename List>
-bool
-ut_list_exists(
- List& list,
- typename List::elem_type* elem)
-{
- typename List::elem_type* e1;
-
- for (e1 = UT_LIST_GET_FIRST(list); e1 != NULL;
- e1 = (e1->*list.node).next) {
- if (elem == e1) {
- return(true);
- }
- }
- return(false);
-}
#endif
-#define UT_LIST_MOVE_TO_FRONT(LIST, ELEM) \
- ut_list_move_to_front(LIST, ELEM)
-
#endif /* ut0lst.h */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 2d6a643c4ea..0c232878c3c 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2581,7 +2581,7 @@ lock_move_granted_locks_to_front(
if (!lock->is_waiting()) {
lock_t* prev = UT_LIST_GET_PREV(trx_locks, lock);
ut_a(prev);
- UT_LIST_MOVE_TO_FRONT(lock_list, lock);
+ ut_list_move_to_front(lock_list, lock);
lock = prev;
}
}
@@ -2669,7 +2669,7 @@ lock_move_reorganize_page(
lock_move_granted_locks_to_front(old_locks);
DBUG_EXECUTE_IF("do_lock_reverse_page_reorganize",
- UT_LIST_REVERSE(old_locks););
+ ut_list_reverse(old_locks););
for (lock = UT_LIST_GET_FIRST(old_locks); lock;
lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
@@ -4620,29 +4620,6 @@ lock_print_info_summary(
return(TRUE);
}
-/** Functor to print not-started transaction from the trx_list. */
-
-struct PrintNotStarted {
-
- PrintNotStarted(FILE* file) : m_file(file) { }
-
- void operator()(const trx_t* trx)
- {
- ut_ad(mutex_own(&trx_sys.mutex));
-
- /* See state transitions and locking rules in trx0trx.h */
-
- if (trx->mysql_thd
- && trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
-
- fputs("---", m_file);
- trx_print_latched(m_file, trx, 600);
- }
- }
-
- FILE* m_file;
-};
-
/** Prints transaction lock wait and MVCC state.
@param[in,out] file file where to print
@param[in] trx transaction */
@@ -4715,29 +4692,24 @@ lock_trx_print_locks(
}
}
-
-static my_bool lock_print_info_all_transactions_callback(
- rw_trx_hash_element_t *element, FILE *file)
+/** Functor to display all transactions */
+struct lock_print_info
{
- mutex_enter(&element->mutex);
- if (trx_t *trx= element->trx)
+ lock_print_info(FILE* file) : file(file) {}
+
+ void operator()(const trx_t* trx) const
{
- check_trx_state(trx);
+ ut_ad(mutex_own(&trx_sys.mutex));
+ if (trx == purge_sys.query->trx)
+ return;
lock_trx_print_wait_and_mvcc_state(file, trx);
- if (srv_print_innodb_lock_monitor)
- {
- trx->reference();
- mutex_exit(&element->mutex);
+ if (trx->will_lock && srv_print_innodb_lock_monitor)
lock_trx_print_locks(file, trx);
- trx->release_reference();
- return 0;
- }
}
- mutex_exit(&element->mutex);
- return 0;
-}
+ FILE* const file;
+};
/*********************************************************************//**
Prints info of locks for each transaction. This function assumes that the
@@ -4752,20 +4724,9 @@ lock_print_info_all_transactions(
fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n");
- /* First print info on non-active transactions */
-
- /* NOTE: information of auto-commit non-locking read-only
- transactions will be omitted here. The information will be
- available from INFORMATION_SCHEMA.INNODB_TRX. */
-
- PrintNotStarted print_not_started(file);
mutex_enter(&trx_sys.mutex);
- ut_list_map(trx_sys.trx_list, print_not_started);
+ ut_list_map(trx_sys.trx_list, lock_print_info(file));
mutex_exit(&trx_sys.mutex);
-
- trx_sys.rw_trx_hash.iterate_no_dups(
- reinterpret_cast<my_hash_walk_action>
- (lock_print_info_all_transactions_callback), file);
lock_mutex_exit();
ut_ad(lock_validate());
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index a6f8ea99dcf..3a8bd63fcdd 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -326,7 +326,7 @@ log_margin_checkpoint_age(
if (!flushed_enough) {
os_thread_sleep(100000);
}
- log_checkpoint(true, false);
+ log_checkpoint(true);
log_mutex_enter();
}
@@ -1405,13 +1405,8 @@ blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
log files. Use log_make_checkpoint_at() to flush also the pool.
@param[in] sync whether to wait for the write to complete
-@param[in] write_always force a write even if no log
-has been generated since the latest checkpoint
@return true if success, false if a checkpoint write was already running */
-bool
-log_checkpoint(
- bool sync,
- bool write_always)
+bool log_checkpoint(bool sync)
{
lsn_t oldest_lsn;
@@ -1454,9 +1449,15 @@ log_checkpoint(
flushed up to oldest_lsn. */
ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn);
- if (!write_always
- && oldest_lsn
- <= log_sys.last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
+ if (oldest_lsn
+ > log_sys.last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
+ /* Some log has been written since the previous checkpoint. */
+ } else if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ /* MariaDB 10.3 startup expects the redo log file to be
+ logically empty (not even containing a MLOG_CHECKPOINT record)
+ after a clean shutdown. Perform an extra checkpoint at
+ shutdown. */
+ } else {
/* Do nothing, because nothing was logged (other than
a MLOG_CHECKPOINT marker) since the previous checkpoint. */
log_mutex_exit();
@@ -1488,20 +1489,6 @@ log_checkpoint(
log_write_up_to(flush_lsn, true, true);
- DBUG_EXECUTE_IF(
- "using_wa_checkpoint_middle",
- if (write_always) {
- DEBUG_SYNC_C("wa_checkpoint_middle");
-
- const my_bool b = TRUE;
- buf_flush_page_cleaner_disabled_debug_update(
- NULL, NULL, NULL, &b);
- dict_stats_disabled_debug_update(
- NULL, NULL, NULL, &b);
- srv_master_thread_disabled_debug_update(
- NULL, NULL, NULL, &b);
- });
-
log_mutex_enter();
ut_ad(log_sys.flushed_to_disk_lsn >= flush_lsn);
@@ -1534,13 +1521,8 @@ log_checkpoint(
/** Make a checkpoint at or after a specified LSN.
@param[in] lsn the log sequence number, or LSN_MAX
-for the latest LSN
-@param[in] write_always force a write even if no log
-has been generated since the latest checkpoint */
-void
-log_make_checkpoint_at(
- lsn_t lsn,
- bool write_always)
+for the latest LSN */
+void log_make_checkpoint_at(lsn_t lsn)
{
/* Preflush pages synchronously */
@@ -1548,7 +1530,7 @@ log_make_checkpoint_at(
/* Flush as much as we can */
}
- while (!log_checkpoint(true, write_always)) {
+ while (!log_checkpoint(true)) {
/* Force a checkpoint */
}
}
@@ -1628,7 +1610,7 @@ loop:
}
if (do_checkpoint) {
- log_checkpoint(checkpoint_sync, FALSE);
+ log_checkpoint(checkpoint_sync);
if (checkpoint_sync) {
@@ -1877,7 +1859,7 @@ wait_suspend_loop:
if (!srv_read_only_mode) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"ensuring dirty buffer pool are written to log");
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_make_checkpoint_at(LSN_MAX);
log_mutex_enter();
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 32c63546e5d..420f186b5fb 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2739,11 +2739,6 @@ loop:
if (lsn == checkpoint_lsn) {
if (recv_sys->mlog_checkpoint_lsn) {
- /* At recv_reset_logs() we may
- write a duplicate MLOG_CHECKPOINT
- for the same checkpoint LSN. Thus
- recv_sys->mlog_checkpoint_lsn
- can differ from the current LSN. */
ut_ad(recv_sys->mlog_checkpoint_lsn
<= recv_sys->recovered_lsn);
break;
@@ -3872,49 +3867,6 @@ recv_recovery_rollback_active(void)
}
}
-/******************************************************//**
-Resets the logs. The contents of log files will be lost! */
-void
-recv_reset_logs(
-/*============*/
- lsn_t lsn) /*!< in: reset to this lsn
- rounded up to be divisible by
- OS_FILE_LOG_BLOCK_SIZE, after
- which we add
- LOG_BLOCK_HDR_SIZE */
-{
- ut_ad(log_mutex_own());
-
- log_sys.lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);
-
- log_sys.log.set_lsn(log_sys.lsn);
- log_sys.log.set_lsn_offset(LOG_FILE_HDR_SIZE);
-
- log_sys.buf_next_to_write = 0;
- log_sys.write_lsn = log_sys.lsn;
-
- log_sys.next_checkpoint_no = 0;
- log_sys.last_checkpoint_lsn = 0;
-
- memset(log_sys.buf, 0, srv_log_buffer_size);
- log_block_init(log_sys.buf, log_sys.lsn);
- log_block_set_first_rec_group(log_sys.buf, LOG_BLOCK_HDR_SIZE);
-
- log_sys.buf_free = LOG_BLOCK_HDR_SIZE;
- log_sys.lsn += LOG_BLOCK_HDR_SIZE;
-
- MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
- (log_sys.lsn - log_sys.last_checkpoint_lsn));
-
- log_mutex_exit();
-
- /* Reset the checkpoint fields in logs */
-
- log_make_checkpoint_at(LSN_MAX, TRUE);
-
- log_mutex_enter();
-}
-
/** Find a doublewrite copy of a page.
@param[in] space_id tablespace identifier
@param[in] page_no page number
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index ded109138dc..77f5ba7c113 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -7743,13 +7743,8 @@ invalid:
return false;
}
- ut_ad(space->free_limit == 0 || space->free_limit == free_limit);
- ut_ad(space->free_len == 0 || space->free_len == free_len);
- space->size_in_header = size;
- space->free_limit = free_limit;
- space->free_len = free_len;
-
if (first) {
+ ut_ad(space->id != TRX_SYS_SPACE);
#ifdef UNIV_LINUX
find_metadata(handle, &statbuf);
#else
@@ -7770,8 +7765,19 @@ invalid:
this->size = ulint(size_bytes / psize);
space->size += this->size;
+ } else if (space->id != TRX_SYS_SPACE || space->size_in_header) {
+ /* If this is not the first-time open, do nothing.
+ For the system tablespace, we always get invoked as
+ first=false, so we detect the true first-time-open based
+ on size_in_header and proceed to initiailze the data. */
+ return true;
}
+ ut_ad(space->free_limit == 0 || space->free_limit == free_limit);
+ ut_ad(space->free_len == 0 || space->free_len == free_len);
+ space->size_in_header = size;
+ space->free_limit = free_limit;
+ space->free_len = free_len;
return true;
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index fdd352390da..9ef737828a0 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -2140,7 +2140,7 @@ row_import_cleanup(
DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE(););
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_make_checkpoint_at(LSN_MAX);
return(err);
}
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index cc30de70798..adb154c8446 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -2782,8 +2782,7 @@ do_insert:
DBUG_EXECUTE_IF(
"row_ins_extern_checkpoint",
- log_make_checkpoint_at(
- LSN_MAX, TRUE););
+ log_write_up_to(mtr.commit_lsn(), true););
err = row_ins_index_entry_big_rec(
entry, big_rec, offsets, &offsets_heap, index,
thr_get_trx(thr)->mysql_thd);
@@ -3413,14 +3412,14 @@ row_ins_spatial_index_entry_set_mbr_field(
dfield_t* field, /*!< in/out: mbr field */
const dfield_t* row_field) /*!< in: row field */
{
- uchar* dptr = NULL;
ulint dlen = 0;
double mbr[SPDIMS * 2];
/* This must be a GEOMETRY datatype */
ut_ad(DATA_GEOMETRY_MTYPE(field->type.mtype));
- dptr = static_cast<uchar*>(dfield_get_data(row_field));
+ const byte* dptr = static_cast<const byte*>(
+ dfield_get_data(row_field));
dlen = dfield_get_len(row_field);
/* obtain the MBR */
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 989f242cf6c..469a25e6836 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -453,7 +453,7 @@ row_merge_buf_redundant_convert(
ut_ad(field_len <= len);
if (row_field->ext) {
- const byte* field_data = static_cast<byte*>(
+ const byte* field_data = static_cast<const byte*>(
dfield_get_data(row_field));
ulint ext_len;
@@ -483,7 +483,7 @@ row_merge_buf_redundant_convert(
@param[in] old_table original table
@param[in] new_table new table
@param[in,out] psort_info parallel sort info
-@param[in] row table row
+@param[in,out] row table row
@param[in] ext cache of externally stored
column prefixes, or NULL
@param[in,out] doc_id Doc ID if we are creating
@@ -505,7 +505,7 @@ row_merge_buf_add(
const dict_table_t* old_table,
const dict_table_t* new_table,
fts_psort_t* psort_info,
- const dtuple_t* row,
+ dtuple_t* row,
const row_ext_t* ext,
doc_id_t* doc_id,
mem_heap_t* conv_heap,
@@ -642,7 +642,7 @@ row_merge_buf_add(
row,
index->table->fts->doc_col);
*doc_id = (doc_id_t) mach_read_from_8(
- static_cast<byte*>(
+ static_cast<const byte*>(
dfield_get_data(doc_field)));
if (*doc_id == 0) {
@@ -1935,7 +1935,7 @@ row_merge_read_clustered_index(
const rec_t* rec;
trx_id_t rec_trx_id;
ulint* offsets;
- const dtuple_t* row;
+ dtuple_t* row;
row_ext_t* ext;
page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
@@ -2244,9 +2244,8 @@ end_of_index:
history_row = dfield->vers_history_row();
}
- dfield_t* dfield;
-
- dfield = dtuple_get_nth_field(row, add_autoinc);
+ dfield_t* dfield = dtuple_get_nth_field(row,
+ add_autoinc);
if (new_table->versioned()) {
if (history_row) {
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 1225c7f35f4..afbcdfe4423 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2979,13 +2979,13 @@ row_discard_tablespace_end(
}
DBUG_EXECUTE_IF("ib_discard_before_commit_crash",
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_write_up_to(LSN_MAX, true);
DBUG_SUICIDE(););
trx_commit_for_mysql(trx);
DBUG_EXECUTE_IF("ib_discard_after_commit_crash",
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_write_up_to(LSN_MAX, true);
DBUG_SUICIDE(););
row_mysql_unlock_data_dictionary(trx);
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index d7191a5971d..c200e6fb15c 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -83,20 +83,21 @@ static bool row_build_spatial_index_key(
return true;
}
- uchar* dptr = NULL;
+ const byte* dptr = NULL;
ulint dlen = 0;
ulint flen = 0;
double tmp_mbr[SPDIMS * 2];
mem_heap_t* temp_heap = NULL;
if (!dfield_is_ext(dfield2)) {
- dptr = static_cast<uchar*>(dfield_get_data(dfield2));
+ dptr = static_cast<const byte*>(dfield_get_data(dfield2));
dlen = dfield_get_len(dfield2);
goto write_mbr;
}
if (flag == ROW_BUILD_FOR_PURGE) {
- byte* ptr = static_cast<byte*>(dfield_get_data(dfield2));
+ const byte* ptr = static_cast<const byte*>(
+ dfield_get_data(dfield2));
switch (dfield_get_spatial_status(dfield2)) {
case SPATIAL_ONLY:
@@ -140,12 +141,12 @@ static bool row_build_spatial_index_key(
log record, and avoid recomputing it here! */
flen = BTR_EXTERN_FIELD_REF_SIZE;
ut_ad(dfield_get_len(dfield2) >= BTR_EXTERN_FIELD_REF_SIZE);
- dptr = static_cast<byte*>(dfield_get_data(dfield2))
+ dptr = static_cast<const byte*>(dfield_get_data(dfield2))
+ dfield_get_len(dfield2)
- BTR_EXTERN_FIELD_REF_SIZE;
} else {
flen = dfield_get_len(dfield2);
- dptr = static_cast<byte*>(dfield_get_data(dfield2));
+ dptr = static_cast<const byte*>(dfield_get_data(dfield2));
}
temp_heap = mem_heap_create(1000);
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 9a3f3bb9be7..20df64d599f 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -224,7 +224,6 @@ row_sel_sec_rec_is_for_clust_rec(
reconstructed from base column in cluster index */
if (is_virtual) {
const dict_v_col_t* v_col;
- const dtuple_t* row;
dfield_t* vfield;
row_ext_t* ext;
@@ -241,10 +240,11 @@ row_sel_sec_rec_is_for_clust_rec(
v_col = reinterpret_cast<const dict_v_col_t*>(col);
- row = row_build(ROW_COPY_POINTERS,
- clust_index, clust_rec,
- clust_offs,
- NULL, NULL, NULL, &ext, heap);
+ dtuple_t* row = row_build(
+ ROW_COPY_POINTERS,
+ clust_index, clust_rec,
+ clust_offs,
+ NULL, NULL, NULL, &ext, heap);
vfield = innobase_get_computed_value(
row, v_col, clust_index,
@@ -804,7 +804,7 @@ row_sel_build_committed_vers_for_mysql(
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- const dtuple_t**vrow, /*!< out: to be filled with old virtual
+ dtuple_t** vrow, /*!< out: to be filled with old virtual
column version if any */
mtr_t* mtr) /*!< in: mtr */
{
@@ -3181,7 +3181,7 @@ row_sel_build_prev_vers_for_mysql(
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- const dtuple_t**vrow, /*!< out: dtuple to hold old virtual
+ dtuple_t** vrow, /*!< out: dtuple to hold old virtual
column data */
mtr_t* mtr) /*!< in: mtr */
{
@@ -3225,7 +3225,7 @@ row_sel_get_clust_rec_for_mysql(
rec_get_offsets(out_rec, clust_index) */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- const dtuple_t**vrow, /*!< out: virtual column to fill */
+ dtuple_t** vrow, /*!< out: virtual column to fill */
mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to
access the clustered index */
@@ -3947,7 +3947,7 @@ void
row_sel_fill_vrow(
const rec_t* rec,
dict_index_t* index,
- const dtuple_t** vrow,
+ dtuple_t** vrow,
mem_heap_t* heap)
{
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4143,7 +4143,7 @@ row_search_mvcc(
dict_index_t* clust_index;
que_thr_t* thr;
const rec_t* UNINIT_VAR(rec);
- const dtuple_t* vrow = NULL;
+ dtuple_t* vrow = NULL;
const rec_t* result_rec = NULL;
const rec_t* clust_rec;
dberr_t err = DB_SUCCESS;
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 88a0bce52a6..e1403eea93b 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -791,7 +791,7 @@ row_upd_index_write_log(
mlog_catenate_string(
mtr,
- static_cast<byte*>(
+ static_cast<const byte*>(
dfield_get_data(new_val)),
len);
@@ -988,8 +988,6 @@ row_upd_build_difference_binary(
dberr_t* error)
{
upd_field_t* upd_field;
- dfield_t* dfield;
- const byte* data;
ulint len;
upd_t* update;
ulint n_diff;
@@ -1015,9 +1013,9 @@ row_upd_build_difference_binary(
}
for (i = 0; i < n_fld; i++) {
- data = rec_get_nth_cfield(rec, index, offsets, i, &len);
-
- dfield = dtuple_get_nth_field(entry, i);
+ const byte* data = rec_get_nth_cfield(rec, index, offsets, i,
+ &len);
+ const dfield_t* dfield = dtuple_get_nth_field(entry, i);
/* NOTE: we compare the fields as binary strings!
(No collation) */
@@ -1078,8 +1076,6 @@ row_upd_build_difference_binary(
index->table, NULL, NULL, &ext, heap);
}
- dfield = dtuple_get_nth_v_field(entry, i);
-
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&v_heap, heap, NULL, thd, mysql_table, record,
@@ -1090,6 +1086,9 @@ row_upd_build_difference_binary(
return(NULL);
}
+ const dfield_t* dfield = dtuple_get_nth_v_field(
+ entry, i);
+
if (!dfield_data_is_binary_equal(
dfield, vfield->len,
static_cast<byte*>(vfield->data))) {
@@ -1734,7 +1733,7 @@ row_upd_changes_ord_field_binary_func(
double mbr2[SPDIMS * 2];
rtr_mbr_t* old_mbr;
rtr_mbr_t* new_mbr;
- uchar* dptr = NULL;
+ const uchar* dptr = NULL;
ulint flen = 0;
ulint dlen = 0;
mem_heap_t* temp_heap = NULL;
@@ -1753,7 +1752,7 @@ row_upd_changes_ord_field_binary_func(
/* For off-page stored data, we
need to read the whole field data. */
flen = dfield_get_len(dfield);
- dptr = static_cast<byte*>(
+ dptr = static_cast<const byte*>(
dfield_get_data(dfield));
temp_heap = mem_heap_create(1000);
@@ -1763,7 +1762,7 @@ row_upd_changes_ord_field_binary_func(
flen,
temp_heap);
} else {
- dptr = static_cast<uchar*>(dfield->data);
+ dptr = static_cast<const uchar*>(dfield->data);
dlen = dfield->len;
}
@@ -1806,13 +1805,13 @@ row_upd_changes_ord_field_binary_func(
flen = BTR_EXTERN_FIELD_REF_SIZE;
ut_ad(dfield_get_len(new_field) >=
BTR_EXTERN_FIELD_REF_SIZE);
- dptr = static_cast<byte*>(
+ dptr = static_cast<const byte*>(
dfield_get_data(new_field))
+ dfield_get_len(new_field)
- BTR_EXTERN_FIELD_REF_SIZE;
} else {
flen = dfield_get_len(new_field);
- dptr = static_cast<byte*>(
+ dptr = static_cast<const byte*>(
dfield_get_data(new_field));
}
@@ -1826,7 +1825,8 @@ row_upd_changes_ord_field_binary_func(
flen,
temp_heap);
} else {
- dptr = static_cast<uchar*>(upd_field->new_val.data);
+ dptr = static_cast<const byte*>(
+ upd_field->new_val.data);
dlen = upd_field->new_val.len;
}
rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE,
@@ -1884,7 +1884,7 @@ row_upd_changes_ord_field_binary_func(
ut_a(dict_index_is_clust(index)
|| ind_field->prefix_len <= dfield_len);
- buf = static_cast<byte*>(dfield_get_data(dfield));
+ buf= static_cast<const byte*>(dfield_get_data(dfield));
copy_dfield:
ut_a(dfield_len > 0);
dfield_copy(&dfield_ext, dfield);
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index f31ae1573cf..bc84348384e 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -98,7 +98,7 @@ row_vers_impl_x_locked_low(
mem_heap_t* heap;
dtuple_t* ientry = NULL;
mem_heap_t* v_heap = NULL;
- const dtuple_t* cur_vrow = NULL;
+ dtuple_t* cur_vrow = NULL;
DBUG_ENTER("row_vers_impl_x_locked_low");
@@ -181,7 +181,7 @@ row_vers_impl_x_locked_low(
ulint vers_del;
trx_id_t prev_trx_id;
mem_heap_t* old_heap = heap;
- const dtuple_t* vrow = NULL;
+ dtuple_t* vrow = NULL;
/* We keep the semaphore in mtr on the clust_rec page, so
that no other transaction can update it and get an
@@ -515,7 +515,7 @@ row_vers_build_cur_vrow_low(
roll_ptr_t roll_ptr,
trx_id_t trx_id,
mem_heap_t* v_heap,
- const dtuple_t** vrow,
+ dtuple_t** vrow,
mtr_t* mtr)
{
const rec_t* version;
@@ -632,7 +632,7 @@ row_vers_vc_matches_cluster(
roll_ptr_t roll_ptr,
trx_id_t trx_id,
mem_heap_t* v_heap,
- const dtuple_t**vrow,
+ dtuple_t** vrow,
mtr_t* mtr)
{
const rec_t* version;
@@ -796,7 +796,7 @@ func_exit:
@param[in,out] vcol_info virtual column information for purge thread
@return dtuple contains virtual column data */
static
-const dtuple_t*
+dtuple_t*
row_vers_build_cur_vrow(
bool in_purge,
const rec_t* rec,
@@ -810,7 +810,7 @@ row_vers_build_cur_vrow(
mtr_t* mtr,
purge_vcol_info_t* vcol_info)
{
- const dtuple_t* cur_vrow = NULL;
+ dtuple_t* cur_vrow = NULL;
roll_ptr_t t_roll_ptr = row_get_rec_roll_ptr(
rec, clust_index, *clust_offsets);
@@ -891,9 +891,9 @@ row_vers_old_has_index_entry(
dtuple_t* row;
const dtuple_t* entry;
ulint comp;
- const dtuple_t* vrow = NULL;
+ dtuple_t* vrow = NULL;
mem_heap_t* v_heap = NULL;
- const dtuple_t* cur_vrow = NULL;
+ dtuple_t* cur_vrow = NULL;
ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
@@ -1155,7 +1155,7 @@ row_vers_build_for_consistent_read(
if the history is missing or the record
does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t**vrow) /*!< out: virtual row */
+ dtuple_t** vrow) /*!< out: virtual row */
{
const rec_t* version;
rec_t* prev_version;
@@ -1269,7 +1269,7 @@ row_vers_build_for_semi_consistent_read(
const rec_t** old_vers,/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t** vrow) /*!< out: virtual row, old version, or NULL
+ dtuple_t** vrow) /*!< out: virtual row, old version, or NULL
if it is not updated in the view */
{
const rec_t* version;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 528384eaa3f..8501ffbf672 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2185,7 +2185,7 @@ srv_master_do_active_tasks(void)
/* Make a new checkpoint */
if (cur_time % SRV_MASTER_CHECKPOINT_INTERVAL == 0) {
srv_main_thread_op_info = "making checkpoint";
- log_checkpoint(TRUE, FALSE);
+ log_checkpoint(true);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_CHECKPOINT_MICROSECOND, counter_time);
}
@@ -2273,7 +2273,7 @@ srv_master_do_idle_tasks(void)
/* Make a new checkpoint */
srv_main_thread_op_info = "making checkpoint";
- log_checkpoint(TRUE, FALSE);
+ log_checkpoint(true);
MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_CHECKPOINT_MICROSECOND,
counter_time);
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index b1c0748a52e..2337dfaada2 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -487,9 +487,30 @@ create_log_files(
return(DB_ERROR);
}
ut_d(recv_no_log_write = false);
- recv_reset_logs(lsn);
+ log_sys.lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);
+
+ log_sys.log.set_lsn(log_sys.lsn);
+ log_sys.log.set_lsn_offset(LOG_FILE_HDR_SIZE);
+
+ log_sys.buf_next_to_write = 0;
+ log_sys.write_lsn = log_sys.lsn;
+
+ log_sys.next_checkpoint_no = 0;
+ log_sys.last_checkpoint_lsn = 0;
+
+ memset(log_sys.buf, 0, srv_log_buffer_size);
+ log_block_init(log_sys.buf, log_sys.lsn);
+ log_block_set_first_rec_group(log_sys.buf, LOG_BLOCK_HDR_SIZE);
+
+ log_sys.buf_free = LOG_BLOCK_HDR_SIZE;
+ log_sys.lsn += LOG_BLOCK_HDR_SIZE;
+
+ MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
+ (log_sys.lsn - log_sys.last_checkpoint_lsn));
log_mutex_exit();
+ log_make_checkpoint_at(LSN_MAX);
+
return(DB_SUCCESS);
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index f56691bd4ec..9fdbe0a7aeb 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -400,8 +400,6 @@ trx_undo_report_insert_virtual(
for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table);
col_no++) {
- dfield_t* vfield = NULL;
-
const dict_v_col_t* col
= dict_table_get_nth_v_col(table, col_no);
@@ -424,7 +422,8 @@ trx_undo_report_insert_virtual(
return(false);
}
- vfield = dtuple_get_nth_v_field(row, col->v_pos);
+ const dfield_t* vfield = dtuple_get_nth_v_field(
+ row, col->v_pos);
ulint flen = vfield->len;
if (flen != UNIV_SQL_NULL) {
@@ -1394,8 +1393,6 @@ already_logged:
for (col_no = 0; col_no < dict_table_get_n_v_cols(table);
col_no++) {
- dfield_t* vfield = NULL;
-
const dict_v_col_t* col
= dict_table_get_nth_v_col(table, col_no);
@@ -1424,6 +1421,8 @@ already_logged:
return(0);
}
+ const dfield_t* vfield = NULL;
+
if (update) {
ut_ad(!row);
if (update->old_vrow == NULL) {
@@ -2338,7 +2337,7 @@ trx_undo_prev_version_build(
dtuple if it is not yet created. This heap
diffs from "heap" above in that it could be
prebuilt->old_vers_heap for selection */
- const dtuple_t**vrow, /*!< out: virtual column info, if any */
+ dtuple_t** vrow, /*!< out: virtual column info, if any */
ulint v_status)
/*!< in: status determine if it is going
into this function by purge thread or not.
@@ -2539,7 +2538,7 @@ void
trx_undo_read_v_cols(
const dict_table_t* table,
const byte* ptr,
- const dtuple_t* row,
+ dtuple_t* row,
bool in_purge)
{
const byte* end_ptr;
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index a420ac1d0d8..7ef6b88a9a9 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1529,7 +1529,8 @@ void trx_commit_low(trx_t* trx, mtr_t* mtr)
DBUG_EXECUTE_IF("ib_crash_during_trx_commit_in_mem",
if (trx->has_logged()) {
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ log_write_up_to(mtr->commit_lsn(),
+ true);
DBUG_SUICIDE();
});
/*--------------*/
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
index 0c61ff09af2..3be57e27943 100644
--- a/unittest/mysys/CMakeLists.txt
+++ b/unittest/mysys/CMakeLists.txt
@@ -14,7 +14,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
- aes
+ aes byte_order
LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
diff --git a/unittest/mysys/byte_order-t.c b/unittest/mysys/byte_order-t.c
new file mode 100644
index 00000000000..e276e597fbf
--- /dev/null
+++ b/unittest/mysys/byte_order-t.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2019, 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
+ 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-1301 USA */
+
+/**
+ @file
+
+ Unit tests for serialization and deserialization functions
+*/
+
+#include "tap.h"
+
+#include "my_byteorder.h"
+#include "myisampack.h"
+#include "m_string.h"
+
+void test_byte_order()
+{
+ MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE)
+ uchar buf[CPU_LEVEL1_DCACHE_LINESIZE * 2];
+
+ uchar *aligned= buf;
+ uchar *not_aligned= buf + CPU_LEVEL1_DCACHE_LINESIZE - 1;
+
+#define TEST(STORE_NAME, LOAD_NAME, TYPE, VALUE, BYTES) \
+ { \
+ TYPE value= VALUE; \
+ uchar bytes[]= BYTES; \
+ STORE_NAME(aligned, value); \
+ ok(!memcmp(aligned, bytes, sizeof(bytes)), "aligned\t\t" #STORE_NAME); \
+ ok(LOAD_NAME(aligned) == value, "aligned\t\t" #LOAD_NAME); \
+ STORE_NAME(not_aligned, value); \
+ ok(!memcmp(not_aligned, bytes, sizeof(bytes)), \
+ "not aligned\t" #STORE_NAME); \
+ ok(LOAD_NAME(not_aligned) == value, "not aligned\t" #LOAD_NAME); \
+ }
+
+#define ARRAY_2(A, B) {A, B}
+#define ARRAY_3(A, B, C) {A, B, C}
+#define ARRAY_4(A, B, C, D) {A, B, C, D}
+#define ARRAY_5(A, B, C, D, E) {A, B, C, D, E}
+#define ARRAY_6(A, B, C, D, E, F) {A, B, C, D, E, F}
+#define ARRAY_7(A, B, C, D, E, F, G) {A, B, C, D, E, F, G}
+#define ARRAY_8(A, B, C, D, E, F, G, H) {A, B, C, D, E, F, G, H}
+
+ TEST(int2store, sint2korr, int16, 0x0201, ARRAY_2(1, 2));
+ TEST(int3store, sint3korr, int32, 0xffffffff, ARRAY_3(0xff, 0xff, 0xff));
+ TEST(int3store, sint3korr, int32, 0x030201, ARRAY_3(1, 2, 3));
+ TEST(int4store, sint4korr, int32, 0xffffffff,
+ ARRAY_4(0xff, 0xff, 0xff, 0xff));
+ TEST(int4store, sint4korr, int32, 0x04030201, ARRAY_4(1, 2, 3, 4));
+ TEST(int8store, sint8korr, longlong, 0x0807060504030201,
+ ARRAY_8(1, 2, 3, 4, 5, 6, 7, 8));
+ TEST(int8store, sint8korr, longlong, 0xffffffffffffffff,
+ ARRAY_8(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff));
+
+ TEST(int2store, uint2korr, uint16, 0x0201, ARRAY_2(1, 2));
+ TEST(int3store, uint3korr, uint32, 0x030201, ARRAY_3(1, 2, 3));
+ TEST(int4store, uint4korr, uint32, 0x04030201, ARRAY_4(1, 2, 3, 4));
+ TEST(int5store, uint5korr, ulonglong, 0x0504030201, ARRAY_5(1, 2, 3, 4, 5));
+ TEST(int6store, uint6korr, ulonglong, 0x060504030201,
+ ARRAY_6(1, 2, 3, 4, 5, 6));
+ TEST(int8store, uint8korr, ulonglong, 0x0807060504030201,
+ ARRAY_8(1, 2, 3, 4, 5, 6, 7, 8));
+
+ TEST(mi_int5store, mi_uint5korr, ulonglong, 0x0504030201,
+ ARRAY_5(5, 4, 3, 2, 1));
+ TEST(mi_int6store, mi_uint6korr, ulonglong, 0x060504030201,
+ ARRAY_6(6, 5, 4, 3, 2, 1));
+ TEST(mi_int7store, mi_uint7korr, ulonglong, 0x07060504030201,
+ ARRAY_7(7, 6, 5, 4, 3, 2, 1));
+ TEST(mi_int8store, mi_uint8korr, ulonglong, 0x0807060504030201,
+ ARRAY_8(8, 7, 6, 5, 4, 3, 2, 1));
+
+#undef ARRAY_8
+#undef ARRAY_7
+#undef ARRAY_6
+#undef ARRAY_5
+#undef ARRAY_4
+#undef ARRAY_3
+#undef ARRAY_2
+
+#undef TEST
+}
+
+int main(int argc, char **argv)
+{
+ plan(68);
+ test_byte_order();
+ return exit_status();
+}