diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-11-19 15:52:14 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-11-19 15:52:14 +0100 |
commit | beded7d9c9592ca8fdfc367f7c64f89c35995c44 (patch) | |
tree | a215a54ed5043bb17fe7d69a69439e05b21682d5 | |
parent | af71da5d2f90c82b2357e808640003907c488bc2 (diff) | |
parent | 2553f143fdeb9068eb02a8fda58750c24071f5ef (diff) | |
download | mariadb-git-beded7d9c9592ca8fdfc367f7c64f89c35995c44.tar.gz |
Merge branch '10.0' into 10.1
186 files changed, 2825 insertions, 963 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 92324c6a073..29e39b6adcb 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1106,7 +1106,7 @@ inline int get_command_index(char cmd_char) All client-specific commands are in the first part of commands array and have a function to implement it. */ - for (uint i= 0; *commands[i].func; i++) + for (uint i= 0; commands[i].func; i++) if (commands[i].cmd_char == cmd_char) return i; return -1; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 27b969f1036..e9896d9f6e6 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -879,6 +879,7 @@ static const char *expected_errors[]= "ERROR 1060", /* Duplicate column name */ "ERROR 1061", /* Duplicate key name */ "ERROR 1054", /* Unknown column */ + "ERROR 1290", /* RR_OPTION_PREVENTS_STATEMENT */ 0 }; diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c6144d9c5e4..3bbfc70eaed 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5101,7 +5101,7 @@ static st_error global_error_names[] = #include <my_base.h> static st_error handler_error_names[] = { - { "<No error>", -1U, "" }, + { "<No error>", UINT_MAX, "" }, #include <handler_ername.h> { 0, 0, 0 } }; diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake index c61e4f9d941..4c35c688a5d 100644 --- a/cmake/os/Windows.cmake +++ b/cmake/os/Windows.cmake @@ -95,8 +95,11 @@ IF(MSVC) STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}") STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}") STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}") + STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}") + STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}") SET(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /OPT:REF /release") ENDFOREACH() + # Mark 32 bit executables large address aware so they can # use > 2GB address space @@ -112,7 +115,7 @@ IF(MSVC) #TODO: update the code and remove the disabled warnings SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805 /wd4996") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805 /wd4996 /we4099") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805 /wd4996 /wd4291 /we4099") IF(CMAKE_SIZEOF_VOID_P MATCHES 8) # _WIN64 is defined by the compiler itself. @@ -180,14 +183,14 @@ CHECK_SYMBOL_REPLACEMENT(S_IROTH _S_IREAD sys/stat.h) CHECK_SYMBOL_REPLACEMENT(S_IFIFO _S_IFIFO sys/stat.h) CHECK_SYMBOL_REPLACEMENT(SIGQUIT SIGTERM signal.h) CHECK_SYMBOL_REPLACEMENT(SIGPIPE SIGINT signal.h) -CHECK_SYMBOL_REPLACEMENT(isnan _isnan float.h) -CHECK_SYMBOL_REPLACEMENT(finite _finite float.h) +CHECK_SYMBOL_REPLACEMENT(isnan _isnan "math.h;float.h") +CHECK_SYMBOL_REPLACEMENT(finite _finite "math;float.h") CHECK_FUNCTION_REPLACEMENT(popen _popen) CHECK_FUNCTION_REPLACEMENT(pclose _pclose) CHECK_FUNCTION_REPLACEMENT(access _access) CHECK_FUNCTION_REPLACEMENT(strcasecmp _stricmp) CHECK_FUNCTION_REPLACEMENT(strncasecmp _strnicmp) -CHECK_FUNCTION_REPLACEMENT(snprintf _snprintf) +CHECK_SYMBOL_REPLACEMENT(snprintf _snprintf stdio.h) CHECK_FUNCTION_REPLACEMENT(strtok_r strtok_s) CHECK_FUNCTION_REPLACEMENT(strtoll _strtoi64) CHECK_FUNCTION_REPLACEMENT(strtoull _strtoui64) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 86c1e425f0c..07a8085a411 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -102,7 +102,6 @@ SET(HAVE_IPPROTO_IPV6 CACHE INTERNAL "") SET(HAVE_IPV6 TRUE CACHE INTERNAL "") SET(HAVE_IPV6_V6ONLY 1 CACHE INTERNAL "") SET(HAVE_ISINF CACHE INTERNAL "") -SET(HAVE_ISNAN CACHE INTERNAL "") SET(HAVE_ISSETUGID CACHE INTERNAL "") SET(HAVE_GETUID CACHE INTERNAL "") SET(HAVE_GETEUID CACHE INTERNAL "") @@ -232,7 +231,6 @@ SET(HAVE_SIZEOF_ULONG FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_U_INT32_T FALSE CACHE INTERNAL "") SET(HAVE_SIZE_OF_SSIZE_T FALSE CACHE INTERNAL "") SET(HAVE_SLEEP CACHE INTERNAL "") -SET(HAVE_SNPRINTF CACHE INTERNAL "") SET(HAVE_SOCKADDR_STORAGE_SS_FAMILY 1 CACHE INTERNAL "") SET(HAVE_SOLARIS_STYLE_GETHOST CACHE INTERNAL "") SET(STACK_DIRECTION -1 CACHE INTERNAL "") @@ -326,10 +324,8 @@ SET(WORDS_BIGENDIAN CACHE INTERNAL "") SET(HAVE__S_IFIFO 1 CACHE INTERNAL "") SET(HAVE__S_IREAD 1 CACHE INTERNAL "") SET(HAVE__finite 1 CACHE INTERNAL "") -SET(HAVE__isnan 1 CACHE INTERNAL "") SET(HAVE__pclose 1 CACHE INTERNAL "") SET(HAVE__popen 1 CACHE INTERNAL "") -SET(HAVE__snprintf 1 CACHE INTERNAL "") SET(HAVE__stricmp 1 CACHE INTERNAL "") SET(HAVE__strnicmp 1 CACHE INTERNAL "") SET(HAVE__strtoi64 1 CACHE INTERNAL "") diff --git a/config.h.cmake b/config.h.cmake index 96165c16aa0..cc54511e360 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -325,6 +325,8 @@ #cmakedefine HAVE_TIMESPEC_TS_SEC 1 #cmakedefine STRUCT_DIRENT_HAS_D_INO 1 #cmakedefine STRUCT_DIRENT_HAS_D_NAMLEN 1 +#cmakedefine STRUCT_TIMESPEC_HAS_TV_SEC 1 +#cmakedefine STRUCT_TIMESPEC_HAS_TV_NSEC 1 #cmakedefine SPRINTF_RETURNS_INT 1 #define USE_MB 1 @@ -496,6 +498,7 @@ #define SYSTEM_TYPE "@SYSTEM_TYPE@" #define MACHINE_TYPE "@CMAKE_SYSTEM_PROCESSOR@" +#define DEFAULT_MACHINE "@DEFAULT_MACHINE@" #cmakedefine HAVE_DTRACE 1 #cmakedefine SIGNAL_WITH_VIO_CLOSE 1 @@ -521,6 +524,10 @@ #cmakedefine strtoll @strtoll@ #cmakedefine strtoull @strtoull@ #cmakedefine vsnprintf @vsnprintf@ +#if (_MSC_VER > 1800) +#define tzname _tzname +#define P_tmpdir "C:\\TEMP" +#endif #if (_MSC_VER > 1310) # define HAVE_SETENV #define setenv(a,b,c) _putenv_s(a,b) @@ -529,7 +536,7 @@ /* We don't want the min/max macros */ #ifdef __WIN__ -#define NOMINMAX +#define NOMINMAX 1 #endif /* diff --git a/configure.cmake b/configure.cmake index e8d29c5bf5f..aaf0268888a 100644 --- a/configure.cmake +++ b/configure.cmake @@ -1067,6 +1067,9 @@ CHECK_STRUCT_HAS_MEMBER("struct dirent" d_namlen "dirent.h" STRUCT_DIRENT_HAS_D SET(SPRINTF_RETURNS_INT 1) CHECK_INCLUDE_FILE(ucontext.h HAVE_UCONTEXT_H) +CHECK_STRUCT_HAS_MEMBER("struct timespec" tv_sec "time.h" STRUCT_TIMESPEC_HAS_TV_SEC) +CHECK_STRUCT_HAS_MEMBER("struct timespec" tv_nsec "time.h" STRUCT_TIMESPEC_HAS_TV_NSEC) + IF(NOT MSVC) CHECK_C_SOURCE_RUNS( " diff --git a/include/decimal.h b/include/decimal.h index 935d341437d..2adeb824318 100644 --- a/include/decimal.h +++ b/include/decimal.h @@ -16,6 +16,10 @@ #ifndef _decimal_h #define _decimal_h +#ifdef __cplusplus +extern "C" { +#endif + typedef enum {TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR} decimal_round_mode; @@ -112,5 +116,9 @@ void max_decimal(int precision, int frac, decimal_t *to); #define E_DEC_ERROR 31 #define E_DEC_FATAL_ERROR 30 +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index 1b7d289b2ef..374529c573a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -86,10 +86,12 @@ typedef volatile LONG my_pthread_once_t; #define MY_PTHREAD_ONCE_INPROGRESS 1 #define MY_PTHREAD_ONCE_DONE 2 +#if !STRUCT_TIMESPEC_HAS_TV_SEC || !STRUCT_TIMESPEC_HAS_TV_NSEC struct timespec { time_t tv_sec; long tv_nsec; }; +#endif int win_pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *); diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index 84884f9565a..e30cdc9762b 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -90,7 +90,7 @@ const char *client_errors[]= "" }; -const char** get_client_errmsgs() +const char** get_client_errmsgs(void) { return client_errors; } diff --git a/mysql-test/extra/binlog_tests/database.test b/mysql-test/extra/binlog_tests/database.test index 05a00c58840..6b3da087f01 100644 --- a/mysql-test/extra/binlog_tests/database.test +++ b/mysql-test/extra/binlog_tests/database.test @@ -52,7 +52,7 @@ eval SELECT 'hello' INTO OUTFILE 'fake_file.$prefix'; # Use '/' instead of '\' in the error message. On windows platform, dir is # formed with '\'. ---replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ +--replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ /17/39/ /File exists/Directory not empty/ --error 1010 DROP DATABASE testing_1; let $wait_binlog_event= DROP TABLE IF EXIST; diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index a16e82f2364..17b2fd5b2bc 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -33,7 +33,6 @@ debug-no-sync # Retry bind as this may fail on busy server port-open-timeout=10 -bind-address=127.0.0.1 log-bin-trust-function-creators=1 key_buffer_size= 1M @@ -42,6 +41,9 @@ max_heap_table_size= 1M loose-aria-pagecache-buffer-size=8M loose-feedback-user-info= mysql-test +loose-feedback-debug-startup-interval=20 +loose-feedback-debug-first-interval=60 +loose-feedback-debug-interval=60 loose-innodb_data_file_path= ibdata1:12M:autoextend loose-innodb_buffer_pool_size= 8M diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index 356bf6dc727..eefefe4bfbe 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -10,7 +10,8 @@ if ($binlog_file) { --let $_in_binlog_file=in '$binlog_file' } ---replace_result $_binlog_start <binlog_start> $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--let $_from_binlog_start=from $_binlog_start +--replace_result "$_from_binlog_start" "from <binlog_start>" $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_column 2 # 5 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ --eval show binlog events $_in_binlog_file from $_binlog_start diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 8c19ed58665..5b0bc0fd856 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -169,6 +169,13 @@ sub fix_log { return "$dir/mysqld.log"; } +sub fix_bind_address { + if (IS_WINDOWS) { + return "*"; + } else { + return "127.0.0.1"; + } +} sub fix_log_slow_queries { my ($self, $config, $group_name, $group)= @_; my $dir= dirname($group->value('datadir')); @@ -251,6 +258,7 @@ my @mysqld_rules= { 'ssl-ca' => \&fix_ssl_ca }, { 'ssl-cert' => \&fix_ssl_server_cert }, { 'ssl-key' => \&fix_ssl_server_key }, + { 'bind-address' => \&fix_bind_address }, ); if (IS_WINDOWS) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 2c2275462cc..9c0a25f6d61 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2021,6 +2021,15 @@ t1 CREATE TABLE `t1` ( UNIQUE KEY `idx` (`i`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 ( +`event_id` bigint(20) unsigned NOT NULL DEFAULT '0', +`market_id` bigint(20) unsigned NOT NULL DEFAULT '0', +PRIMARY KEY (`event_id`,`market_id`) +); +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS event_id (event_id,market_id); +Warnings: +Note 1061 Multiple primary key defined +DROP TABLE t1; # # MDEV-7374 : Losing connection to MySQL while running ALTER TABLE # @@ -2045,6 +2054,3 @@ t1 CREATE TABLE `t1` ( KEY `i1` (`a`) COMMENT 'comment2' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; -# -# Start of 10.1 tests -# diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index 04ab385bca6..62e3b1c7331 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1805,5 +1805,20 @@ set impressions = column_add(impressions, ); drop table t1; # +# MDEV-8565: COLUMN_CHECK fails on valid data +# +SELECT COLUMN_CHECK(COLUMN_CREATE('a',0,'b','1')); +COLUMN_CHECK(COLUMN_CREATE('a',0,'b','1')) +1 +SELECT COLUMN_CHECK(COLUMN_CREATE('a',1,'b','1')); +COLUMN_CHECK(COLUMN_CREATE('a',1,'b','1')) +1 +SELECT COLUMN_JSON(COLUMN_CREATE('a',0,'b','1')); +COLUMN_JSON(COLUMN_CREATE('a',0,'b','1')) +{"a":0,"b":"1"} +SELECT COLUMN_JSON(COLUMN_CREATE('a',1,'b','1')); +COLUMN_JSON(COLUMN_CREATE('a',1,'b','1')) +{"a":1,"b":"1"} +# # end of 10.0 tests # diff --git a/mysql-test/r/events_restart.result b/mysql-test/r/events_restart.result index ba3aa503b63..0caac907f64 100644 --- a/mysql-test/r/events_restart.result +++ b/mysql-test/r/events_restart.result @@ -18,7 +18,7 @@ change column body body longtext character set utf8 collate utf8_bin; use events_test; select @@event_scheduler; @@event_scheduler -DISABLED +OFF show events; ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start select event_name from information_schema.events; @@ -40,12 +40,12 @@ ERROR HY000: Cannot proceed because system tables used by Event Scheduler were f drop event intact_check; ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start set global event_scheduler=on; -ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start +ERROR HY000: Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler. set global event_scheduler=off; -ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start +ERROR HY000: Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler. show variables like 'event_scheduler'; Variable_name Value -event_scheduler DISABLED +event_scheduler OFF Make sure that we still can create and drop databases, and no warnings are produced. drop database if exists mysqltest_database_not_exists; @@ -58,6 +58,22 @@ Error 1545 Failed to open mysql.event Restore the original mysql.event table drop table mysql.event; rename table event_like to mysql.event; +check that we can now enable events without restart +set global event_scheduler=original; +Warnings: +Note 1408 Event Scheduler: Loaded 3 events +select @@global.event_scheduler; +@@global.event_scheduler +ON +set global event_scheduler=on; +select @@global.event_scheduler; +@@global.event_scheduler +ON +show events; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +events_test abc1 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +events_test abc2 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +events_test abc3 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci Now let's restart the server again use events_test; select @@event_scheduler; diff --git a/mysql-test/r/init_file_set_password-7656.result b/mysql-test/r/init_file_set_password-7656.result new file mode 100644 index 00000000000..e5b3fc75706 --- /dev/null +++ b/mysql-test/r/init_file_set_password-7656.result @@ -0,0 +1,8 @@ +create user foo@localhost; +select user,host,password from mysql.user where user='foo'; +user host password +foo localhost +select user,host,password from mysql.user where user='foo'; +user host password +foo localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +drop user foo@localhost; diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result index 4c4cdb76615..dea4670d2c7 100644 --- a/mysql-test/r/lowercase_fs_off.result +++ b/mysql-test/r/lowercase_fs_off.result @@ -65,4 +65,9 @@ CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a= 1; RENAME TABLE t1 TO T1; ALTER TABLE T1 RENAME t1; DROP TABLE t1; +create table t1 (a int); +create trigger t1_bi before insert on t1 for each row set new.a= 1; +show triggers like '%T1%'; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +drop table t1; set GLOBAL sql_mode=default; diff --git a/mysql-test/r/mysql_upgrade-6984.result b/mysql-test/r/mysql_upgrade-6984.result index 7890b66d494..6aea4806ddb 100644 --- a/mysql-test/r/mysql_upgrade-6984.result +++ b/mysql-test/r/mysql_upgrade-6984.result @@ -57,3 +57,4 @@ Phase 6/6: Running 'FLUSH PRIVILEGES' OK update mysql.user set password='' where user='root'; flush privileges; +set global event_scheduler=OFF; diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 8a72d5fe3b1..bfe9dc96bc2 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -767,3 +767,37 @@ f1 f2 f3 f4 f5 f6 INSERT INTO t3 SELECT * FROM t2 WHERE f3 = 'm' AND f2 ='c'; DROP TABLE t1,t2,t3; set global default_storage_engine=default; +# +# Bug#13737949: CRASH IN HA_PARTITION::INDEX_INIT +# Bug#18694052: SERVER CRASH IN HA_PARTITION::INIT_RECORD_PRIORITY_QUEUE +# +CREATE TABLE t1 +(a INT, +b INT, +PRIMARY KEY (a)) +ENGINE = InnoDB +PARTITION BY HASH (a) PARTITIONS 3; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +# con1 +ALTER TABLE t1 ADD INDEX idx1 (b); +# con default +SELECT b FROM t1 WHERE b = 0; +ERROR HY000: Table definition has changed, please retry transaction +SELECT b FROM t1 WHERE b = 0; +ERROR HY000: Table definition has changed, please retry transaction +DROP TABLE t1; +# Same test without partitioning +CREATE TABLE t1 +(a INT, +b INT, +PRIMARY KEY (a)) +ENGINE = InnoDB; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +# con1 +ALTER TABLE t1 ADD INDEX idx1 (b); +# con default +SELECT b FROM t1 WHERE b = 0; +ERROR HY000: Table definition has changed, please retry transaction +SELECT b FROM t1 WHERE b = 0; +ERROR HY000: Table definition has changed, please retry transaction +DROP TABLE t1; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 1bdfaa7cc70..e8a7eb133fb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4053,3 +4053,24 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)' drop table t1; # End of 5.3 tests +# +# MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +# +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +id value +1 1 +2 1 +3 NULL +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; +# End of 10.0 tests diff --git a/mysql-test/r/ps_change_master.result b/mysql-test/r/ps_change_master.result new file mode 100644 index 00000000000..25069a537a5 --- /dev/null +++ b/mysql-test/r/ps_change_master.result @@ -0,0 +1,22 @@ +# +# CHANGE MASTER TO doesn't work with prepared statements +# +CHANGE MASTER TO MASTER_HOST='host1', MASTER_USER='user1'; +# Master_Host : host1 +# Master_User : user1 +SET @s := "CHANGE MASTER TO MASTER_HOST='host2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +# Master_Host : host2 +# Master_User : user1 +SET @s := "CHANGE MASTER TO MASTER_USER='user2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +# Master_Host : host2 +# Master_User : user2 +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +# End of test diff --git a/mysql-test/r/skip_grants.result b/mysql-test/r/skip_grants.result index 9852d6d12c1..b167a197e50 100644 --- a/mysql-test/r/skip_grants.result +++ b/mysql-test/r/skip_grants.result @@ -59,7 +59,9 @@ DROP FUNCTION f1; DROP FUNCTION f2; DROP FUNCTION f3; set global event_scheduler=1; -ERROR HY000: The MariaDB server is running with the --event-scheduler=DISABLED or --skip-grant-tables option so it cannot execute this statement +Warnings: +Note 1408 Event Scheduler: Loaded 0 events +set global event_scheduler=0; select count(*) from information_schema.COLUMN_PRIVILEGES; count(*) 0 diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index 285284596c4..fcced761283 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -421,4 +421,99 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where DROP TABLE t1,t2; +# +# MDEV-7370: Server deadlocks on renaming a table for which persistent statistics exists +# +drop database if exists db1; +drop database if exists db1; +create database db1; +create database db2; +use db1; +# +# First, run the original testcase: +# +create table t1 (i int); +insert into t1 values (10),(20); +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +db1.t1 analyze status Engine-independent statistics collected +db1.t1 analyze status OK +rename table t1 to db2.t1; +# Verify that stats in the old database are gone: +select * from mysql.column_stats where db_name='db1' and table_name='t1'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.table_stats where db_name='db1' and table_name='t1'; +db_name table_name cardinality +# Verify that stats are present in the new database: +select * from mysql.column_stats where db_name='db2' and table_name='t1'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t1 i 10 20 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.table_stats where db_name='db2' and table_name='t1'; +db_name table_name cardinality +db2 t1 2 +# +# Now, try with more than one column and with indexes: +# +use test; +create table t1(a int primary key); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +use db1; +create table t2 (a int, b int, c int, key IDX1(a), key IDX2(a,b)); +insert into t2 select a/10, a/2, a from test.t1; +analyze table t2 persistent for all; +Table Op Msg_type Msg_text +db1.t2 analyze status Engine-independent statistics collected +db1.t2 analyze status Table is already up to date +alter table t2 rename db2.t2; +# Verify that stats in the old database are gone: +select * from mysql.table_stats where db_name='db1' and table_name='t2'; +db_name table_name cardinality +select * from mysql.column_stats where db_name='db1' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.index_stats where db_name='db1' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +# Verify that stats are present in the new database: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +db_name table_name cardinality +db2 t2 10 +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t2 a 0 1 0.0000 4.0000 5.0000 0 NULL NULL +db2 t2 b 0 5 0.0000 4.0000 1.6667 0 NULL NULL +db2 t2 c 0 9 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.index_stats where db_name='db2' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +db2 t2 IDX1 1 5.0000 +db2 t2 IDX2 1 5.0000 +db2 t2 IDX2 2 1.6667 +use db2; +# +# Now, rename within the same database and verify: +# +rename table t2 to t3; +# No stats under old name: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +db_name table_name cardinality +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.index_stats where db_name='db2' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +# Stats under the new name: +select * from mysql.table_stats where db_name='db2' and table_name='t3'; +db_name table_name cardinality +db2 t3 10 +select * from mysql.column_stats where db_name='db2' and table_name='t3'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t3 a 0 1 0.0000 4.0000 5.0000 0 NULL NULL +db2 t3 b 0 5 0.0000 4.0000 1.6667 0 NULL NULL +db2 t3 c 0 9 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.index_stats where db_name='db2' and table_name='t3'; +db_name table_name index_name prefix_arity avg_frequency +db2 t3 IDX1 1 5.0000 +db2 t3 IDX2 1 5.0000 +db2 t3 IDX2 2 1.6667 +use test; +drop database db1; +drop database db2; +drop table t1; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 301c093ce9c..0e866755532 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -448,6 +448,101 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where DROP TABLE t1,t2; +# +# MDEV-7370: Server deadlocks on renaming a table for which persistent statistics exists +# +drop database if exists db1; +drop database if exists db1; +create database db1; +create database db2; +use db1; +# +# First, run the original testcase: +# +create table t1 (i int); +insert into t1 values (10),(20); +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +db1.t1 analyze status Engine-independent statistics collected +db1.t1 analyze status OK +rename table t1 to db2.t1; +# Verify that stats in the old database are gone: +select * from mysql.column_stats where db_name='db1' and table_name='t1'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.table_stats where db_name='db1' and table_name='t1'; +db_name table_name cardinality +# Verify that stats are present in the new database: +select * from mysql.column_stats where db_name='db2' and table_name='t1'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t1 i 10 20 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.table_stats where db_name='db2' and table_name='t1'; +db_name table_name cardinality +db2 t1 2 +# +# Now, try with more than one column and with indexes: +# +use test; +create table t1(a int primary key); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +use db1; +create table t2 (a int, b int, c int, key IDX1(a), key IDX2(a,b)); +insert into t2 select a/10, a/2, a from test.t1; +analyze table t2 persistent for all; +Table Op Msg_type Msg_text +db1.t2 analyze status Engine-independent statistics collected +db1.t2 analyze status OK +alter table t2 rename db2.t2; +# Verify that stats in the old database are gone: +select * from mysql.table_stats where db_name='db1' and table_name='t2'; +db_name table_name cardinality +select * from mysql.column_stats where db_name='db1' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.index_stats where db_name='db1' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +# Verify that stats are present in the new database: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +db_name table_name cardinality +db2 t2 10 +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t2 a 0 1 0.0000 4.0000 5.0000 0 NULL NULL +db2 t2 b 0 5 0.0000 4.0000 1.6667 0 NULL NULL +db2 t2 c 0 9 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.index_stats where db_name='db2' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +db2 t2 IDX1 1 5.0000 +db2 t2 IDX2 1 5.0000 +db2 t2 IDX2 2 1.6667 +use db2; +# +# Now, rename within the same database and verify: +# +rename table t2 to t3; +# No stats under old name: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +db_name table_name cardinality +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +select * from mysql.index_stats where db_name='db2' and table_name='t2'; +db_name table_name index_name prefix_arity avg_frequency +# Stats under the new name: +select * from mysql.table_stats where db_name='db2' and table_name='t3'; +db_name table_name cardinality +db2 t3 10 +select * from mysql.column_stats where db_name='db2' and table_name='t3'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +db2 t3 a 0 1 0.0000 4.0000 5.0000 0 NULL NULL +db2 t3 b 0 5 0.0000 4.0000 1.6667 0 NULL NULL +db2 t3 c 0 9 0.0000 4.0000 1.0000 0 NULL NULL +select * from mysql.index_stats where db_name='db2' and table_name='t3'; +db_name table_name index_name prefix_arity avg_frequency +db2 t3 IDX1 1 5.0000 +db2 t3 IDX2 1 5.0000 +db2 t3 IDX2 2 1.6667 +use test; +drop database db1; +drop database db2; +drop table t1; set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index a2d3d392f45..bd6a0849e3d 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1622,3 +1622,22 @@ test t2 id 1 1024 0.0000 8.0000 63 SINGLE_PREC_HB 03070B0F13171B1F23272B2F33373B set histogram_size=default; drop table t1, t2; set use_stat_tables=@save_use_stat_tables; +# +# Bug MDEV-7383: min/max value for a column not utf8 compatible +# +create table t1 (a varchar(100)) engine=MyISAM; +insert into t1 values(unhex('D879626AF872675F73E662F8')); +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +show warnings; +Level Code Message +select db_name, table_name, column_name, +HEX(min_value), HEX(max_value), +nulls_ratio, avg_frequency, +hist_size, hist_type, HEX(histogram) +FROM mysql.column_stats; +db_name table_name column_name HEX(min_value) HEX(max_value) nulls_ratio avg_frequency hist_size hist_type HEX(histogram) +test t1 a D879626AF872675F73E662F8 D879626AF872675F73E662F8 0.0000 1.0000 0 NULL NULL +drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 3f0e6955b67..75c8597590a 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -7109,3 +7109,27 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index 34c766ed9b3..e6238af4cdc 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -7109,6 +7109,30 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; set optimizer_switch=default; select @@optimizer_switch like '%exists_to_in=off%'; @@optimizer_switch like '%exists_to_in=off%' diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index de21a8dbd96..70edc6463c4 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -7102,6 +7102,30 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; @@optimizer_switch like '%materialization=on%' diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 09d8328a639..c89fd132b35 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -7100,4 +7100,28 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index a164ae98aa0..b12bf216327 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -7115,6 +7115,30 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; set optimizer_switch=default; select @@optimizer_switch like '%subquery_cache=on%'; @@optimizer_switch like '%subquery_cache=on%' diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index d15a07fffa6..54f145d5c5e 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -7100,5 +7100,29 @@ sq NULL deallocate prepare stmt; drop table t1,t2,t3,t4; +# +# MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +# m_lock_type != 2' failed in handler::ha_index_read_map +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +3 +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +f2 +3 +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); +count(*) +1 +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +sq +NULL +drop view v2; +drop table t1,t2; set @optimizer_switch_for_subselect_test=null; set @join_cache_level_for_subselect_test=NULL; diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index 2fe6512eee3..bc4de8b4171 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -290,8 +290,8 @@ column_stats CREATE TABLE `column_stats` ( `db_name` varchar(64) COLLATE utf8_bin NOT NULL, `table_name` varchar(64) COLLATE utf8_bin NOT NULL, `column_name` varchar(64) COLLATE utf8_bin NOT NULL, - `min_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, - `max_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `min_value` varbinary(255) DEFAULT NULL, + `max_value` varbinary(255) DEFAULT NULL, `nulls_ratio` decimal(12,4) DEFAULT NULL, `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, diff --git a/mysql-test/r/system_mysql_db_fix40123.result b/mysql-test/r/system_mysql_db_fix40123.result index 2fe6512eee3..bc4de8b4171 100644 --- a/mysql-test/r/system_mysql_db_fix40123.result +++ b/mysql-test/r/system_mysql_db_fix40123.result @@ -290,8 +290,8 @@ column_stats CREATE TABLE `column_stats` ( `db_name` varchar(64) COLLATE utf8_bin NOT NULL, `table_name` varchar(64) COLLATE utf8_bin NOT NULL, `column_name` varchar(64) COLLATE utf8_bin NOT NULL, - `min_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, - `max_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `min_value` varbinary(255) DEFAULT NULL, + `max_value` varbinary(255) DEFAULT NULL, `nulls_ratio` decimal(12,4) DEFAULT NULL, `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, diff --git a/mysql-test/r/system_mysql_db_fix50030.result b/mysql-test/r/system_mysql_db_fix50030.result index 2fe6512eee3..bc4de8b4171 100644 --- a/mysql-test/r/system_mysql_db_fix50030.result +++ b/mysql-test/r/system_mysql_db_fix50030.result @@ -290,8 +290,8 @@ column_stats CREATE TABLE `column_stats` ( `db_name` varchar(64) COLLATE utf8_bin NOT NULL, `table_name` varchar(64) COLLATE utf8_bin NOT NULL, `column_name` varchar(64) COLLATE utf8_bin NOT NULL, - `min_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, - `max_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `min_value` varbinary(255) DEFAULT NULL, + `max_value` varbinary(255) DEFAULT NULL, `nulls_ratio` decimal(12,4) DEFAULT NULL, `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, diff --git a/mysql-test/r/system_mysql_db_fix50117.result b/mysql-test/r/system_mysql_db_fix50117.result index 2fe6512eee3..bc4de8b4171 100644 --- a/mysql-test/r/system_mysql_db_fix50117.result +++ b/mysql-test/r/system_mysql_db_fix50117.result @@ -290,8 +290,8 @@ column_stats CREATE TABLE `column_stats` ( `db_name` varchar(64) COLLATE utf8_bin NOT NULL, `table_name` varchar(64) COLLATE utf8_bin NOT NULL, `column_name` varchar(64) COLLATE utf8_bin NOT NULL, - `min_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, - `max_value` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `min_value` varbinary(255) DEFAULT NULL, + `max_value` varbinary(255) DEFAULT NULL, `nulls_ratio` decimal(12,4) DEFAULT NULL, `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index db7c2380398..a0c35c6e0ca 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -619,6 +619,65 @@ Handler_update 5 ROLLBACK; DROP TABLE t1, t2; # +# MDEV-8938: Server Crash on Update with joins +# +CREATE TABLE `t1` ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +UPDATE `t1` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `t1` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain"; +drop table t1; +CREATE TABLE `t1` ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +create table t2 ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +UPDATE t1 +SET value = (SELECT value FROM t2 WHERE `name`= t1.name) +WHERE value is null ; +drop table t1,t2; +# +#MDEV-8701: Crash on derived query +# +CREATE TABLE t1 ( +data_exit_entry_id int(11) NOT NULL, +data_entry_id int(11) NOT NULL, +data_entry_exit_id int(11) NOT NULL, +data_exit_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +data_entry_id int(11) NOT NULL, +data_entry_cost double NOT NULL, +data_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; +create algorithm=temptable view v1 as SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost +FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id; +UPDATE t2 +SET data_entry_cost += ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) +FROM +v1 AS query +WHERE data_entry_exit_id = t2.data_entry_id +) +); +UPDATE t2 +SET data_entry_cost += ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) +FROM +( SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost +FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id) AS query +WHERE data_entry_exit_id = t2.data_entry_id +) +); +drop view v1; +drop table t1, t2; +# # MDEV-4410: update does not want to use a covering index, but select uses it. # create table t2(a int); diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8a502a4a3ba..dec85fbcd4b 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5507,6 +5507,39 @@ UPDATE t1, t2 SET a = 1 WHERE a IN ( SELECT 0 FROM v3 ); EXECUTE stmt; DROP TABLE t1, t2, t3; DROP VIEW v3; +# +# MDEV-8632: Segmentation fault on INSERT +# +CREATE TABLE `t1` ( +`id` int(10) unsigned NOT NULL, +`r` float NOT NULL, +PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +create view v1 as select id, if(r=r,1,2) as d from t1; +create view v2 as +select id, +d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p +from v1; +insert into t1 (id, r) +select id,p from +( +select id, +d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p +from ( +select id, if(r=r,1,2) as d +from t1 +) a +) b +on duplicate key update r=p; +insert into t1 (id, r) +select id,p from v2 +on duplicate key update r=p; +prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p"; +execute stmt; +execute stmt; +deallocate prepare stmt; +drop view v1,v2; +drop table `t1`; # ----------------------------------------------------------------- # -- End of 5.5 tests. # ----------------------------------------------------------------- @@ -5627,6 +5660,149 @@ count(v3.i) 0 drop table t1, t2; drop view v3; +# +# MDEV-8525: mariadb 10.0.20 crashing when data is read by Kodi +# media center (http://kodi.tv). +# +CREATE TABLE `t1` ( +`idSong` int(11) NOT NULL AUTO_INCREMENT, +`idAlbum` int(11) DEFAULT NULL, +`idPath` int(11) DEFAULT NULL, +`strArtists` text, +`strGenres` text, +`strTitle` varchar(512) DEFAULT NULL, +`iTrack` int(11) DEFAULT NULL, +`iDuration` int(11) DEFAULT NULL, +`iYear` int(11) DEFAULT NULL, +`dwFileNameCRC` text, +`strFileName` text, +`strMusicBrainzTrackID` text, +`iTimesPlayed` int(11) DEFAULT NULL, +`iStartOffset` int(11) DEFAULT NULL, +`iEndOffset` int(11) DEFAULT NULL, +`idThumb` int(11) DEFAULT NULL, +`lastplayed` varchar(20) DEFAULT NULL, +`rating` char(1) DEFAULT '0', +`comment` text, +`mood` text, +PRIMARY KEY (`idSong`), +UNIQUE KEY `idxSong7` (`idAlbum`,`strMusicBrainzTrackID`(36)), +KEY `idxSong` (`strTitle`(255)), +KEY `idxSong1` (`iTimesPlayed`), +KEY `idxSong2` (`lastplayed`), +KEY `idxSong3` (`idAlbum`), +KEY `idxSong6` (`idPath`,`strFileName`(255)) +) DEFAULT CHARSET=utf8; +INSERT INTO `t1` VALUES (1,1,1,'strArtists1','strGenres1','strTitle1',1,100,2000,NULL,'strFileName1','strMusicBrainzTrackID1',0,0,0,NULL,NULL,'0','',''),(2,2,2,'strArtists2','strGenres2','strTitle2',2,200,2001,NULL,'strFileName2','strMusicBrainzTrackID2',0,0,0,NULL,NULL,'0','',''); +CREATE TABLE `t2` ( +`idAlbum` int(11) NOT NULL AUTO_INCREMENT, +`strAlbum` varchar(256) DEFAULT NULL, +`strMusicBrainzAlbumID` text, +`strArtists` text, +`strGenres` text, +`iYear` int(11) DEFAULT NULL, +`idThumb` int(11) DEFAULT NULL, +`bCompilation` int(11) NOT NULL DEFAULT '0', +`strMoods` text, +`strStyles` text, +`strThemes` text, +`strReview` text, +`strImage` text, +`strLabel` text, +`strType` text, +`iRating` int(11) DEFAULT NULL, +`lastScraped` varchar(20) DEFAULT NULL, +`dateAdded` varchar(20) DEFAULT NULL, +`strReleaseType` text, +PRIMARY KEY (`idAlbum`), +UNIQUE KEY `idxAlbum_2` (`strMusicBrainzAlbumID`(36)), +KEY `idxAlbum` (`strAlbum`(255)), +KEY `idxAlbum_1` (`bCompilation`) +) DEFAULT CHARSET=utf8; +INSERT INTO `t2` VALUES (1,'strAlbum1','strMusicBrainzAlbumID1','strArtists1','strGenres1',2000,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'album'); +CREATE TABLE `t3` ( +`idArtist` int(11) DEFAULT NULL, +`idAlbum` int(11) DEFAULT NULL, +`strJoinPhrase` text, +`boolFeatured` int(11) DEFAULT NULL, +`iOrder` int(11) DEFAULT NULL, +`strArtist` text, +UNIQUE KEY `idxAlbumArtist_1` (`idAlbum`,`idArtist`), +UNIQUE KEY `idxAlbumArtist_2` (`idArtist`,`idAlbum`), +KEY `idxAlbumArtist_3` (`boolFeatured`) +) DEFAULT CHARSET=utf8; +INSERT INTO `t3` VALUES (1,1,'',0,0,'strArtist1'); +CREATE TABLE `t4` ( +`idArtist` int(11) NOT NULL AUTO_INCREMENT, +`strArtist` varchar(256) DEFAULT NULL, +`strMusicBrainzArtistID` text, +`strBorn` text, +`strFormed` text, +`strGenres` text, +`strMoods` text, +`strStyles` text, +`strInstruments` text, +`strBiography` text, +`strDied` text, +`strDisbanded` text, +`strYearsActive` text, +`strImage` text, +`strFanart` text, +`lastScraped` varchar(20) DEFAULT NULL, +`dateAdded` varchar(20) DEFAULT NULL, +PRIMARY KEY (`idArtist`), +UNIQUE KEY `idxArtist1` (`strMusicBrainzArtistID`(36)), +KEY `idxArtist` (`strArtist`(255)) +) DEFAULT CHARSET=utf8; +INSERT INTO `t4` VALUES (1,'strArtist1','strMusicBrainzArtistID',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +CREATE VIEW `v1` AS select `t2`.`idAlbum` AS `idAlbum`,`t2`.`strAlbum` AS `strAlbum`,`t2`.`strMusicBrainzAlbumID` AS `strMusicBrainzAlbumID`,`t2`.`strArtists` AS `strArtists`,`t2`.`strGenres` AS `strGenres`,`t2`.`iYear` AS `iYear`,`t2`.`strMoods` AS `strMoods`,`t2`.`strStyles` AS `strStyles`,`t2`.`strThemes` AS `strThemes`,`t2`.`strReview` AS `strReview`,`t2`.`strLabel` AS `strLabel`,`t2`.`strType` AS `strType`,`t2`.`strImage` AS `strImage`,`t2`.`iRating` AS `iRating`,`t2`.`bCompilation` AS `bCompilation`,(select min(`t1`.`iTimesPlayed`) from `t1` where (`t1`.`idAlbum` = `t2`.`idAlbum`)) AS `iTimesPlayed`,`t2`.`strReleaseType` AS `strReleaseType` from `t2`; +CREATE VIEW `v2` AS select `t3`.`idAlbum` AS `idAlbum`,`t3`.`idArtist` AS `idArtist`,`t4`.`strArtist` AS `strArtist`,`t4`.`strMusicBrainzArtistID` AS `strMusicBrainzArtistID`,`t3`.`boolFeatured` AS `boolFeatured`,`t3`.`strJoinPhrase` AS `strJoinPhrase`,`t3`.`iOrder` AS `iOrder` from (`t3` join `t4` on((`t3`.`idArtist` = `t4`.`idArtist`))); +SELECT v1.*,v2.* FROM v1 LEFT JOIN v2 ON v1.idAlbum = v2.idAlbum WHERE v1.idAlbum = 1 ORDER BY v2.iOrder; +idAlbum strAlbum strMusicBrainzAlbumID strArtists strGenres iYear strMoods strStyles strThemes strReview strLabel strType strImage iRating bCompilation iTimesPlayed strReleaseType idAlbum idArtist strArtist strMusicBrainzArtistID boolFeatured strJoinPhrase iOrder +1 strAlbum1 strMusicBrainzAlbumID1 strArtists1 strGenres1 2000 NULL NULL NULL NULL NULL NULL NULL NULL 0 0 album 1 1 strArtist1 strMusicBrainzArtistID 0 0 +drop view v1,v2; +drop table t1,t2,t3,t4; +# +# MDEV-8913: Derived queries with same column names as final +# projection causes issues when using Order By +# +create table t1 (field int); +insert into t1 values (10),(5),(3),(8),(20); +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM ( SELECT field AS f1, 1 AS f2 FROM t1) AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +create view v1 as SELECT field AS f1, 1 AS f2 FROM t1; +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM v1 AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +drop view v1; +create table t2 SELECT field AS f1, 1 AS f2 FROM t1; +SELECT +sq.f2 AS f1, +sq.f1 AS f2 +FROM t2 AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +drop table t1, t2; +SELECT 1 FROM (SELECT 1 as a) AS b HAVING (SELECT `SOME_GARBAGE`.b.a)=1; +ERROR 42S22: Unknown column 'SOME_GARBAGE.b.a' in 'field list' # ----------------------------------------------------------------- # -- End of 10.0 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index d1685f40314..2821e1112e5 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -16,8 +16,8 @@ def mysql column_stats db_name 1 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8 def mysql column_stats histogram 11 NULL YES varbinary 255 255 NULL NULL NULL NULL NULL varbinary(255) select,insert,update,references def mysql column_stats hist_size 9 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references def mysql column_stats hist_type 10 NULL YES enum 14 42 NULL NULL NULL utf8 utf8_bin enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') select,insert,update,references -def mysql column_stats max_value 5 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_bin varchar(255) select,insert,update,references -def mysql column_stats min_value 4 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_bin varchar(255) select,insert,update,references +def mysql column_stats max_value 5 NULL YES varbinary 255 255 NULL NULL NULL NULL NULL varbinary(255) select,insert,update,references +def mysql column_stats min_value 4 NULL YES varbinary 255 255 NULL NULL NULL NULL NULL varbinary(255) select,insert,update,references def mysql column_stats nulls_ratio 6 NULL YES decimal NULL NULL 12 4 NULL NULL NULL decimal(12,4) select,insert,update,references def mysql column_stats table_name 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references def mysql db Alter_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references @@ -333,8 +333,8 @@ NULL mysql columns_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql column_stats db_name varchar 64 192 utf8 utf8_bin varchar(64) 3.0000 mysql column_stats table_name varchar 64 192 utf8 utf8_bin varchar(64) 3.0000 mysql column_stats column_name varchar 64 192 utf8 utf8_bin varchar(64) -3.0000 mysql column_stats min_value varchar 255 765 utf8 utf8_bin varchar(255) -3.0000 mysql column_stats max_value varchar 255 765 utf8 utf8_bin varchar(255) +1.0000 mysql column_stats min_value varbinary 255 255 NULL NULL varbinary(255) +1.0000 mysql column_stats max_value varbinary 255 255 NULL NULL varbinary(255) NULL mysql column_stats nulls_ratio decimal NULL NULL NULL NULL decimal(12,4) NULL mysql column_stats avg_length decimal NULL NULL NULL NULL decimal(12,4) NULL mysql column_stats avg_frequency decimal NULL NULL NULL NULL decimal(12,4) diff --git a/mysql-test/suite/innodb/r/innodb-alter-filewrite.result b/mysql-test/suite/innodb/r/innodb-alter-filewrite.result new file mode 100644 index 00000000000..444b09ad440 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-alter-filewrite.result @@ -0,0 +1,30 @@ +CREATE TABLE `test_wo_keys` ( +`f01` int AUTO_INCREMENT, +`f02` bigint, `f03` bigint, `f04` enum('a','b'), +`f05` date, `f06` int, `f07` int, `f08` double, `f09` int, +`f10` bigint, `f11` double, `f12` enum('a','b','c','d','e'), +`f13` int, `f14` int, `f15` varchar(255), `f16` int, `f17` int, `f18` int, +`f19` double, `f20` double, `f21` double, `f22` double, `f23` double, `f24` tinyint, +`f25` double, `f26` double, `f27` double, `f28` double, `f29` int unsigned, +`f30` int unsigned, `f31` bigint, `f32` int unsigned, `f33` bigint, +`f34` int unsigned, `f35` int unsigned, +PRIMARY KEY `f01` (`f01`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +show status like '%merge_buffers%'; +Variable_name Value +Innodb_os_merge_buffers_written 0 +Innodb_os_merge_buffers_read 0 +Innodb_os_merge_buffers_merged 0 +ALTER TABLE test_wo_keys +ADD KEY `f06` (`f06`), ADD KEY `f05` (`f05`), ADD KEY `f04` (`f04`), ADD KEY `f23` (`f23`), +ADD KEY `f10` (`f10`), ADD KEY `f11` (`f11`), ADD KEY `f09` (`f09`), ADD KEY `f22` (`f22`), +ADD KEY `f21` (`f21`), ADD KEY `f07` (`f07`), ADD KEY `f08` (`f08`), ADD KEY `f18` (`f18`), +ADD KEY `f19` (`f19`), ADD KEY `f20` (`f20`), ADD KEY `f29` (`f29`,`f31`,`f33`), +ADD KEY `f35` (`f35`), ADD KEY `f25` (`f25`), ADD KEY `f26` (`f26`), +ADD KEY `f27` (`f27`), ADD KEY `f28` (`f28`); +show status like '%merge_buffers%'; +Variable_name Value +Innodb_os_merge_buffers_written 0 +Innodb_os_merge_buffers_read 0 +Innodb_os_merge_buffers_merged 0 +DROP TABLE test_wo_keys; diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index a022f07936c..eddedfc3620 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -25,7 +25,7 @@ create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=i ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(a)) engine=innodb. +Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(a)) engine=innodb'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; @@ -42,7 +42,7 @@ alter table t2 add constraint b foreign key (b) references t2(b); ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key (b) references t2(b). +Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'. Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t2, t1; @@ -51,7 +51,7 @@ alter table t1 add constraint c1 foreign key (f1) references t11(f1); ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary close to foreign key (f1) references t11(f1). +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary near ' foreign key (f1) references t11(f1)'. Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; @@ -90,14 +90,14 @@ alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update se ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column f1 is defined as NOT NULL in foreign key (f1) references t1(f1) on update set null close to on update set null. +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column 'f1' is defined as NOT NULL in ' foreign key (f1) references t1(f1) on update set null' near ' on update set null'. Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb; ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column a is defined as NOT NULL in foreign key(a) references t1(f1) on delete set null) engine=innodb close to on delete set null) engine=innodb. +Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column 'a' is defined as NOT NULL in 'foreign key(a) references t1(f1) on delete set null) engine=innodb' near ' on delete set null) engine=innodb'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; @@ -106,7 +106,7 @@ create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=inn ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column a does not mach referenced column f1 close to foreign key(a) references t1(f1)) engine=innodb +Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column 'a' does not mach referenced column 'f1' near 'foreign key(a) references t1(f1)) engine=innodb'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result index dee20d282f7..c916d665bf0 100644 --- a/mysql-test/suite/innodb/r/innodb-fk.result +++ b/mysql-test/suite/innodb/r/innodb-fk.result @@ -50,8 +50,8 @@ CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE -) ENGINE=InnoDB. +Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE +) ENGINE=InnoDB'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint CREATE TABLE t2 ( @@ -65,7 +65,7 @@ ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE. +Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE'. Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t2; diff --git a/mysql-test/suite/innodb/r/innodb_monitor.result b/mysql-test/suite/innodb/r/innodb_monitor.result index 8c580348e1a..31c6123c964 100644 --- a/mysql-test/suite/innodb/r/innodb_monitor.result +++ b/mysql-test/suite/innodb/r/innodb_monitor.result @@ -130,6 +130,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs disabled os_log_pending_writes disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled trx_rw_commits disabled trx_ro_commits disabled trx_nl_ro_commits disabled @@ -278,6 +281,9 @@ lock_row_lock_time disabled lock_row_lock_time_max disabled lock_row_lock_waits disabled lock_row_lock_time_avg disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled innodb_rwlock_s_spin_waits disabled innodb_rwlock_x_spin_waits disabled innodb_rwlock_s_spin_rounds disabled @@ -316,6 +322,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs enabled os_log_pending_writes enabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled set global innodb_monitor_enable=""; ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '' set global innodb_monitor_enable="_"; diff --git a/mysql-test/suite/innodb/r/snapshot.result b/mysql-test/suite/innodb/r/snapshot.result new file mode 100644 index 00000000000..dcb3d242fc2 --- /dev/null +++ b/mysql-test/suite/innodb/r/snapshot.result @@ -0,0 +1,8 @@ +START TRANSACTION WITH CONSISTENT SNAPSHOT; +CREATE TABLE IF NOT EXISTS t1 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=InnoDB; +UPDATE t1 SET i = 0; +ERROR HY000: Table definition has changed, please retry transaction +UPDATE t1 SET pk = 0; +ERROR HY000: Table definition has changed, please retry transaction +commit; +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-alter-filewrite.test b/mysql-test/suite/innodb/t/innodb-alter-filewrite.test new file mode 100644 index 00000000000..d0372056937 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-alter-filewrite.test @@ -0,0 +1,32 @@ +--source include/have_innodb.inc + +# +# MDEV-8696: Adding indexes on empty table is slow with large innodb_sort_buffer_size. +# + +CREATE TABLE `test_wo_keys` ( +`f01` int AUTO_INCREMENT, +`f02` bigint, `f03` bigint, `f04` enum('a','b'), +`f05` date, `f06` int, `f07` int, `f08` double, `f09` int, +`f10` bigint, `f11` double, `f12` enum('a','b','c','d','e'), +`f13` int, `f14` int, `f15` varchar(255), `f16` int, `f17` int, `f18` int, +`f19` double, `f20` double, `f21` double, `f22` double, `f23` double, `f24` tinyint, +`f25` double, `f26` double, `f27` double, `f28` double, `f29` int unsigned, +`f30` int unsigned, `f31` bigint, `f32` int unsigned, `f33` bigint, +`f34` int unsigned, `f35` int unsigned, +PRIMARY KEY `f01` (`f01`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +show status like '%merge_buffers%'; + +ALTER TABLE test_wo_keys +ADD KEY `f06` (`f06`), ADD KEY `f05` (`f05`), ADD KEY `f04` (`f04`), ADD KEY `f23` (`f23`), +ADD KEY `f10` (`f10`), ADD KEY `f11` (`f11`), ADD KEY `f09` (`f09`), ADD KEY `f22` (`f22`), +ADD KEY `f21` (`f21`), ADD KEY `f07` (`f07`), ADD KEY `f08` (`f08`), ADD KEY `f18` (`f18`), +ADD KEY `f19` (`f19`), ADD KEY `f20` (`f20`), ADD KEY `f29` (`f29`,`f31`,`f33`), +ADD KEY `f35` (`f35`), ADD KEY `f25` (`f25`), ADD KEY `f26` (`f26`), +ADD KEY `f27` (`f27`), ADD KEY `f28` (`f28`); + +show status like '%merge_buffers%'; + +DROP TABLE test_wo_keys; diff --git a/mysql-test/suite/innodb/t/snapshot.test b/mysql-test/suite/innodb/t/snapshot.test new file mode 100644 index 00000000000..8e3dc76fe54 --- /dev/null +++ b/mysql-test/suite/innodb/t/snapshot.test @@ -0,0 +1,18 @@ + +--source include/have_log_bin.inc +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc + +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connect (con1,localhost,root,,test) +CREATE TABLE IF NOT EXISTS t1 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=InnoDB; + +--connection default +--error 1412 +UPDATE t1 SET i = 0; +--error 1412 +UPDATE t1 SET pk = 0; +commit; + +drop table t1; diff --git a/mysql-test/suite/parts/r/partition_debug.result b/mysql-test/suite/parts/r/partition_debug.result index 3f0f2def790..109072be49c 100644 --- a/mysql-test/suite/parts/r/partition_debug.result +++ b/mysql-test/suite/parts/r/partition_debug.result @@ -1,5 +1,21 @@ DROP TABLE IF EXISTS t1; # +# Bug#13737949: CRASH IN HA_PARTITION::INDEX_INIT +# Bug#18694052: SERVER CRASH IN HA_PARTITION::INIT_RECORD_PRIORITY_QUEUE +# +CREATE TABLE t1 (a INT, b VARCHAR(64), KEY(b,a)) +PARTITION BY HASH (a) PARTITIONS 3; +INSERT INTO t1 VALUES (1, "1"), (2, "2"), (3, "3"), (4, "Four"), (5, "Five"), +(6, "Six"), (7, "Seven"), (8, "Eight"), (9, "Nine"); +SET SESSION debug_dbug="+d,ha_partition_fail_index_init"; +SELECT * FROM t1 WHERE b = "Seven"; +ERROR HY000: Table has no partition for value 0 +SET SESSION debug_dbug="-d,ha_partition_fail_index_init"; +SELECT * FROM t1 WHERE b = "Seven"; +a b +7 Seven +DROP TABLE t1; +# # WL#4445: EXCHANGE PARTITION WITH TABLE # Verify ddl_log in case of crashing. call mtr.add_suppression("Attempting backtrace. You can use the following information to find out"); diff --git a/mysql-test/suite/parts/t/partition_debug.test b/mysql-test/suite/parts/t/partition_debug.test index aa943e5fbe1..11b66e4afd8 100644 --- a/mysql-test/suite/parts/t/partition_debug.test +++ b/mysql-test/suite/parts/t/partition_debug.test @@ -12,6 +12,24 @@ DROP TABLE IF EXISTS t1; --enable_warnings +# Partitioning test that require debug features + +--echo # +--echo # Bug#13737949: CRASH IN HA_PARTITION::INDEX_INIT +--echo # Bug#18694052: SERVER CRASH IN HA_PARTITION::INIT_RECORD_PRIORITY_QUEUE +--echo # +CREATE TABLE t1 (a INT, b VARCHAR(64), KEY(b,a)) + PARTITION BY HASH (a) PARTITIONS 3; + INSERT INTO t1 VALUES (1, "1"), (2, "2"), (3, "3"), (4, "Four"), (5, "Five"), + (6, "Six"), (7, "Seven"), (8, "Eight"), (9, "Nine"); +SET SESSION debug_dbug="+d,ha_partition_fail_index_init"; +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +SELECT * FROM t1 WHERE b = "Seven"; +SET SESSION debug_dbug="-d,ha_partition_fail_index_init"; +SELECT * FROM t1 WHERE b = "Seven"; +DROP TABLE t1; + + --let $DATADIR= `SELECT @@datadir;` --echo # diff --git a/mysql-test/suite/perfschema/include/have_timer_cycle.inc b/mysql-test/suite/perfschema/include/have_timer_cycle.inc new file mode 100644 index 00000000000..b801ea256d6 --- /dev/null +++ b/mysql-test/suite/perfschema/include/have_timer_cycle.inc @@ -0,0 +1,4 @@ +if (!`SELECT count(*) FROM performance_schema.performance_timers WHERE timer_name='CYCLE' AND timer_frequency IS NOT NULL`) +{ + Skip Need performance timer CYCLE; +} diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result index f46c094b5ac..1f806d94991 100644 --- a/mysql-test/suite/perfschema/r/privilege.result +++ b/mysql-test/suite/perfschema/r/privilege.result @@ -557,7 +557,7 @@ ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'eve # # Grant access to change tables with the root account GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4; -GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4; +GRANT UPDATE, SELECT ON performance_schema.setup_timers TO pfs_user_4; GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4; GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4; GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4; @@ -568,7 +568,7 @@ UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; UPDATE performance_schema.setup_consumers SET enabled = 'YES'; -UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; +UPDATE performance_schema.setup_timers SET timer_name = 'TICK' WHERE name <> "wait"; TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; TRUNCATE TABLE performance_schema.events_waits_current; @@ -579,6 +579,5 @@ flush privileges; UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; UPDATE performance_schema.setup_consumers SET enabled = 'YES'; UPDATE performance_schema.setup_timers SET timer_name = 'MICROSECOND' where name="idle"; -UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE' where name="wait"; UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="stage"; UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="statement"; diff --git a/mysql-test/suite/perfschema/t/dml_performance_timers.test b/mysql-test/suite/perfschema/t/dml_performance_timers.test index 2ec37fbe7e9..587c54144aa 100644 --- a/mysql-test/suite/perfschema/t/dml_performance_timers.test +++ b/mysql-test/suite/perfschema/t/dml_performance_timers.test @@ -2,6 +2,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/have_timer_cycle.inc --replace_column 2 <frequency> 3 <resolution> 4 <overhead> select * from performance_schema.performance_timers; diff --git a/mysql-test/suite/perfschema/t/dml_setup_timers.test b/mysql-test/suite/perfschema/t/dml_setup_timers.test index 641ac90b1c5..bd8822d2b19 100644 --- a/mysql-test/suite/perfschema/t/dml_setup_timers.test +++ b/mysql-test/suite/perfschema/t/dml_setup_timers.test @@ -2,6 +2,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/have_timer_cycle.inc # Set to a known state update performance_schema.setup_timers diff --git a/mysql-test/suite/perfschema/t/privilege.test b/mysql-test/suite/perfschema/t/privilege.test index f5bd5cc4036..0e51d161934 100644 --- a/mysql-test/suite/perfschema/t/privilege.test +++ b/mysql-test/suite/perfschema/t/privilege.test @@ -294,7 +294,7 @@ TRUNCATE TABLE performance_schema.events_waits_current; --echo # Grant access to change tables with the root account GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4; -GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4; +GRANT UPDATE, SELECT ON performance_schema.setup_timers TO pfs_user_4; GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4; GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4; GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4; @@ -311,7 +311,11 @@ WHERE name LIKE 'wait/synch/mutex/%' UPDATE performance_schema.setup_consumers SET enabled = 'YES'; -UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; +# We do not touch "wait", to avoid restoring it at the end of the test, +# as its default value initialized at server startup is ambiguous: +# it can be CYCLE or NANOSECOND depending on platform + +UPDATE performance_schema.setup_timers SET timer_name = 'TICK' WHERE name <> "wait"; TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; @@ -327,7 +331,8 @@ flush privileges; UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +# Restore the default values for the timers that we changed. +# Note, we did not touch "wait", see above. UPDATE performance_schema.setup_timers SET timer_name = 'MICROSECOND' where name="idle"; -UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE' where name="wait"; UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="stage"; UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="statement"; diff --git a/mysql-test/suite/plugins/r/feedback_plugin_install.result b/mysql-test/suite/plugins/r/feedback_plugin_install.result index 37d26b48501..c52fdb8f85b 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_install.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_install.result @@ -3,7 +3,8 @@ select plugin_status from information_schema.plugins where plugin_name='feedback plugin_status ACTIVE select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid'; + and variable_name not like '%_uid' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK used 1 FEEDBACK version 1.1 diff --git a/mysql-test/suite/plugins/r/feedback_plugin_load.result b/mysql-test/suite/plugins/r/feedback_plugin_load.result index 9fd488052e4..8770ce19f49 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_load.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_load.result @@ -6,7 +6,8 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher variable_value = @feedback_used + 1 1 select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK version 1.1 FEEDBACK_HTTP_PROXY diff --git a/mysql-test/suite/plugins/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result index df55c3fdedb..935ea11d67b 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -6,7 +6,8 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher variable_value = @feedback_used + 1 1 select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK version 1.1 FEEDBACK_HTTP_PROXY @@ -23,7 +24,6 @@ VARIABLE_VALUE>0 VARIABLE_NAME 1 Collation used latin1_swedish_ci 1 Collation used utf8_bin 1 Collation used utf8_general_ci -feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -feedback plugin: server replied 'ok' -feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -feedback plugin: server replied 'ok' +set global sql_mode=ONLY_FULL_GROUP_BY; +6: feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent +6: feedback plugin: server replied 'ok' diff --git a/mysql-test/suite/plugins/t/feedback_plugin_install.test b/mysql-test/suite/plugins/t/feedback_plugin_install.test index 81343c436c3..559dcebfc05 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_install.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_install.test @@ -10,6 +10,8 @@ select plugin_status from information_schema.plugins where plugin_name='feedback --replace_result https http --sorted_result select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid'; + and variable_name not like '%_uid' + and variable_name not like '%debug%'; + uninstall plugin feedback; diff --git a/mysql-test/suite/plugins/t/feedback_plugin_load.test b/mysql-test/suite/plugins/t/feedback_plugin_load.test index f2f8c1f97a7..8b4aee28362 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_load.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_load.test @@ -24,7 +24,8 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher --replace_result https http --sorted_result select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; # Embedded server does not use the table mysqld.user and thus # does not automatically use latin1_bin on startup. Use it manually. diff --git a/mysql-test/suite/plugins/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index 31542c33482..b28f9d4cb38 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -13,7 +13,11 @@ if (!$MTR_FEEDBACK_PLUGIN) { # Let's wait, and hope that mtr is started with --parallel and # is doing some work in other workers. # -sleep 310; + +sleep 100; +set global sql_mode=ONLY_FULL_GROUP_BY; +sleep 210; + # The test expects that the plugin will send a report at least 2 times, # now (5 min after loading) and on server shutdown which happens below. @@ -25,20 +29,15 @@ sleep 310; --let $shutdown_timeout= 60 source include/restart_mysqld.inc; -replace_result https http; +replace_result https http 2 6; perl; $log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err'; open(LOG, '<', $log_error) or die "open(< $log_error): $!"; - # Get the first few rows (as there may be different number rows in the log) - $i= 0; - while ($_=<LOG>) - { - if (/feedback plugin:.*/) - { - print "$&\n"; - break if ($i++ >= 3); - } + %logg=(); + while ($_=<LOG>) { + $logg{$&}++ if /feedback plugin:.*/; } + print "$logg{$_}: $_\n" for sort keys %logg; close LOG; EOF diff --git a/mysql-test/suite/roles/create_and_drop_role.result b/mysql-test/suite/roles/create_and_drop_role.result index 79c6f412111..d565b888c5f 100644 --- a/mysql-test/suite/roles/create_and_drop_role.result +++ b/mysql-test/suite/roles/create_and_drop_role.result @@ -36,6 +36,10 @@ select user, host, is_role from user where user like 'test%'; user host is_role create role ''; ERROR OP000: Invalid role specification ``. +create role ' '; +ERROR OP000: Invalid role specification ``. +create role 'foo '; +drop role foo; create role r1; drop user r1; ERROR HY000: Operation DROP USER failed for 'r1'@'%' diff --git a/mysql-test/suite/roles/create_and_drop_role.test b/mysql-test/suite/roles/create_and_drop_role.test index 0bf5b744e6b..71d6de7053f 100644 --- a/mysql-test/suite/roles/create_and_drop_role.test +++ b/mysql-test/suite/roles/create_and_drop_role.test @@ -53,6 +53,14 @@ connection default; create role ''; # +# MDEV-8609 Server crashes in is_invalid_role_name on reloading ACL with a blank role name +# +--error ER_INVALID_ROLE +create role ' '; +create role 'foo '; +drop role foo; + +# # MDEV-5523 Server crashes on DROP USER <rolename> # create role r1; diff --git a/mysql-test/suite/roles/ip-6401.test b/mysql-test/suite/roles/ip-6401.test index 34d8553afa3..b7d4b168b75 100644 --- a/mysql-test/suite/roles/ip-6401.test +++ b/mysql-test/suite/roles/ip-6401.test @@ -1,3 +1,6 @@ +# +# MDEV-6401 SET ROLE returning ERROR 1959 Invalid role specification for valid role +# --source include/not_embedded.inc create role r1; create user foo@'127.0.0.1'; diff --git a/mysql-test/suite/roles/rebuild_role_grants.result b/mysql-test/suite/roles/rebuild_role_grants.result index 2817c046ae9..bc68d8ddc9f 100644 --- a/mysql-test/suite/roles/rebuild_role_grants.result +++ b/mysql-test/suite/roles/rebuild_role_grants.result @@ -56,3 +56,9 @@ Host User Role Admin_option localhost root r1 Y drop role r1; drop user u2; +create user foo@localhost; +grant create user on *.* to foo@localhost; +create role look, isp, xxx, ppp; +rename user current_user to nnnn@'%'; +drop role look, isp, xxx, ppp; +drop user nnnn@'%'; diff --git a/mysql-test/suite/roles/rebuild_role_grants.test b/mysql-test/suite/roles/rebuild_role_grants.test index 3ec3577317a..84dbdf78fb8 100644 --- a/mysql-test/suite/roles/rebuild_role_grants.test +++ b/mysql-test/suite/roles/rebuild_role_grants.test @@ -54,3 +54,16 @@ select * from mysql.roles_mapping; drop role r1; drop user u2; + +# +# MDEV-8614 Assertion `status == 0' failed in add_role_user_mapping_action on RENAME USER +# +create user foo@localhost; +grant create user on *.* to foo@localhost; +--connect (con1, localhost, foo,,) +create role look, isp, xxx, ppp; +rename user current_user to nnnn@'%'; +drop role look, isp, xxx, ppp; +connection default; +disconnect con1; +drop user nnnn@'%'; diff --git a/mysql-test/suite/rpl/r/rpl_parallel2.result b/mysql-test/suite/rpl/r/rpl_parallel2.result index 2ca73738d84..f79661ee6fb 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel2.result +++ b/mysql-test/suite/rpl/r/rpl_parallel2.result @@ -88,6 +88,12 @@ a b 18 0 19 0 UNLOCK TABLES; +SELECT "after UNLOCK TABLES" as state; +state +after UNLOCK TABLES +SELECT "after reap of STOP SLAVE" as state; +state +after reap of STOP SLAVE include/wait_for_slave_to_stop.inc include/start_slave.inc SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/suite/rpl/t/rpl_parallel2.test b/mysql-test/suite/rpl/t/rpl_parallel2.test index 50617c63024..3a9c801175f 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel2.test +++ b/mysql-test/suite/rpl/t/rpl_parallel2.test @@ -162,9 +162,13 @@ SELECT * FROM t2 ORDER BY a; --connection s2 UNLOCK TABLES; +SELECT "after UNLOCK TABLES" as state; + --connection s1 reap; +SELECT "after reap of STOP SLAVE" as state; + --connection server_2 --source include/wait_for_slave_to_stop.inc --source include/start_slave.inc diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result index 6c7051dc3d0..d3d36b2d40e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result @@ -130,6 +130,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs disabled os_log_pending_writes disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled trx_rw_commits disabled trx_ro_commits disabled trx_nl_ro_commits disabled @@ -278,6 +281,9 @@ lock_row_lock_time disabled lock_row_lock_time_max disabled lock_row_lock_waits disabled lock_row_lock_time_avg disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled innodb_rwlock_s_spin_waits disabled innodb_rwlock_x_spin_waits disabled innodb_rwlock_s_spin_rounds disabled @@ -316,6 +322,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs enabled os_log_pending_writes enabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled set global innodb_monitor_enable=""; ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '' set global innodb_monitor_enable="_"; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result index 6c7051dc3d0..d3d36b2d40e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result @@ -130,6 +130,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs disabled os_log_pending_writes disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled trx_rw_commits disabled trx_ro_commits disabled trx_nl_ro_commits disabled @@ -278,6 +281,9 @@ lock_row_lock_time disabled lock_row_lock_time_max disabled lock_row_lock_waits disabled lock_row_lock_time_avg disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled innodb_rwlock_s_spin_waits disabled innodb_rwlock_x_spin_waits disabled innodb_rwlock_s_spin_rounds disabled @@ -316,6 +322,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs enabled os_log_pending_writes enabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled set global innodb_monitor_enable=""; ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '' set global innodb_monitor_enable="_"; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result index 6c7051dc3d0..d3d36b2d40e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result @@ -130,6 +130,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs disabled os_log_pending_writes disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled trx_rw_commits disabled trx_ro_commits disabled trx_nl_ro_commits disabled @@ -278,6 +281,9 @@ lock_row_lock_time disabled lock_row_lock_time_max disabled lock_row_lock_waits disabled lock_row_lock_time_avg disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled innodb_rwlock_s_spin_waits disabled innodb_rwlock_x_spin_waits disabled innodb_rwlock_s_spin_rounds disabled @@ -316,6 +322,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs enabled os_log_pending_writes enabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled set global innodb_monitor_enable=""; ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '' set global innodb_monitor_enable="_"; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result index 6c7051dc3d0..d3d36b2d40e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result @@ -130,6 +130,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs disabled os_log_pending_writes disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled trx_rw_commits disabled trx_ro_commits disabled trx_nl_ro_commits disabled @@ -278,6 +281,9 @@ lock_row_lock_time disabled lock_row_lock_time_max disabled lock_row_lock_waits disabled lock_row_lock_time_avg disabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled innodb_rwlock_s_spin_waits disabled innodb_rwlock_x_spin_waits disabled innodb_rwlock_s_spin_rounds disabled @@ -316,6 +322,9 @@ os_log_bytes_written disabled os_log_fsyncs disabled os_log_pending_fsyncs enabled os_log_pending_writes enabled +os_merge_blocks_written disabled +os_merge_blocks_read disabled +os_merge_blocks_merged disabled set global innodb_monitor_enable=""; ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '' set global innodb_monitor_enable="_"; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index bce7f3f95bb..df4958bd2bc 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1700,6 +1700,18 @@ alter table t1 add unique index if not exists idx(i); show create table t1; DROP TABLE t1; +# +# MDEV-8358 ADD PRIMARY KEY IF NOT EXISTS -> ERROR 1068 (42000): Multiple primary key +# + +CREATE TABLE t1 ( + `event_id` bigint(20) unsigned NOT NULL DEFAULT '0', + `market_id` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`event_id`,`market_id`) + ); +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS event_id (event_id,market_id); +DROP TABLE t1; + --echo # --echo # MDEV-7374 : Losing connection to MySQL while running ALTER TABLE --echo # @@ -1722,6 +1734,3 @@ ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2'; SHOW CREATE TABLE t1; DROP TABLE t1; ---echo # ---echo # Start of 10.1 tests ---echo # diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 86dcee8148a..ac55fec3e2b 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -872,5 +872,17 @@ set impressions = column_add(impressions, drop table t1; --echo # +--echo # MDEV-8565: COLUMN_CHECK fails on valid data +--echo # + +SELECT COLUMN_CHECK(COLUMN_CREATE('a',0,'b','1')); + +SELECT COLUMN_CHECK(COLUMN_CREATE('a',1,'b','1')); + +SELECT COLUMN_JSON(COLUMN_CREATE('a',0,'b','1')); + +SELECT COLUMN_JSON(COLUMN_CREATE('a',1,'b','1')); + +--echo # --echo # end of 10.0 tests --echo # diff --git a/mysql-test/t/events_restart.test b/mysql-test/t/events_restart.test index c6152e5d961..7f01859e059 100644 --- a/mysql-test/t/events_restart.test +++ b/mysql-test/t/events_restart.test @@ -71,9 +71,9 @@ drop event intact_check_1; drop event intact_check_2; --error ER_EVENTS_DB_ERROR drop event intact_check; ---error ER_EVENTS_DB_ERROR +--error ER_STARTUP set global event_scheduler=on; ---error ER_EVENTS_DB_ERROR +--error ER_STARTUP set global event_scheduler=off; show variables like 'event_scheduler'; --echo Make sure that we still can create and drop databases, @@ -84,6 +84,16 @@ drop database mysqltest_db1; --echo Restore the original mysql.event table drop table mysql.event; rename table event_like to mysql.event; + +--echo check that we can now enable events without restart +set global event_scheduler=original; +select @@global.event_scheduler; +set global event_scheduler=on; +select @@global.event_scheduler; +--sorted_result +--replace_column 6 # 9 # 10 # +show events; + --echo Now let's restart the server again --source include/restart_mysqld.inc diff --git a/mysql-test/t/init_file_set_password-7656.test b/mysql-test/t/init_file_set_password-7656.test new file mode 100644 index 00000000000..ecee3924355 --- /dev/null +++ b/mysql-test/t/init_file_set_password-7656.test @@ -0,0 +1,26 @@ +# +# MDEV-7656 init_file option does not allow changing passwords +# +--source include/not_embedded.inc + +create user foo@localhost; + +select user,host,password from mysql.user where user='foo'; + +--write_file $MYSQLTEST_VARDIR/init.file +grant all on *.* to foo@localhost identified by 'test'; +EOF + +--enable_reconnect + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--shutdown_server 10 +--source include/wait_until_disconnected.inc + +--exec echo "restart:--init-file=$MYSQLTEST_VARDIR/init.file " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--source include/wait_until_connected_again.inc +select user,host,password from mysql.user where user='foo'; + +drop user foo@localhost; diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test index cb5cd711c7f..b8a9795db9a 100644 --- a/mysql-test/t/lowercase_fs_off.test +++ b/mysql-test/t/lowercase_fs_off.test @@ -105,4 +105,12 @@ RENAME TABLE t1 TO T1; ALTER TABLE T1 RENAME t1; DROP TABLE t1; +# +# MDEV-9014 SHOW TRIGGERS not case sensitive +# +create table t1 (a int); +create trigger t1_bi before insert on t1 for each row set new.a= 1; +show triggers like '%T1%'; +drop table t1; + set GLOBAL sql_mode=default; diff --git a/mysql-test/t/mysql_upgrade-6984.test b/mysql-test/t/mysql_upgrade-6984.test index 6f10d3f33e9..9bbfbeb3f87 100644 --- a/mysql-test/t/mysql_upgrade-6984.test +++ b/mysql-test/t/mysql_upgrade-6984.test @@ -19,4 +19,5 @@ connect(con1,localhost,root,foo,,,); update mysql.user set password='' where user='root'; flush privileges; - +# Load event table +set global event_scheduler=OFF; diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index b982ab8d2e8..d7f683aa9e9 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -858,3 +858,45 @@ INSERT INTO t3 SELECT * FROM t2 WHERE f3 = 'm' AND f2 ='c'; DROP TABLE t1,t2,t3; set global default_storage_engine=default; + +--echo # +--echo # Bug#13737949: CRASH IN HA_PARTITION::INDEX_INIT +--echo # Bug#18694052: SERVER CRASH IN HA_PARTITION::INIT_RECORD_PRIORITY_QUEUE +--echo # +CREATE TABLE t1 +(a INT, + b INT, + PRIMARY KEY (a)) + ENGINE = InnoDB + PARTITION BY HASH (a) PARTITIONS 3; + START TRANSACTION WITH CONSISTENT SNAPSHOT; + --connect (con1, localhost, root,,) + --echo # con1 + ALTER TABLE t1 ADD INDEX idx1 (b); + --connection default + --echo # con default + --error ER_TABLE_DEF_CHANGED + SELECT b FROM t1 WHERE b = 0; + --error ER_TABLE_DEF_CHANGED + SELECT b FROM t1 WHERE b = 0; + --disconnect con1 + DROP TABLE t1; + +--echo # Same test without partitioning +CREATE TABLE t1 +(a INT, + b INT, + PRIMARY KEY (a)) + ENGINE = InnoDB; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +--echo # con1 +--connect (con1, localhost, root,,) +ALTER TABLE t1 ADD INDEX idx1 (b); +--connection default +--echo # con default +--error ER_TABLE_DEF_CHANGED +SELECT b FROM t1 WHERE b = 0; +--error ER_TABLE_DEF_CHANGED +SELECT b FROM t1 WHERE b = 0; +--disconnect con1 +DROP TABLE t1; diff --git a/mysql-test/t/partition_myisam.test b/mysql-test/t/partition_myisam.test index bce0c6f009c..d07637057e0 100644 --- a/mysql-test/t/partition_myisam.test +++ b/mysql-test/t/partition_myisam.test @@ -123,6 +123,7 @@ CHECK TABLE t1; SELECT * FROM t1; --echo # Note that it is currently impossible to drop a partitioned table --echo # without the .par file +--replace_result "Not owner" "Operation not permitted" --error ER_GET_ERRNO DROP TABLE t1; --remove_file $MYSQLD_DATADIR/test/t1.frm diff --git a/mysql-test/t/partition_not_blackhole.test b/mysql-test/t/partition_not_blackhole.test index 64d4f3877c8..d9e653b5252 100644 --- a/mysql-test/t/partition_not_blackhole.test +++ b/mysql-test/t/partition_not_blackhole.test @@ -19,6 +19,9 @@ SHOW TABLES; --replace_result $MYSQLD_DATADIR ./ --error ER_FAILED_READ_FROM_PAR_FILE SHOW CREATE TABLE t1; + +# The replace is needed for Solaris +--replace_result "Not owner" "Operation not permitted" --error ER_GET_ERRNO DROP TABLE t1; --list_files $MYSQLD_DATADIR/test t1* diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 96dd88f5eb6..3881d522bbf 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3650,3 +3650,25 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; drop table t1; --echo # End of 5.3 tests + +--echo # +--echo # MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +--echo # + +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; + +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; + + +--echo # End of 10.0 tests diff --git a/mysql-test/t/ps_change_master.test b/mysql-test/t/ps_change_master.test new file mode 100644 index 00000000000..d756b8cd4fb --- /dev/null +++ b/mysql-test/t/ps_change_master.test @@ -0,0 +1,45 @@ +--source include/not_embedded.inc +--source include/have_log_bin.inc + +--echo # +--echo # CHANGE MASTER TO doesn't work with prepared statements +--echo # + +CHANGE MASTER TO MASTER_HOST='host1', MASTER_USER='user1'; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + +SET @s := "CHANGE MASTER TO MASTER_HOST='host2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + +SET @s := "CHANGE MASTER TO MASTER_USER='user2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +# Multiple executions should not hurt. +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + + +# Reset +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; + +--echo # End of test diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test index 2dc64254a9a..5f79404e7e4 100644 --- a/mysql-test/t/skip_grants.test +++ b/mysql-test/t/skip_grants.test @@ -112,8 +112,8 @@ DROP FUNCTION f3; # # Bug #26807 "set global event_scheduler=1" and --skip-grant-tables crashes server # ---error ER_OPTION_PREVENTS_STATEMENT set global event_scheduler=1; +set global event_scheduler=0; # # Bug#26285 Selecting information_schema crahes server diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 25ca322ca0a..4cbaa9e27c8 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -232,4 +232,77 @@ SELECT * FROM t1 STRAIGHT_JOIN t2 WHERE name IN ( 'AUS','YEM' ) AND id = 1; DROP TABLE t1,t2; +--echo # +--echo # MDEV-7370: Server deadlocks on renaming a table for which persistent statistics exists +--echo # + +--disable_warnings +drop database if exists db1; +drop database if exists db1; +--enable_warnings + +create database db1; +create database db2; +use db1; +--echo # +--echo # First, run the original testcase: +--echo # +create table t1 (i int); +insert into t1 values (10),(20); +analyze table t1 persistent for all; +rename table t1 to db2.t1; + +--echo # Verify that stats in the old database are gone: +select * from mysql.column_stats where db_name='db1' and table_name='t1'; +select * from mysql.table_stats where db_name='db1' and table_name='t1'; + +--echo # Verify that stats are present in the new database: +select * from mysql.column_stats where db_name='db2' and table_name='t1'; +select * from mysql.table_stats where db_name='db2' and table_name='t1'; + + +--echo # +--echo # Now, try with more than one column and with indexes: +--echo # +use test; +create table t1(a int primary key); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + + +use db1; +create table t2 (a int, b int, c int, key IDX1(a), key IDX2(a,b)); +insert into t2 select a/10, a/2, a from test.t1; +analyze table t2 persistent for all; + +alter table t2 rename db2.t2; + +--echo # Verify that stats in the old database are gone: +select * from mysql.table_stats where db_name='db1' and table_name='t2'; +select * from mysql.column_stats where db_name='db1' and table_name='t2'; +select * from mysql.index_stats where db_name='db1' and table_name='t2'; + +--echo # Verify that stats are present in the new database: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +select * from mysql.index_stats where db_name='db2' and table_name='t2'; + +use db2; +--echo # +--echo # Now, rename within the same database and verify: +--echo # +rename table t2 to t3; +--echo # No stats under old name: +select * from mysql.table_stats where db_name='db2' and table_name='t2'; +select * from mysql.column_stats where db_name='db2' and table_name='t2'; +select * from mysql.index_stats where db_name='db2' and table_name='t2'; +--echo # Stats under the new name: +select * from mysql.table_stats where db_name='db2' and table_name='t3'; +select * from mysql.column_stats where db_name='db2' and table_name='t3'; +select * from mysql.index_stats where db_name='db2' and table_name='t3'; + +use test; +drop database db1; +drop database db2; +drop table t1; + set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index 36e2c5a77bd..2c8dec307cc 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -701,3 +701,19 @@ drop table t1, t2; set use_stat_tables=@save_use_stat_tables; +--echo # +--echo # Bug MDEV-7383: min/max value for a column not utf8 compatible +--echo # + +create table t1 (a varchar(100)) engine=MyISAM; +insert into t1 values(unhex('D879626AF872675F73E662F8')); +analyze table t1 persistent for all; +show warnings; + +select db_name, table_name, column_name, + HEX(min_value), HEX(max_value), + nulls_ratio, avg_frequency, + hist_size, hist_type, HEX(histogram) + FROM mysql.column_stats; + +drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 0a542ac9888..a862870e9ff 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5966,3 +5966,26 @@ EXECUTE stmt; deallocate prepare stmt; drop table t1,t2,t3,t4; + +--echo # +--echo # MDEV-7930: Assertion `table_share->tmp_table != NO_TMP_TABLE || +--echo # m_lock_type != 2' failed in handler::ha_index_read_map +--echo # + +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (f2 INT, KEY(f2)); +INSERT INTO t2 VALUES (3); + +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2; + +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; +SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0; +SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 ); + +delete from t1; +SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq; + +drop view v2; +drop table t1,t2; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 05f9ce39bec..e5ef0b11127 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -560,6 +560,79 @@ ROLLBACK; DROP TABLE t1, t2; --echo # +--echo # MDEV-8938: Server Crash on Update with joins +--echo # + +CREATE TABLE `t1` ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +UPDATE `t1` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `t1` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain"; + +drop table t1; + +CREATE TABLE `t1` ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +create table t2 ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +UPDATE t1 +SET value = (SELECT value FROM t2 WHERE `name`= t1.name) +WHERE value is null ; + +drop table t1,t2; + +--echo # +--echo #MDEV-8701: Crash on derived query +--echo # + +CREATE TABLE t1 ( + data_exit_entry_id int(11) NOT NULL, + data_entry_id int(11) NOT NULL, + data_entry_exit_id int(11) NOT NULL, + data_exit_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; + +CREATE TABLE t2 ( + data_entry_id int(11) NOT NULL, + data_entry_cost double NOT NULL, + data_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; + +create algorithm=temptable view v1 as SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost + FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id; + +UPDATE t2 +SET data_entry_cost + = ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) + FROM + v1 AS query + WHERE data_entry_exit_id = t2.data_entry_id + ) + ); + +UPDATE t2 +SET data_entry_cost + = ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) + FROM + ( SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost + FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id) AS query + WHERE data_entry_exit_id = t2.data_entry_id + ) + ); + +drop view v1; +drop table t1, t2; +--echo # --echo # MDEV-4410: update does not want to use a covering index, but select uses it. --echo # create table t2(a int); diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f57025bcccb..b5426ce53f4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5456,6 +5456,41 @@ EXECUTE stmt; DROP TABLE t1, t2, t3; DROP VIEW v3; +--echo # +--echo # MDEV-8632: Segmentation fault on INSERT +--echo # +CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL, + `r` float NOT NULL, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +create view v1 as select id, if(r=r,1,2) as d from t1; +create view v2 as + select id, + d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p + from v1; +insert into t1 (id, r) +select id,p from +( + select id, + d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p + from ( + select id, if(r=r,1,2) as d + from t1 + ) a +) b +on duplicate key update r=p; +insert into t1 (id, r) +select id,p from v2 +on duplicate key update r=p; + +prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop view v1,v2; +drop table `t1`; --echo # ----------------------------------------------------------------- --echo # -- End of 5.5 tests. --echo # ----------------------------------------------------------------- @@ -5500,6 +5535,151 @@ execute stmt; drop table t1, t2; drop view v3; +--echo # +--echo # MDEV-8525: mariadb 10.0.20 crashing when data is read by Kodi +--echo # media center (http://kodi.tv). +--echo # + +CREATE TABLE `t1` ( + `idSong` int(11) NOT NULL AUTO_INCREMENT, + `idAlbum` int(11) DEFAULT NULL, + `idPath` int(11) DEFAULT NULL, + `strArtists` text, + `strGenres` text, + `strTitle` varchar(512) DEFAULT NULL, + `iTrack` int(11) DEFAULT NULL, + `iDuration` int(11) DEFAULT NULL, + `iYear` int(11) DEFAULT NULL, + `dwFileNameCRC` text, + `strFileName` text, + `strMusicBrainzTrackID` text, + `iTimesPlayed` int(11) DEFAULT NULL, + `iStartOffset` int(11) DEFAULT NULL, + `iEndOffset` int(11) DEFAULT NULL, + `idThumb` int(11) DEFAULT NULL, + `lastplayed` varchar(20) DEFAULT NULL, + `rating` char(1) DEFAULT '0', + `comment` text, + `mood` text, + PRIMARY KEY (`idSong`), + UNIQUE KEY `idxSong7` (`idAlbum`,`strMusicBrainzTrackID`(36)), + KEY `idxSong` (`strTitle`(255)), + KEY `idxSong1` (`iTimesPlayed`), + KEY `idxSong2` (`lastplayed`), + KEY `idxSong3` (`idAlbum`), + KEY `idxSong6` (`idPath`,`strFileName`(255)) +) DEFAULT CHARSET=utf8; + +INSERT INTO `t1` VALUES (1,1,1,'strArtists1','strGenres1','strTitle1',1,100,2000,NULL,'strFileName1','strMusicBrainzTrackID1',0,0,0,NULL,NULL,'0','',''),(2,2,2,'strArtists2','strGenres2','strTitle2',2,200,2001,NULL,'strFileName2','strMusicBrainzTrackID2',0,0,0,NULL,NULL,'0','',''); + +CREATE TABLE `t2` ( + `idAlbum` int(11) NOT NULL AUTO_INCREMENT, + `strAlbum` varchar(256) DEFAULT NULL, + `strMusicBrainzAlbumID` text, + `strArtists` text, + `strGenres` text, + `iYear` int(11) DEFAULT NULL, + `idThumb` int(11) DEFAULT NULL, + `bCompilation` int(11) NOT NULL DEFAULT '0', + `strMoods` text, + `strStyles` text, + `strThemes` text, + `strReview` text, + `strImage` text, + `strLabel` text, + `strType` text, + `iRating` int(11) DEFAULT NULL, + `lastScraped` varchar(20) DEFAULT NULL, + `dateAdded` varchar(20) DEFAULT NULL, + `strReleaseType` text, + PRIMARY KEY (`idAlbum`), + UNIQUE KEY `idxAlbum_2` (`strMusicBrainzAlbumID`(36)), + KEY `idxAlbum` (`strAlbum`(255)), + KEY `idxAlbum_1` (`bCompilation`) +) DEFAULT CHARSET=utf8; + +INSERT INTO `t2` VALUES (1,'strAlbum1','strMusicBrainzAlbumID1','strArtists1','strGenres1',2000,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'album'); + +CREATE TABLE `t3` ( + `idArtist` int(11) DEFAULT NULL, + `idAlbum` int(11) DEFAULT NULL, + `strJoinPhrase` text, + `boolFeatured` int(11) DEFAULT NULL, + `iOrder` int(11) DEFAULT NULL, + `strArtist` text, + UNIQUE KEY `idxAlbumArtist_1` (`idAlbum`,`idArtist`), + UNIQUE KEY `idxAlbumArtist_2` (`idArtist`,`idAlbum`), + KEY `idxAlbumArtist_3` (`boolFeatured`) +) DEFAULT CHARSET=utf8; + +INSERT INTO `t3` VALUES (1,1,'',0,0,'strArtist1'); + +CREATE TABLE `t4` ( + `idArtist` int(11) NOT NULL AUTO_INCREMENT, + `strArtist` varchar(256) DEFAULT NULL, + `strMusicBrainzArtistID` text, + `strBorn` text, + `strFormed` text, + `strGenres` text, + `strMoods` text, + `strStyles` text, + `strInstruments` text, + `strBiography` text, + `strDied` text, + `strDisbanded` text, + `strYearsActive` text, + `strImage` text, + `strFanart` text, + `lastScraped` varchar(20) DEFAULT NULL, + `dateAdded` varchar(20) DEFAULT NULL, + PRIMARY KEY (`idArtist`), + UNIQUE KEY `idxArtist1` (`strMusicBrainzArtistID`(36)), + KEY `idxArtist` (`strArtist`(255)) +) DEFAULT CHARSET=utf8; + +INSERT INTO `t4` VALUES (1,'strArtist1','strMusicBrainzArtistID',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +CREATE VIEW `v1` AS select `t2`.`idAlbum` AS `idAlbum`,`t2`.`strAlbum` AS `strAlbum`,`t2`.`strMusicBrainzAlbumID` AS `strMusicBrainzAlbumID`,`t2`.`strArtists` AS `strArtists`,`t2`.`strGenres` AS `strGenres`,`t2`.`iYear` AS `iYear`,`t2`.`strMoods` AS `strMoods`,`t2`.`strStyles` AS `strStyles`,`t2`.`strThemes` AS `strThemes`,`t2`.`strReview` AS `strReview`,`t2`.`strLabel` AS `strLabel`,`t2`.`strType` AS `strType`,`t2`.`strImage` AS `strImage`,`t2`.`iRating` AS `iRating`,`t2`.`bCompilation` AS `bCompilation`,(select min(`t1`.`iTimesPlayed`) from `t1` where (`t1`.`idAlbum` = `t2`.`idAlbum`)) AS `iTimesPlayed`,`t2`.`strReleaseType` AS `strReleaseType` from `t2`; + +CREATE VIEW `v2` AS select `t3`.`idAlbum` AS `idAlbum`,`t3`.`idArtist` AS `idArtist`,`t4`.`strArtist` AS `strArtist`,`t4`.`strMusicBrainzArtistID` AS `strMusicBrainzArtistID`,`t3`.`boolFeatured` AS `boolFeatured`,`t3`.`strJoinPhrase` AS `strJoinPhrase`,`t3`.`iOrder` AS `iOrder` from (`t3` join `t4` on((`t3`.`idArtist` = `t4`.`idArtist`))); + +SELECT v1.*,v2.* FROM v1 LEFT JOIN v2 ON v1.idAlbum = v2.idAlbum WHERE v1.idAlbum = 1 ORDER BY v2.iOrder; + +drop view v1,v2; +drop table t1,t2,t3,t4; + +--echo # +--echo # MDEV-8913: Derived queries with same column names as final +--echo # projection causes issues when using Order By +--echo # +create table t1 (field int); +insert into t1 values (10),(5),(3),(8),(20); + +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM ( SELECT field AS f1, 1 AS f2 FROM t1) AS sq +ORDER BY sq.f1; + +create view v1 as SELECT field AS f1, 1 AS f2 FROM t1; + +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM v1 AS sq +ORDER BY sq.f1; + +drop view v1; + +create table t2 SELECT field AS f1, 1 AS f2 FROM t1; + +SELECT + sq.f2 AS f1, + sq.f1 AS f2 +FROM t2 AS sq +ORDER BY sq.f1; + +drop table t1, t2; + +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM (SELECT 1 as a) AS b HAVING (SELECT `SOME_GARBAGE`.b.a)=1; + --echo # ----------------------------------------------------------------- --echo # -- End of 10.0 tests. --echo # ----------------------------------------------------------------- diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 7bced68d34d..10fe5ae40c4 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -44,7 +44,7 @@ const int LF_HASH_OVERHEAD= sizeof(LF_SLIST); /* a structure to pass the context (pointers two the three successive elements - in a list) from lfind to linsert/ldelete + in a list) from l_find to l_insert/l_delete */ typedef struct { intptr volatile *prev; @@ -84,7 +84,7 @@ typedef struct { 0 - ok 1 - error (callbck returned 1) */ -static int lfind(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, +static int l_find(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, const uchar *key, uint keylen, CURSOR *cursor, LF_PINS *pins, my_hash_walk_action callback) { @@ -157,7 +157,7 @@ retry: /* DESCRIPTION insert a 'node' in the list that starts from 'head' in the correct - position (as found by lfind) + position (as found by l_find) RETURN 0 - inserted @@ -167,7 +167,7 @@ retry: it uses pins[0..2], on return all pins are removed. if there're nodes with the same key value, a new node is added before them. */ -static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, +static LF_SLIST *l_insert(LF_SLIST * volatile *head, CHARSET_INFO *cs, LF_SLIST *node, LF_PINS *pins, uint flags) { CURSOR cursor; @@ -175,7 +175,7 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, for (;;) { - if (lfind(head, cs, node->hashnr, node->key, node->keylen, + if (l_find(head, cs, node->hashnr, node->key, node->keylen, &cursor, pins, 0) && (flags & LF_HASH_UNIQUE)) { @@ -219,7 +219,7 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, NOTE it uses pins[0..2], on return all pins are removed. */ -static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, +static int l_delete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, const uchar *key, uint keylen, LF_PINS *pins) { CURSOR cursor; @@ -227,7 +227,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, for (;;) { - if (!lfind(head, cs, hashnr, key, keylen, &cursor, pins, 0)) + if (!l_find(head, cs, hashnr, key, keylen, &cursor, pins, 0)) { res= 1; /* not found */ break; @@ -251,7 +251,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, (to ensure the number of "set DELETED flag" actions is equal to the number of "remove from the list" actions) */ - lfind(head, cs, hashnr, key, keylen, &cursor, pins, 0); + l_find(head, cs, hashnr, key, keylen, &cursor, pins, 0); } res= 0; break; @@ -277,12 +277,12 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, it uses pins[0..2], on return the pin[2] keeps the node found all other pins are removed. */ -static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs, +static LF_SLIST *l_search(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, const uchar *key, uint keylen, LF_PINS *pins) { CURSOR cursor; - int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins, 0); + int res= l_find(head, cs, hashnr, key, keylen, &cursor, pins, 0); if (res) lf_pin(pins, 2, cursor.curr); else @@ -392,7 +392,7 @@ void lf_hash_destroy(LF_HASH *hash) -1 - out of memory NOTE - see linsert() for pin usage notes + see l_insert() for pin usage notes */ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) { @@ -412,7 +412,7 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) return -1; node->hashnr= my_reverse_bits(hashnr) | 1; /* normal node */ - if (linsert(el, hash->charset, node, pins, hash->flags)) + if (l_insert(el, hash->charset, node, pins, hash->flags)) { lf_alloc_free(pins, node); return 1; @@ -432,7 +432,7 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) 0 - deleted 1 - didn't (not found) NOTE - see ldelete() for pin usage notes + see l_delete() for pin usage notes */ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) { @@ -450,7 +450,7 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) if (unlikely(bucket == 0)) return 1; /* if there's no bucket==0, the hash is empty */ } - if (ldelete(el, hash->charset, my_reverse_bits(hashnr) | 1, + if (l_delete(el, hash->charset, my_reverse_bits(hashnr) | 1, (uchar *)key, keylen, pins)) { return 1; @@ -466,7 +466,7 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) NULL if nothing is found NOTE - see lsearch() for pin usage notes + see l_search() for pin usage notes */ void *lf_hash_search_using_hash_value(LF_HASH *hash, LF_PINS *pins, my_hash_value_type hashnr, @@ -484,7 +484,7 @@ void *lf_hash_search_using_hash_value(LF_HASH *hash, LF_PINS *pins, if (unlikely(bucket == 0)) return 0; /* if there's no bucket==0, the hash is empty */ } - found= lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1, + found= l_search(el, hash->charset, my_reverse_bits(hashnr) | 1, (uchar *)key, keylen, pins); return found ? found+1 : 0; } @@ -514,7 +514,7 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins, if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) return 0; /* if there's no bucket==0, the hash is empty */ - res= lfind(el, 0, 0, (uchar*)argument, 0, &cursor, pins, action); + res= l_find(el, 0, 0, (uchar*)argument, 0, &cursor, pins, action); lf_unpin(pins, 2); lf_unpin(pins, 1); @@ -553,16 +553,16 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node, dummy->hashnr= my_reverse_bits(bucket) | 0; /* dummy node */ dummy->key= dummy_key; dummy->keylen= 0; - if ((cur= linsert(el, hash->charset, dummy, pins, LF_HASH_UNIQUE))) + if ((cur= l_insert(el, hash->charset, dummy, pins, LF_HASH_UNIQUE))) { my_free(dummy); dummy= cur; } my_atomic_casptr((void **)node, (void **)(char*) &tmp, dummy); /* - note that if the CAS above failed (after linsert() succeeded), - it would mean that some other thread has executed linsert() for - the same dummy node, its linsert() failed, it picked up our + note that if the CAS above failed (after l_insert() succeeded), + it would mean that some other thread has executed l_insert() for + the same dummy node, its l_insert() failed, it picked up our dummy node (in "dummy= cur") and executed the same CAS as above. Which means that even if CAS above failed we don't need to retry, and we should not free(dummy) - there's no memory leak here diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 38c4c10c7f1..e6e04efe121 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -3722,10 +3722,12 @@ mariadb_dyncol_check(DYNAMIC_COLUMN *str) if (prev_type != DYN_COL_NULL) { /* It is not first entry */ - if (prev_data_offset >= data_offset) + if (prev_data_offset > data_offset || + ((prev_type != DYN_COL_INT && + prev_type != DYN_COL_UINT) && prev_data_offset == data_offset)) { DBUG_PRINT("info", ("Field order: %u Previous data offset: %u" - " >= Current data offset: %u", + " >(=) Current data offset: %u", (uint)i, (uint)prev_data_offset, (uint)data_offset)); diff --git a/mysys/my_rdtsc.c b/mysys/my_rdtsc.c index c624a5ca288..82e560944f9 100644 --- a/mysys/my_rdtsc.c +++ b/mysys/my_rdtsc.c @@ -129,6 +129,31 @@ ulonglong my_timer_cycles_il_x86_64(); clock_gettime(CLOCK_SGI_CYCLE) for Irix platforms, or on read_real_time for aix platforms. There is nothing for Alpha platforms, they would be tricky. + + On the platforms that do not have a CYCLE timer, + "wait" events are initialized to use NANOSECOND instead of CYCLE + during performance_schema initialization (at the server startup). + + Linux performance monitor (see "man perf_event_open") can + provide cycle counter on the platforms that do not have + other kinds of cycle counters. But we don't use it so far. + + ARM notes + --------- + During tests on ARMv7 Debian, perf_even_open() based cycle counter provided + too low frequency with too high overhead: + MariaDB [performance_schema]> SELECT * FROM performance_timers; + +-------------+-----------------+------------------+----------------+ + | TIMER_NAME | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD | + +-------------+-----------------+------------------+----------------+ + | CYCLE | 689368159 | 1 | 970 | + | NANOSECOND | 1000000000 | 1 | 308 | + | MICROSECOND | 1000000 | 1 | 417 | + | MILLISECOND | 1000 | 1000 | 407 | + | TICK | 127 | 1 | 612 | + +-------------+-----------------+------------------+----------------+ + Therefore, it was decided not to use perf_even_open() on ARM + (i.e. go without CYCLE and have "wait" events use NANOSECOND by default). */ ulonglong my_timer_cycles(void) diff --git a/pcre/CMakeLists.txt b/pcre/CMakeLists.txt index 90ebc0d5100..a4faef6f47a 100644 --- a/pcre/CMakeLists.txt +++ b/pcre/CMakeLists.txt @@ -311,11 +311,6 @@ IF(MSVC) ENDIF(MSVC) SET(CMAKE_INCLUDE_CURRENT_DIR 1) -# needed to make sure to not link debug libs -# against release libs and vice versa -IF(WIN32) - SET(CMAKE_DEBUG_POSTFIX "d") -ENDIF(WIN32) SET(targets) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index e0c8738eae3..dcfa9e07476 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -22,6 +22,10 @@ extern ST_SCHEMA_TABLE schema_tables[]; namespace feedback { +#ifndef DBUG_OFF +ulong debug_startup_interval, debug_first_interval, debug_interval; +#endif + char server_uid_buf[SERVER_UID_SIZE+1]; ///< server uid will be written here /* backing store for system variables */ @@ -253,6 +257,18 @@ static int init(void *p) prepare_linux_info(); +#ifndef DBUG_OFF + if (startup_interval != debug_startup_interval || + first_interval != debug_first_interval || + interval != debug_interval) + { + startup_interval= debug_startup_interval; + first_interval= debug_first_interval; + interval= debug_interval; + user_info= "mysql-test"; + } +#endif + url_count= 0; if (*url) { @@ -361,6 +377,18 @@ static MYSQL_SYSVAR_STR(http_proxy, http_proxy, "Proxy server host:port.", NULL, NULL,0); +#ifndef DBUG_OFF +static MYSQL_SYSVAR_ULONG(debug_startup_interval, debug_startup_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, startup_interval, 1, INT_MAX32, 1); +static MYSQL_SYSVAR_ULONG(debug_first_interval, debug_first_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, first_interval, 1, INT_MAX32, 1); +static MYSQL_SYSVAR_ULONG(debug_interval, debug_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, interval, 1, INT_MAX32, 1); +#endif + static struct st_mysql_sys_var* settings[] = { MYSQL_SYSVAR(server_uid), MYSQL_SYSVAR(user_info), @@ -368,6 +396,11 @@ static struct st_mysql_sys_var* settings[] = { MYSQL_SYSVAR(send_timeout), MYSQL_SYSVAR(send_retry_wait), MYSQL_SYSVAR(http_proxy), +#ifndef DBUG_OFF + MYSQL_SYSVAR(debug_startup_interval), + MYSQL_SYSVAR(debug_first_interval), + MYSQL_SYSVAR(debug_interval), +#endif NULL }; diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h index 6c4794e451b..9ac2997c158 100644 --- a/plugin/feedback/feedback.h +++ b/plugin/feedback/feedback.h @@ -65,6 +65,10 @@ class Url { extern Url **urls; extern uint url_count; +extern time_t startup_interval; +extern time_t first_interval; +extern time_t interval; + /* these are used to communicate with the background thread */ extern mysql_mutex_t sleep_mutex; extern mysql_cond_t sleep_condition; diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 732118f245e..bbf7f567811 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -26,9 +26,9 @@ static my_thread_id thd_thread_id; ///< its thread_id static size_t needed_size= 20480; -static const time_t startup_interval= 60*5; ///< in seconds (5 minutes) -static const time_t first_interval= 60*60*24; ///< in seconds (one day) -static const time_t interval= 60*60*24*7; ///< in seconds (one week) +time_t startup_interval= 60*5; ///< in seconds (5 minutes) +time_t first_interval= 60*60*24; ///< in seconds (one day) +time_t interval= 60*60*24*7; ///< in seconds (one week) /** reads the rows from a table and puts them, concatenated, in a String @@ -125,6 +125,7 @@ static int prepare_for_fill(TABLE_LIST *tables) if (!tables->table) return 1; + tables->select_lex= thd->lex->current_select; tables->table->pos_in_table_list= tables; return 0; @@ -260,7 +261,7 @@ ret: the effect of the background thread on SHOW STATUS. */ mysql_mutex_lock(&LOCK_thread_count); - bzero(&thd->status_var, sizeof(thd->status_var)); + thd->set_status_var_init(); thread_count--; thd->killed= KILL_CONNECTION; mysql_cond_broadcast(&COND_thread_count); diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index b1f7fbd8b07..bbe4e3fb7a4 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -746,8 +746,10 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, /* At this point, the binlog file and position of this transaction must have been removed from ActiveTranx. + active_tranxs_ may be NULL if someone disabled semi sync during + cond_timewait() */ - assert(thd_killed(current_thd) || + assert(thd_killed(current_thd) || !active_tranxs_ || !active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name, trx_wait_binlog_pos)); diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index d91e31cda48..82ea1b60a17 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -24,7 +24,6 @@ rootpass="" echo_n= echo_c= basedir= -bindir= defaults_file= defaults_extra_file= no_defaults= @@ -159,8 +158,15 @@ then cannot_find_file my_print_defaults $basedir/bin $basedir/extra exit 1 fi + mysql_command=`find_in_basedir mysql bin` + if test -z "$mysql_command" + then + cannot_find_file mysql $basedir/bin + exit 1 + fi else print_defaults="@bindir@/my_print_defaults" + mysql_command="@bindir@/mysql" fi if test ! -x "$print_defaults" @@ -169,29 +175,17 @@ then exit 1 fi +if test ! -x "$mysql_command" +then + cannot_find_file "$mysql_command" + exit 1 +fi + # Now we can get arguments from the group [client] and [client-server] # in the my.cfg file, then re-run to merge with command line arguments. parse_arguments `$print_defaults $defaults_file $defaults_extra_file $no_defaults client client-server client-mariadb` parse_arguments PICK-ARGS-FROM-ARGV "$@" -# Configure paths to support files -if test -n "$basedir" -then - bindir="$basedir/bin" -elif test -f "./bin/mysql" - then - bindir="./bin" -else - bindir="@bindir@" -fi - -mysql_command=`find_in_basedir mysql $bindir` -if test -z "$mysql_command" -then - cannot_find_file mysql $bindir - exit 1 -fi - set_echo_compat() { case `echo "testing\c"`,`echo -n testing` in *c*,-n*) echo_n= echo_c= ;; diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index eea65f285d3..b878a2e636e 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -220,7 +220,7 @@ set @had_proxies_priv_table= @@warning_count != 0; CREATE TABLE IF NOT EXISTS table_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, cardinality bigint(21) unsigned DEFAULT NULL, PRIMARY KEY (db_name,table_name) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Tables'; -CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varchar(255) DEFAULT NULL, max_value varchar(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB'), histogram varbinary(255), PRIMARY KEY (db_name,table_name,column_name) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; +CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varbinary(255) DEFAULT NULL, max_value varbinary(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB'), histogram varbinary(255), PRIMARY KEY (db_name,table_name,column_name) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; CREATE TABLE IF NOT EXISTS index_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, index_name varchar(64) NOT NULL, prefix_arity int(11) unsigned NOT NULL, avg_frequency decimal(12,4) DEFAULT NULL, PRIMARY KEY (db_name,table_name,index_name,prefix_arity) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Indexes'; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index ec47a1c65db..ea1059cdd78 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -600,6 +600,8 @@ ALTER TABLE event ADD body_utf8 longblob DEFAULT NULL AFTER db_collation; ALTER TABLE event MODIFY body_utf8 longblob DEFAULT NULL; +# Enable event scheduler if the event table was not up to date before. +set global event_scheduler=original; # # TRIGGER privilege @@ -719,3 +721,5 @@ flush privileges; ALTER TABLE help_category MODIFY url TEXT NOT NULL; ALTER TABLE help_topic MODIFY url TEXT NOT NULL; +# MDEV-7383 - varbinary on mix/max of column_stats +alter table column_stats modify min_value varbinary(255) DEFAULT NULL, modify max_value varbinary(255) DEFAULT NULL; diff --git a/sql-common/client.c b/sql-common/client.c index 609eef5d8b7..143d3fae068 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -170,188 +170,6 @@ static int get_vio_connect_timeout(MYSQL *mysql) } -/**************************************************************************** - A modified version of connect(). my_connect() allows you to specify - a timeout value, in seconds, that we should wait until we - derermine we can't connect to a particular host. If timeout is 0, - my_connect() will behave exactly like connect(). - - Base version coded by Steve Bernacki, Jr. <steve@navinet.net> -*****************************************************************************/ - -int my_connect(my_socket fd, const struct sockaddr *name, uint namelen, - uint timeout) -{ -#if defined(__WIN__) - DBUG_ENTER("my_connect"); - DBUG_RETURN(connect(fd, (struct sockaddr*) name, namelen)); -#else - int flags, res, s_err; - DBUG_ENTER("my_connect"); - DBUG_PRINT("enter", ("fd: %d timeout: %u", fd, timeout)); - - /* - If they passed us a timeout of zero, we should behave - exactly like the normal connect() call does. - */ - - if (timeout == 0) - DBUG_RETURN(connect(fd, (struct sockaddr*) name, namelen)); - - flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */ -#ifdef O_NONBLOCK - fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ -#endif - - DBUG_PRINT("info", ("connecting non-blocking")); - res= connect(fd, (struct sockaddr*) name, namelen); - DBUG_PRINT("info", ("connect result: %d errno: %d", res, errno)); - s_err= errno; /* Save the error... */ - fcntl(fd, F_SETFL, flags); - if ((res != 0) && (s_err != EINPROGRESS)) - { - errno= s_err; /* Restore it */ - DBUG_RETURN(-1); - } - if (res == 0) /* Connected quickly! */ - DBUG_RETURN(0); - DBUG_RETURN(wait_for_data(fd, timeout)); -#endif -} - - -/* - Wait up to timeout seconds for a connection to be established. - - We prefer to do this with poll() as there is no limitations with this. - If not, we will use select() -*/ - -#if !defined(__WIN__) - -static int wait_for_data(my_socket fd, uint timeout) -{ -#ifdef HAVE_POLL - struct pollfd ufds; - int res; - DBUG_ENTER("wait_for_data"); - - DBUG_PRINT("info", ("polling")); - ufds.fd= fd; - ufds.events= POLLIN | POLLPRI; - if (!(res= poll(&ufds, 1, (int) timeout*1000))) - { - DBUG_PRINT("info", ("poll timed out")); - errno= EINTR; - DBUG_RETURN(-1); - } - DBUG_PRINT("info", - ("poll result: %d errno: %d revents: 0x%02d events: 0x%02d", - res, errno, ufds.revents, ufds.events)); - if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) - DBUG_RETURN(-1); - /* - At this point, we know that something happened on the socket. - But this does not means that everything is alright. - The connect might have failed. We need to retrieve the error code - from the socket layer. We must return success only if we are sure - that it was really a success. Otherwise we might prevent the caller - from trying another address to connect to. - */ - { - int s_err; - socklen_t s_len= sizeof(s_err); - - DBUG_PRINT("info", ("Get SO_ERROR from non-blocked connected socket.")); - res= getsockopt(fd, SOL_SOCKET, SO_ERROR, &s_err, &s_len); - DBUG_PRINT("info", ("getsockopt res: %d s_err: %d", res, s_err)); - if (res) - DBUG_RETURN(res); - /* getsockopt() was successful, check the retrieved status value. */ - if (s_err) - { - errno= s_err; - DBUG_RETURN(-1); - } - /* Status from connect() is zero. Socket is successfully connected. */ - } - DBUG_RETURN(0); -#else - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - time_t start_time, now_time; - int res, s_err; - DBUG_ENTER("wait_for_data"); - - if (fd >= FD_SETSIZE) /* Check if wrong error */ - DBUG_RETURN(0); /* Can't use timeout */ - - /* - Our connection is "in progress." We can use the select() call to wait - up to a specified period of time for the connection to suceed. - If select() returns 0 (after waiting howevermany seconds), our socket - never became writable (host is probably unreachable.) Otherwise, if - select() returns 1, then one of two conditions exist: - - 1. An error occured. We use getsockopt() to check for this. - 2. The connection was set up sucessfully: getsockopt() will - return 0 as an error. - - Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk> - who posted this method of timing out a connect() in - comp.unix.programmer on August 15th, 1997. - */ - - FD_ZERO(&sfds); - FD_SET(fd, &sfds); - /* - select could be interrupted by a signal, and if it is, - the timeout should be adjusted and the select restarted - to work around OSes that don't restart select and - implementations of select that don't adjust tv upon - failure to reflect the time remaining - */ - start_time= my_time(0); - for (;;) - { - tv.tv_sec = (long) timeout; - tv.tv_usec = 0; -#if defined(HPUX10) - if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0) - break; -#else - if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0) - break; -#endif - if (res == 0) /* timeout */ - DBUG_RETURN(-1); - now_time= my_time(0); - timeout-= (uint) (now_time - start_time); - if (errno != EINTR || (int) timeout <= 0) - DBUG_RETURN(-1); - } - - /* - select() returned something more interesting than zero, let's - see if we have any errors. If the next two statements pass, - we've got an open socket! - */ - - s_err=0; - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) - DBUG_RETURN(-1); - - if (s_err) - { /* getsockopt could succeed */ - errno = s_err; - DBUG_RETURN(-1); /* but return an error... */ - } - DBUG_RETURN(0); /* ok */ -#endif /* HAVE_POLL */ -} -#endif /* !defined(__WIN__) */ - /** Set the internal error message to mysql handler @@ -3165,19 +2983,20 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, static int connect_sync_or_async(MYSQL *mysql, NET *net, my_socket fd, - const struct sockaddr *name, uint namelen) + struct sockaddr *name, uint namelen) { + int vio_timeout = get_vio_connect_timeout(mysql); + if (mysql->options.extension && mysql->options.extension->async_context && mysql->options.extension->async_context->active) { my_bool old_mode; - int vio_timeout= get_vio_connect_timeout(mysql); vio_blocking(net->vio, FALSE, &old_mode); return my_connect_async(mysql->options.extension->async_context, fd, name, namelen, vio_timeout); } - return my_connect(fd, name, namelen, mysql->options.connect_timeout); + return vio_socket_connect(net->vio, name, namelen, vio_timeout); } diff --git a/sql/events.cc b/sql/events.cc index 2bb112867bf..abc798b659a 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -80,7 +80,8 @@ Event_queue *Events::event_queue; Event_scheduler *Events::scheduler; Event_db_repository *Events::db_repository; ulong Events::opt_event_scheduler= Events::EVENTS_OFF; -bool Events::check_system_tables_error= FALSE; +ulong Events::startup_state= Events::EVENTS_OFF; +ulong Events::inited; /* @@ -114,7 +115,7 @@ bool Events::check_if_system_tables_error() { DBUG_ENTER("Events::check_if_system_tables_error"); - if (check_system_tables_error) + if (!inited) { my_error(ER_EVENTS_DB_ERROR, MYF(0)); DBUG_RETURN(TRUE); @@ -257,10 +258,10 @@ common_1_lev_code: /** - Create a new query string for removing executable comments - for avoiding leak and keeping consistency of the execution + Create a new query string for removing executable comments + for avoiding leak and keeping consistency of the execution on master and slave. - + @param[in] thd Thread handler @param[in] buf Query string @@ -287,7 +288,7 @@ create_query_string(THD *thd, String *buf) thd->lex->stmt_definition_end - thd->lex->stmt_definition_begin)) return 1; - + return 0; } @@ -340,8 +341,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data) if (parse_data->do_not_create) DBUG_RETURN(FALSE); - /* - Turn off row binlogging of this statement and use statement-based + /* + Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE EVENT command. */ save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); @@ -392,8 +393,10 @@ Events::create_event(THD *thd, Event_parse_data *parse_data) String log_query(buffer, sizeof(buffer), &my_charset_bin); if (create_query_string(thd, &log_query)) { - sql_print_error("Event Error: An error occurred while creating query " - "string, before writing it into binary log."); + my_message_sql(ER_STARTUP, + "Event Error: An error occurred while creating query " + "string, before writing it into binary log.", + MYF(ME_NOREFRESH)); ret= true; } else @@ -481,8 +484,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, } } - /* - Turn off row binlogging of this statement and use statement-based + /* + Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for UPDATE EVENT command. */ save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); @@ -769,6 +772,13 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) int ret; DBUG_ENTER("Events::fill_schema_events"); + /* + If we didn't start events because of --skip-grant-tables, return an + empty set + */ + if (opt_noacl) + DBUG_RETURN(0); + if (check_if_system_tables_error()) DBUG_RETURN(1); @@ -797,6 +807,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) /** Initializes the scheduler's structures. + @param THD or null (if called by init) @param opt_noacl_or_bootstrap TRUE if there is --skip-grant-tables or --bootstrap option. In that case we disable the event scheduler. @@ -804,44 +815,56 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) @note This function is not synchronized. @retval FALSE Perhaps there was an error, and the event scheduler - is disabled. But the error is not fatal and the + is disabled. But the error is not fatal and the server start up can continue. @retval TRUE Fatal error. Startup must terminate (call unireg_abort()). */ bool -Events::init(bool opt_noacl_or_bootstrap) +Events::init(THD *thd, bool opt_noacl_or_bootstrap) { - - THD *thd; int err_no; bool res= FALSE; - + bool had_thd= thd != 0; DBUG_ENTER("Events::init"); + DBUG_ASSERT(inited == 0); + + /* + Was disabled explicitly from the command line + */ + if (opt_event_scheduler == Events::EVENTS_DISABLED || + opt_noacl_or_bootstrap) + DBUG_RETURN(FALSE); + /* We need a temporary THD during boot */ - if (!(thd= new THD())) + if (!thd) { - res= TRUE; - goto end; + + if (!(thd= new THD())) + { + res= TRUE; + goto end; + } + /* + The thread stack does not start from this function but we cannot + guess the real value. So better some value that doesn't assert than + no value. + */ + thd->thread_stack= (char*) &thd; + thd->store_globals(); + /* + Set current time for the thread that handles events. + Current time is stored in data member start_time of THD class. + Subsequently, this value is used to check whether event was expired + when make loading events from storage. Check for event expiration time + is done at Event_queue_element::compute_next_execution_time() where + event's status set to Event_parse_data::DISABLED and dropped flag set + to true if event was expired. + */ + thd->set_time(); } - /* - The thread stack does not start from this function but we cannot - guess the real value. So better some value that doesn't assert than - no value. - */ - thd->thread_stack= (char*) &thd; - thd->store_globals(); - /* - Set current time for the thread that handles events. - Current time is stored in data member start_time of THD class. - Subsequently, this value is used to check whether event was expired - when make loading events from storage. Check for event expiration time - is done at Event_queue_element::compute_next_execution_time() where - event's status set to Event_parse_data::DISABLED and dropped flag set - to true if event was expired. - */ - thd->set_time(); + /* We will need Event_db_repository anyway, even if the scheduler is disabled - to perform events DDL. @@ -861,28 +884,19 @@ Events::init(bool opt_noacl_or_bootstrap) are most likely not there and we're going to disable the event scheduler anyway. */ - if (opt_noacl_or_bootstrap || Event_db_repository::check_system_tables(thd)) + if (Event_db_repository::check_system_tables(thd)) { - if (! opt_noacl_or_bootstrap) - { - sql_print_error("Event Scheduler: An error occurred when initializing " - "system tables. Disabling the Event Scheduler."); - check_system_tables_error= TRUE; - } - + delete db_repository; + db_repository= 0; + my_message(ER_STARTUP, + "Event Scheduler: An error occurred when initializing " + "system tables. Disabling the Event Scheduler.", + MYF(ME_NOREFRESH)); /* Disable the scheduler since the system tables are not up to date */ - opt_event_scheduler= EVENTS_DISABLED; + opt_event_scheduler= EVENTS_OFF; goto end; } - /* - Was disabled explicitly from the command line, or because we're running - with --skip-grant-tables, or --bootstrap, or because we have no system - tables. - */ - if (opt_event_scheduler == Events::EVENTS_DISABLED) - goto end; - DBUG_ASSERT(opt_event_scheduler == Events::EVENTS_ON || opt_event_scheduler == Events::EVENTS_OFF); @@ -897,20 +911,20 @@ Events::init(bool opt_noacl_or_bootstrap) if (event_queue->init_queue(thd) || load_events_from_db(thd) || (opt_event_scheduler == EVENTS_ON && scheduler->start(&err_no))) { - sql_print_error("Event Scheduler: Error while loading from disk."); + my_message_sql(ER_STARTUP, + "Event Scheduler: Error while loading from mysql.event table.", + MYF(ME_NOREFRESH)); res= TRUE; /* fatal error: request unireg_abort */ goto end; } Event_worker_thread::init(db_repository); + inited= 1; end: if (res) - { - delete db_repository; - delete event_queue; - delete scheduler; - } - delete thd; + deinit(); + if (!had_thd) + delete thd; DBUG_RETURN(res); } @@ -930,17 +944,14 @@ Events::deinit() { DBUG_ENTER("Events::deinit"); - if (opt_event_scheduler != EVENTS_DISABLED) - { - delete scheduler; - scheduler= NULL; /* safety */ - delete event_queue; - event_queue= NULL; /* safety */ - } - + delete scheduler; + scheduler= NULL; /* For restart */ + delete event_queue; + event_queue= NULL; /* For restart */ delete db_repository; - db_repository= NULL; /* safety */ + db_repository= NULL; /* For restart */ + inited= 0; DBUG_VOID_RETURN; } @@ -1043,7 +1054,7 @@ Events::dump_internal_status() holding LOCK_global_system_variables. */ mysql_mutex_lock(&LOCK_global_system_variables); - if (opt_event_scheduler == EVENTS_DISABLED) + if (!inited) puts("The Event Scheduler is disabled"); else { @@ -1057,11 +1068,13 @@ Events::dump_internal_status() bool Events::start(int *err_no) { + DBUG_ASSERT(inited); return scheduler->start(err_no); } bool Events::stop() { + DBUG_ASSERT(inited); return scheduler->stop(); } @@ -1091,7 +1104,6 @@ Events::load_events_from_db(THD *thd) bool ret= TRUE; uint count= 0; ulong saved_master_access; - DBUG_ENTER("Events::load_events_from_db"); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); @@ -1116,7 +1128,9 @@ Events::load_events_from_db(THD *thd) if (ret) { - sql_print_error("Event Scheduler: Failed to open table mysql.event"); + my_message_sql(ER_STARTUP, + "Event Scheduler: Failed to open table mysql.event", + MYF(ME_NOREFRESH)); DBUG_RETURN(TRUE); } @@ -1138,9 +1152,11 @@ Events::load_events_from_db(THD *thd) if (et->load_from_row(thd, table)) { - sql_print_error("Event Scheduler: " - "Error while loading events from mysql.event. " - "The table probably contains bad data or is corrupted"); + my_message(ER_STARTUP, + "Event Scheduler: " + "Error while loading events from mysql.event. " + "The table probably contains bad data or is corrupted", + MYF(ME_NOREFRESH)); delete et; goto end; } @@ -1177,9 +1193,12 @@ Events::load_events_from_db(THD *thd) } } } - if (global_system_variables.log_warnings) - sql_print_information("Event Scheduler: Loaded %d event%s", - count, (count == 1) ? "" : "s"); + my_printf_error(ER_STARTUP, + "Event Scheduler: Loaded %d event%s", + MYF(ME_NOREFRESH | + (global_system_variables.log_warnings) ? + ME_JUST_INFO: 0), + count, (count == 1) ? "" : "s"); ret= FALSE; end: diff --git a/sql/events.h b/sql/events.h index bc2af1fb4de..368aa9a05d5 100644 --- a/sql/events.h +++ b/sql/events.h @@ -79,9 +79,11 @@ public: and the @@global.event_scheduler SQL variable. See sys_var.cc */ - enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED }; + enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED, + EVENTS_ORIGINAL }; /* Protected using LOCK_global_system_variables only. */ - static ulong opt_event_scheduler; + static ulong opt_event_scheduler, startup_state; + static ulong inited; static bool check_if_system_tables_error(); static bool start(int *err_no); static bool stop(); @@ -91,8 +93,7 @@ public: static Event_db_repository * get_db_repository() { return db_repository; } - static bool - init(bool opt_noacl); + static bool init(THD *thd, bool opt_noacl); static void deinit(); @@ -130,6 +131,11 @@ public: static void dump_internal_status(); + static void set_original_state(ulong startup_state_org) + { + startup_state= startup_state_org; + } + private: static bool @@ -139,8 +145,6 @@ private: static Event_queue *event_queue; static Event_scheduler *scheduler; static Event_db_repository *db_repository; - /* Set to TRUE if an error at start up */ - static bool check_system_tables_error; private: /* Prevent use of these */ diff --git a/sql/filesort.cc b/sql/filesort.cc index ef91e227928..917b9de6038 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -25,7 +25,6 @@ #include <my_global.h> #include "sql_priv.h" #include "filesort.h" -#include "unireg.h" // REQUIRED by other includes #ifdef HAVE_STDDEF_H #include <stddef.h> /* for macro offsetof */ #endif diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 043f7fb280b..0e009e76066 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5271,6 +5271,7 @@ err: { (void) m_file[j]->ha_index_end(); } + destroy_record_priority_queue(); } DBUG_RETURN(error); } diff --git a/sql/handler.cc b/sql/handler.cc index 0f341a0ccc5..193d36a1122 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5113,7 +5113,7 @@ bool Discovered_table_list::add_table(const char *tname, size_t tlen) custom discover_table_names() method, that calls add_table() directly). Note: avoid comparing the same name twice (here and in add_file). */ - if (wild && my_wildcmp(files_charset_info, tname, tname + tlen, wild, wend, + if (wild && my_wildcmp(table_alias_charset, tname, tname + tlen, wild, wend, wild_prefix, wild_one, wild_many)) return 0; diff --git a/sql/hostname.cc b/sql/hostname.cc index 656663a9692..6aef84f1b26 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -26,6 +26,7 @@ */ #include <my_global.h> #include "sql_priv.h" +#include "unireg.h" // SPECIAL_NO_HOST_CACHE #include "hostname.h" #include "unireg.h" #ifndef __WIN__ diff --git a/sql/item.cc b/sql/item.cc index a1a91007a0a..0f10ccbd88c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -21,7 +21,6 @@ #endif #include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include <mysql.h> #include <m_ctype.h> #include "my_dir.h" @@ -4676,8 +4675,24 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) As this is an outer field it should be added to the list of non aggregated fields of the outer select. */ - marker= select->cur_pos_in_select_list; - select->join->non_agg_fields.push_back(this, thd->mem_root); + if (select->join) + { + marker= select->cur_pos_in_select_list; + select->join->non_agg_fields.push_back(this, thd->mem_root); + } + else + { + /* + join is absent if it is upper SELECT_LEX of non-select + command + */ + DBUG_ASSERT(select->master_unit()->outer_select() == NULL && + (thd->lex->sql_command != SQLCOM_SELECT && + thd->lex->sql_command != SQLCOM_UPDATE_MULTI && + thd->lex->sql_command != SQLCOM_DELETE_MULTI && + thd->lex->sql_command != SQLCOM_INSERT_SELECT && + thd->lex->sql_command != SQLCOM_REPLACE_SELECT)); + } } if (*from_field != view_ref_found) { @@ -6582,6 +6597,7 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg) { List<Item> *all_fields= &select->join->all_fields; Item **ref_pointer_array= select->ref_pointer_array; + DBUG_ASSERT(all_fields->elements <= select->ref_pointer_array_size); int el= all_fields->elements; Item_ref *ref; diff --git a/sql/item.h b/sql/item.h index e662eed4a71..e262ce9d12d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -25,7 +25,6 @@ #include "sql_priv.h" /* STRING_BUFFER_USUAL_SIZE */ #include "unireg.h" #include "sql_const.h" /* RAND_TABLE_BIT, MAX_FIELD_NAME */ -#include "unireg.h" // REQUIRED: for other includes #include "thr_malloc.h" /* sql_calloc */ #include "field.h" /* Derivation */ #include "sql_type.h" @@ -4264,6 +4263,8 @@ public: bool eq(const Item *item, bool binary_cmp) const; Item *get_tmp_table_item(THD *thd) { + if (const_item()) + return copy_or_same(thd); Item *item= Item_ref::get_tmp_table_item(thd); item->name= name; return item; diff --git a/sql/key.cc b/sql/key.cc index aaecbda57ad..1b00e951de0 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -18,7 +18,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: by includes later #include "key.h" // key_rec_cmp #include "field.h" // Field diff --git a/sql/lock.cc b/sql/lock.cc index 7e7b378bfb4..2e44786d6fe 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -73,7 +73,6 @@ #include <my_global.h> #include "sql_priv.h" #include "debug_sync.h" -#include "unireg.h" // REQUIRED: for other includes #include "lock.h" #include "sql_base.h" // close_tables_for_reopen #include "sql_parse.h" // is_log_table_write_query diff --git a/sql/log.cc b/sql/log.cc index cea3d7e855e..ddf6bd07695 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -8013,12 +8013,14 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd, int ret= 0; DBUG_ENTER("wait_for_update_bin_log"); + thd_wait_begin(thd, THD_WAIT_BINLOG); mysql_mutex_assert_owner(&LOCK_log); if (!timeout) mysql_cond_wait(&update_cond, &LOCK_log); else ret= mysql_cond_timedwait(&update_cond, &LOCK_log, const_cast<struct timespec *>(timeout)); + thd_wait_end(thd); DBUG_RETURN(ret); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f9a3c2a0b3a..9dcf87adecb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5876,7 +5876,15 @@ int mysqld_main(int argc, char **argv) execute_ddl_log_recovery(); - if (Events::init(opt_noacl || opt_bootstrap)) + /* + Change EVENTS_ORIGINAL to EVENTS_OFF (the default value) as there is no + point in using ORIGINAL during startup + */ + if (Events::opt_event_scheduler == Events::EVENTS_ORIGINAL) + Events::opt_event_scheduler= Events::EVENTS_OFF; + + Events::set_original_state(Events::opt_event_scheduler); + if (Events::init((THD*) 0, opt_noacl || opt_bootstrap)) unireg_abort(1); if (WSREP_ON) diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index e8cff9e69ab..f36887eb137 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -341,7 +341,8 @@ int opt_sum_query(THD *thd, there are no outer joins. */ if (!conds && !((Item_sum_count*) item)->get_arg(0)->maybe_null && - !outer_tables && maybe_exact_count) + !outer_tables && maybe_exact_count && + ((item->used_tables() & OUTER_REF_TABLE_BIT) == 0)) { if (!is_exact_count) { @@ -369,7 +370,8 @@ int opt_sum_query(THD *thd, indexes to find the key. */ Item *expr=item_sum->get_arg(0); - if (expr->real_item()->type() == Item::FIELD_ITEM) + if (((expr->used_tables() & OUTER_REF_TABLE_BIT) == 0) && + expr->real_item()->type() == Item::FIELD_ITEM) { uchar key_buff[MAX_KEY_LENGTH]; TABLE_REF ref; diff --git a/sql/protocol.cc b/sql/protocol.cc index 249dd73e2df..fa42915f5a9 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -27,7 +27,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "protocol.h" #include "sql_class.h" // THD #include <stdarg.h> diff --git a/sql/records.cc b/sql/records.cc index b6d68a5017f..ebda0ed35b0 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -66,10 +66,12 @@ static int rr_index_desc(READ_RECORD *info); @param reverse Scan in the reverse direction */ -void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, +bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse) { int error; + DBUG_ENTER("init_read_record_idx"); + empty_record(table); bzero((char*) info,sizeof(*info)); info->thd= thd; @@ -88,6 +90,7 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, /* read_record will be changed to rr_index in rr_index_first */ info->read_record= reverse ? rr_index_last : rr_index_first; + DBUG_RETURN(error != 0); } diff --git a/sql/records.h b/sql/records.h index 21477d4a30b..a3f0b5eb084 100644 --- a/sql/records.h +++ b/sql/records.h @@ -76,7 +76,7 @@ public: bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors, bool disable_rr_cache); -void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, +bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse); void end_read_record(READ_RECORD *info); diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index caa84d867ad..bff0da26862 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -15,7 +15,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED by later includes #include "rpl_injector.h" #include "transaction.h" #include "sql_parse.h" // begin_trans, end_trans, COMMIT diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 02104af8cd3..216fbde0177 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -17,7 +17,6 @@ #include <my_global.h> // For HAVE_REPLICATION #include "sql_priv.h" #include <my_dir.h> -#include "unireg.h" // REQUIRED by other includes #include "rpl_mi.h" #include "slave.h" // SLAVE_MAX_HEARTBEAT_PERIOD #include "strfunc.h" diff --git a/sql/rpl_record_old.cc b/sql/rpl_record_old.cc index 061fab78dbd..5b876373b9c 100644 --- a/sql/rpl_record_old.cc +++ b/sql/rpl_record_old.cc @@ -15,7 +15,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED by other includes #include "rpl_rli.h" #include "rpl_record_old.h" #include "log_event.h" // Log_event_type diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 679bd152a39..03fef5de866 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2693,7 +2693,8 @@ static int check_alter_user(THD *thd, const char *host, const char *user) } if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier), 1) && - !thd->slave_thread && !thd->security_ctx->priv_user[0]) + !thd->slave_thread && !thd->security_ctx->priv_user[0] && + !in_bootstrap) { my_message(ER_PASSWORD_ANONYMOUS_USER, ER_THD(thd, ER_PASSWORD_ANONYMOUS_USER), @@ -9110,8 +9111,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, So we need to examine the current element once again, but we don't need to restart the search from the beginning. */ - if (idx != elements) - idx++; + idx++; break; } @@ -9143,6 +9143,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair, (uchar*) old_key, old_key_length); + idx++; // see the comment above break; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1189a26f047..90ba0451e30 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6455,6 +6455,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, */ table_name && table_name[0] && (my_strcasecmp(table_alias_charset, table_list->alias, table_name) || + (db_name && db_name[0] && (!table_list->db || !table_list->db[0])) || (db_name && db_name[0] && table_list->db && table_list->db[0] && (table_list->schema_table ? my_strcasecmp(system_charset_info, db_name, table_list->db) : @@ -6928,7 +6929,10 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, for (uint i= 0; (item=li++); i++) { - if (field_name && item->real_item()->type() == Item::FIELD_ITEM) + if (field_name && + (item->real_item()->type() == Item::FIELD_ITEM || + ((item->type() == Item::REF_ITEM) && + (((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)))) { Item_ident *item_field= (Item_ident*) item; @@ -7054,35 +7058,6 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, break; } } - else if (table_name && item->type() == Item::REF_ITEM && - ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF) - { - /* - TODO:Here we process prefixed view references only. What we should - really do is process all types of Item_ref's. But this will currently - lead to a clash with the way references to outer SELECTs (from the - HAVING clause) are handled in e.g. : - SELECT 1 FROM t1 AS t1_o GROUP BY a - HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1). - Processing all Item_ref's here will cause t1_o.a to resolve to itself. - We still need to process the special case of Item_direct_view_ref - because in the context of views they have the same meaning as - Item_field for tables. - */ - Item_ident *item_ref= (Item_ident *) item; - if (field_name && item_ref->name && item_ref->table_name && - !my_strcasecmp(system_charset_info, item_ref->name, field_name) && - !my_strcasecmp(table_alias_charset, item_ref->table_name, - table_name) && - (!db_name || (item_ref->db_name && - !strcmp (item_ref->db_name, db_name)))) - { - found= li.ref(); - *counter= i; - *resolution= RESOLVED_IGNORING_ALIAS; - break; - } - } } if (!found) { diff --git a/sql/sql_base.h b/sql/sql_base.h index 1c0029d9692..3a23e2ea218 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -16,7 +16,6 @@ #ifndef SQL_BASE_INCLUDED #define SQL_BASE_INCLUDED -#include "unireg.h" // REQUIRED: for other includes #include "sql_trigger.h" /* trg_event_type */ #include "sql_class.h" /* enum_mark_columns */ #include "mysqld.h" /* key_map */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1bf48921998..e95e32a5e0b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -30,7 +30,6 @@ #include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_class.h" #include "sql_cache.h" // query_cache_abort #include "sql_base.h" // close_thread_tables diff --git a/sql/sql_class.h b/sql/sql_class.h index 2b62c462abc..aee6d560bfb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -20,16 +20,14 @@ /* Classes in mysql */ -#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ -#ifdef MYSQL_SERVER -#include "unireg.h" // REQUIRED: for other includes -#endif +#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include <waiting_threads.h> #include "sql_const.h" #include <mysql/plugin_audit.h> #include "log.h" #include "rpl_tblmap.h" #include "mdl.h" +#include "field.h" // Create_field #include "probes_mysql.h" #include "sql_locale.h" /* my_locale_st */ #include "sql_profile.h" /* PROFILING */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index f6e37f07e60..7821b96b9bb 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -28,7 +28,6 @@ #include "sql_audit.h" #include "sql_connect.h" #include "probes_mysql.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_parse.h" // sql_command_flags, // execute_init_command, // do_command diff --git a/sql/sql_const.h b/sql/sql_const.h index f856362f4e5..76e47bd278b 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -17,12 +17,14 @@ @file File containing constants that can be used throughout the server. - @note This file shall not contain any includes of any kinds. + @note This file shall not contain or include any declarations of any kinds. */ #ifndef SQL_CONST_INCLUDED #define SQL_CONST_INCLUDED +#include <mysql_version.h> + #define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */ /* extra 4+4 bytes for slave tmp tables */ #define MAX_DBKEY_LENGTH (NAME_LEN*2+1+1+4+4) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8995684b8f6..f49a053918b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -529,17 +529,18 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); DBUG_RETURN(TRUE); } + if (query_plan.index == MAX_KEY || (select && select->quick)) + error= init_read_record(&info, thd, table, select, 1, 1, FALSE); + else + error= init_read_record_idx(&info, thd, table, 1, query_plan.index, + reverse); + if (error) { - if (init_read_record(&info, thd, table, select, 1, 1, FALSE)) - { - delete select; - free_underlaid_joins(thd, select_lex); - DBUG_RETURN(TRUE); - } + delete select; + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); } - else - init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); init_ftfuncs(thd, select_lex, 1); THD_STAGE_INFO(thd, stage_updating); diff --git a/sql/sql_digest.h b/sql/sql_digest.h index ce159283d4d..eaf74b9542e 100644 --- a/sql/sql_digest.h +++ b/sql/sql_digest.h @@ -41,6 +41,9 @@ struct sql_digest_storage For Example: SELECT * FROM T1; <SELECT_TOKEN> <*> <FROM_TOKEN> <ID_TOKEN> <2> <T1> + + @note Only the first @c m_byte_count bytes are initialized, + out of @c m_token_array_length. */ unsigned char *m_token_array; /* Length of the token array to be considered for DIGEST_TEXT calculation. */ @@ -63,10 +66,6 @@ struct sql_digest_storage m_full= false; m_byte_count= 0; m_charset_number= 0; - if (m_token_array_length > 0) - { - memset(m_token_array, 0, m_token_array_length); - } memset(m_md5, 0, MD5_HASH_SIZE); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 47f24ad9cb8..b72d642efbc 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -510,8 +510,10 @@ Diagnostics_area::set_error_status(uint sql_errno, void Diagnostics_area::disable_status() { + DBUG_ENTER("disable_status"); DBUG_ASSERT(! is_set()); m_status= DA_DISABLED; + DBUG_VOID_RETURN; } Warning_info::Warning_info(ulonglong warn_id_arg, diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 05e333e37fc..662fa33dc9f 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -55,7 +55,6 @@ #include <my_global.h> #include "sql_priv.h" #include "sql_handler.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_base.h" // close_thread_tables #include "lock.h" // mysql_unlock_tables #include "key.h" // key_copy diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 574e0892872..7a0a114971d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -58,7 +58,6 @@ #include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_insert.h" #include "sql_update.h" // compare_record #include "sql_base.h" // close_thread_tables diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3c4f99d1a7c..898e3ae33c6 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -20,7 +20,6 @@ #define MYSQL_LEX 1 #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_class.h" // sql_lex.h: SQLCOM_END #include "sql_lex.h" #include "sql_parse.h" // add_to_list @@ -557,6 +556,16 @@ void lex_end(LEX *lex) DBUG_ENTER("lex_end"); DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex)); + lex_end_stage1(lex); + lex_end_stage2(lex); + + DBUG_VOID_RETURN; +} + +void lex_end_stage1(LEX *lex) +{ + DBUG_ENTER("lex_end_stage1"); + /* release used plugins */ if (lex->plugins.elements) /* No function call and no mutex if no plugins. */ { @@ -580,6 +589,19 @@ void lex_end(LEX *lex) lex->sphead= NULL; } + DBUG_VOID_RETURN; +} + +/* + MASTER INFO parameters (or state) is normally cleared towards the end + of a statement. But in case of PS, the state needs to be preserved during + its lifetime and should only be cleared on PS close or deallocation. +*/ +void lex_end_stage2(LEX *lex) +{ + DBUG_ENTER("lex_end_stage2"); + + /* Reset LEX_MASTER_INFO */ lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER); DBUG_VOID_RETURN; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index d39da819513..644d1a19cfd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3119,6 +3119,8 @@ extern void lex_init(void); extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); +extern void lex_end_stage1(LEX *lex); +extern void lex_end_stage2(LEX *lex); void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex); int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex); extern int MYSQLlex(union YYSTYPE *yylval, THD *thd); diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index c6c465aa4e2..8cf849b97d0 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -24,7 +24,6 @@ #include <my_global.h> #include "sql_priv.h" #include "sql_manager.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_base.h" // flush_tables static bool volatile manager_thread_in_use; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6c965cf8359..1388ec01459 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -17,7 +17,6 @@ #define MYSQL_LEX 1 #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_parse.h" // sql_kill, *_precheck, *_prepare #include "lock.h" // try_transactional_lock, // check_transactional_lock, @@ -693,7 +692,7 @@ static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error static void handle_bootstrap_impl(THD *thd) { MYSQL_FILE *file= bootstrap_file; - DBUG_ENTER("handle_bootstrap"); + DBUG_ENTER("handle_bootstrap_impl"); #ifndef EMBEDDED_LIBRARY pthread_detach_this_thread(); @@ -6691,6 +6690,7 @@ bool check_fk_parent_table_access(THD *thd, table_name.str= (char *) thd->memdup(fk_key->ref_table.str, fk_key->ref_table.length+1); table_name.length= my_casedn_str(files_charset_info, table_name.str); + db_name.length = my_casedn_str(files_charset_info, db_name.str); } parent_table.init_one_table(db_name.str, db_name.length, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 8e77d77205c..16588871fd8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -49,7 +49,6 @@ #define MYSQL_LEX 1 #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_partition.h" #include "key.h" // key_restore #include "sql_parse.h" // parse_sql diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2b37cb172aa..dfe6d1c2117 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1419,7 +1419,8 @@ static int mysql_test_update(Prepared_statement *stmt, (SELECT_ACL & ~table_list->table->grant.privilege); table_list->register_want_access(SELECT_ACL); #endif - if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0)) + if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) || + check_unique_table(thd, table_list)) goto error; /* TODO: here we should send types of placeholders to the client. */ DBUG_RETURN(0); @@ -3475,7 +3476,8 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) select_number_after_prepare= thd->select_number; - lex_end(lex); + /* Preserve CHANGE MASTER attributes */ + lex_end_stage1(lex); cleanup_stmt(); thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; @@ -4102,6 +4104,10 @@ void Prepared_statement::deallocate() { /* We account deallocate in the same manner as mysqld_stmt_close */ status_var_increment(thd->status_var.com_stmt_close); + + /* It should now be safe to reset CHANGE MASTER parameters */ + lex_end_stage2(lex); + /* Statement map calls delete stmt on erase */ thd->stmt_map.erase(this); } diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index bc11f5fdb21..48f7987daf5 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -31,7 +31,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_profile.h" #include <my_sys.h> #include "sql_show.h" // schema_table_store_record diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index e6c8e0777b8..7f2cf987f0e 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -94,6 +94,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, my_error(ER_UNKNOWN_ERROR, MYF(0)); } } + opt_noacl= 0; if (tmp_thd) { diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index d9cf0344cdf..17b297f63bd 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -274,8 +274,9 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, LEX_STRING table_name= { ren_table->table_name, ren_table->table_name_length }; LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) }; + LEX_STRING new_db_name= { (char*)new_db, strlen(new_db)}; (void) rename_table_in_stat_tables(thd, &db_name, &table_name, - &db_name, &new_table); + &new_db_name, &new_table); if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, old_alias, ren_table->table_name, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bc5cf2df0ca..3b339368d0a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -492,6 +492,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select, if (ref_pointer_array && !ref->found_in_select_list) { int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= select->ref_pointer_array_size); ref_pointer_array[el]= item; /* Add the field item to the select list of the current select. */ all_fields.push_front(item, thd->mem_root); @@ -907,6 +908,7 @@ JOIN::prepare(Item ***rref_pointer_array, { Item_field *field= new (thd->mem_root) Item_field(thd, *(Item_field**)ord->item); int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= select_lex->ref_pointer_array_size); ref_pointer_array[el]= field; all_fields.push_front(field, thd->mem_root); ord->item= ref_pointer_array + el; @@ -21980,6 +21982,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, return TRUE; /* Wrong field. */ uint el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= + thd->lex->current_select->ref_pointer_array_size); /* Add new field to field list. */ all_fields.push_front(order_item, thd->mem_root); ref_pointer_array[el]= order_item; @@ -22240,6 +22244,8 @@ create_distinct_group(THD *thd, Item **ref_pointer_array, */ Item_field *new_item= new (thd->mem_root) Item_field(thd, (Item_field*)item); int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= + thd->lex->current_select->ref_pointer_array_size); orig_ref_pointer_array[el]= new_item; all_fields.push_front(new_item, thd->mem_root); ord->item= orig_ref_pointer_array + el; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 021e4c37e86..28e76ae43f1 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -592,6 +592,8 @@ public: stat_file->extra(HA_EXTRA_FLUSH); return FALSE; } + + friend class Stat_table_write_iter; }; @@ -888,7 +890,7 @@ public: @note A value from the field min_value/max_value is always converted - into a utf8 string. If the length of the column 'min_value'/'max_value' + into a varbinary string. If the length of the column 'min_value'/'max_value' is less than the length of the string the string is trimmed to fit the length of the column. */ @@ -896,7 +898,7 @@ public: void store_stat_fields() { char buff[MAX_FIELD_WIDTH]; - String val(buff, sizeof(buff), &my_charset_utf8_bin); + String val(buff, sizeof(buff), &my_charset_bin); for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HISTOGRAM; i++) { @@ -913,7 +915,7 @@ public: else { table_field->collected_stats->min_value->val_str(&val); - stat_field->store(val.ptr(), val.length(), &my_charset_utf8_bin); + stat_field->store(val.ptr(), val.length(), &my_charset_bin); } break; case COLUMN_STAT_MAX_VALUE: @@ -922,7 +924,7 @@ public: else { table_field->collected_stats->max_value->val_str(&val); - stat_field->store(val.ptr(), val.length(), &my_charset_utf8_bin); + stat_field->store(val.ptr(), val.length(), &my_charset_bin); } break; case COLUMN_STAT_NULLS_RATIO: @@ -983,7 +985,7 @@ public: if (find_stat()) { char buff[MAX_FIELD_WIDTH]; - String val(buff, sizeof(buff), &my_charset_utf8_bin); + String val(buff, sizeof(buff), &my_charset_bin); for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HIST_TYPE; i++) { @@ -1002,12 +1004,12 @@ public: case COLUMN_STAT_MIN_VALUE: stat_field->val_str(&val); table_field->read_stats->min_value->store(val.ptr(), val.length(), - &my_charset_utf8_bin); + &my_charset_bin); break; case COLUMN_STAT_MAX_VALUE: stat_field->val_str(&val); table_field->read_stats->max_value->store(val.ptr(), val.length(), - &my_charset_utf8_bin); + &my_charset_bin); break; case COLUMN_STAT_NULLS_RATIO: table_field->read_stats->set_nulls_ratio(stat_field->val_real()); @@ -1053,7 +1055,7 @@ public: if (find_stat()) { char buff[MAX_FIELD_WIDTH]; - String val(buff, sizeof(buff), &my_charset_utf8_bin); + String val(buff, sizeof(buff), &my_charset_bin); uint fldno= COLUMN_STAT_HISTOGRAM; Field *stat_field= stat_table->field[fldno]; table_field->read_stats->set_not_null(fldno); @@ -1264,6 +1266,117 @@ public: }; + +/* + An iterator to enumerate statistics table rows which allows to modify + the rows while reading them. + + Used by RENAME TABLE handling to assign new dbname.tablename to statistic + rows. +*/ +class Stat_table_write_iter +{ + Stat_table *owner; + IO_CACHE io_cache; + uchar *rowid_buf; + uint rowid_size; + +public: + Stat_table_write_iter(Stat_table *stat_table_arg) + : owner(stat_table_arg), rowid_buf(NULL), + rowid_size(owner->stat_file->ref_length) + { + my_b_clear(&io_cache); + } + + /* + Initialize the iterator. It will return rows with n_keyparts matching the + curernt values. + + @return false - OK + true - Error + */ + bool init(uint n_keyparts) + { + if (!(rowid_buf= (uchar*)my_malloc(rowid_size, MYF(0)))) + return true; + + if (open_cached_file(&io_cache, mysql_tmpdir, TEMP_PREFIX, + 1024, MYF(MY_WME))) + return true; + + handler *h= owner->stat_file; + uchar key[MAX_KEY_LENGTH]; + uint prefix_len= 0; + for (uint i= 0; i < n_keyparts; i++) + prefix_len += owner->stat_key_info->key_part[i].store_length; + + key_copy(key, owner->record[0], owner->stat_key_info, + prefix_len); + key_part_map prefix_map= (key_part_map) ((1 << n_keyparts) - 1); + h->ha_index_init(owner->stat_key_idx, false); + int res= h->ha_index_read_map(owner->record[0], key, prefix_map, + HA_READ_KEY_EXACT); + if (res) + { + reinit_io_cache(&io_cache, READ_CACHE, 0L, 0, 0); + /* "Key not found" is not considered an error */ + return (res == HA_ERR_KEY_NOT_FOUND)? false: true; + } + + do { + h->position(owner->record[0]); + my_b_write(&io_cache, h->ref, rowid_size); + + } while (!h->ha_index_next_same(owner->record[0], key, prefix_len)); + + /* Prepare for reading */ + reinit_io_cache(&io_cache, READ_CACHE, 0L, 0, 0); + h->ha_index_or_rnd_end(); + if (h->ha_rnd_init(false)) + return true; + + return false; + } + + /* + Read the next row. + + @return + false OK + true No more rows or error. + */ + bool get_next_row() + { + if (!my_b_inited(&io_cache) || my_b_read(&io_cache, rowid_buf, rowid_size)) + return true; /* No more data */ + + handler *h= owner->stat_file; + /* + We should normally be able to find the row that we have rowid for. If we + don't, let's consider this an error. + */ + int res= h->ha_rnd_pos(owner->record[0], rowid_buf); + + return (res==0)? false : true; + } + + void cleanup() + { + if (rowid_buf) + my_free(rowid_buf); + rowid_buf= NULL; + owner->stat_file->ha_index_or_rnd_end(); + close_cached_file(&io_cache); + my_b_clear(&io_cache); + } + + ~Stat_table_write_iter() + { + cleanup(); + } +}; + /* Histogram_builder is a helper class that is used to build histograms for columns @@ -3285,25 +3398,34 @@ int rename_table_in_stat_tables(THD *thd, LEX_STRING *db, LEX_STRING *tab, stat_table= tables[INDEX_STAT].table; Index_stat index_stat(stat_table, db, tab); index_stat.set_full_table_name(); - while (index_stat.find_next_stat_for_prefix(2)) + + Stat_table_write_iter index_iter(&index_stat); + if (index_iter.init(2)) + rc= 1; + while (!index_iter.get_next_row()) { err= index_stat.update_table_name_key_parts(new_db, new_tab); if (err & !rc) rc= 1; index_stat.set_full_table_name(); } + index_iter.cleanup(); /* Rename table in the statistical table column_stats */ stat_table= tables[COLUMN_STAT].table; Column_stat column_stat(stat_table, db, tab); column_stat.set_full_table_name(); - while (column_stat.find_next_stat_for_prefix(2)) + Stat_table_write_iter column_iter(&column_stat); + if (column_iter.init(2)) + rc= 1; + while (!column_iter.get_next_row()) { err= column_stat.update_table_name_key_parts(new_db, new_tab); if (err & !rc) rc= 1; column_stat.set_full_table_name(); } + column_iter.cleanup(); /* Rename table in the statistical table table_stats */ stat_table= tables[TABLE_STAT].table; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 35d736ea8a3..5af13273130 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5848,6 +5848,13 @@ drop_create_field: { if (!key->if_not_exists() && !key->or_replace()) continue; + + /* Check if the table already has a PRIMARY KEY */ + bool dup_primary_key= key->type == Key::PRIMARY && + table->s->primary_key != MAX_KEY; + if (dup_primary_key) + goto remove_key; + /* If the name of the key is not specified, */ /* let us check the name of the first key part. */ if ((keyname= key->name.str) == NULL) @@ -5915,8 +5922,8 @@ remove_key: if (key->if_not_exists()) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_DUP_KEYNAME, ER_THD(thd, ER_DUP_KEYNAME), - keyname); + ER_DUP_KEYNAME, ER_THD(thd, dup_primary_key + ? ER_MULTIPLE_PRI_KEY : ER_DUP_KEYNAME), keyname); key_it.remove(); if (key->type == Key::FOREIGN_KEY) { diff --git a/sql/sql_time.cc b/sql/sql_time.cc index ccba3d16575..9785a1691af 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -19,7 +19,6 @@ #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED by other includes #include "sql_time.h" #include "tztime.h" // struct Time_zone #include "sql_class.h" // THD diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 52892550d35..7dfe8939945 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -17,6 +17,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <mysqld_error.h> + /* Forward declarations */ class Item_trigger_field; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7a66cc3734c..0caae7ac821 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -22,7 +22,6 @@ #include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_update.h" #include "sql_cache.h" // query_cache_* #include "sql_base.h" // close_tables_for_reopen @@ -366,6 +365,9 @@ int mysql_update(THD *thd, DBUG_RETURN(1); /* purecov: inspected */ } + if (check_unique_table(thd, table_list)) + DBUG_RETURN(TRUE); + /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */ if (select_lex->optimize_unflattened_subqueries(false)) DBUG_RETURN(TRUE); @@ -460,7 +462,8 @@ int mysql_update(THD *thd, query_plan.scanned_rows= select? select->records: table->file->stats.records; if (select && select->quick && select->quick->unique_key_range()) - { // Single row select (always "ordered"): Ok to use with key field UPDATE + { + /* Single row select (always "ordered"): Ok to use with key field UPDATE */ need_sort= FALSE; query_plan.index= MAX_KEY; used_key_is_modified= FALSE; @@ -469,7 +472,8 @@ int mysql_update(THD *thd, { ha_rows scanned_limit= query_plan.scanned_rows; query_plan.index= get_index_for_order(order, table, select, limit, - &scanned_limit, &need_sort, &reverse); + &scanned_limit, &need_sort, + &reverse); if (!need_sort) query_plan.scanned_rows= scanned_limit; @@ -482,12 +486,15 @@ int mysql_update(THD *thd, else { if (need_sort) - { // Assign table scan index to check below for modified key fields: + { + /* Assign table scan index to check below for modified key fields: */ query_plan.index= table->file->key_used_on_scan; } if (query_plan.index != MAX_KEY) - { // Check if we are modifying a key that we are used to search with: - used_key_is_modified= is_key_used(table, query_plan.index, table->write_set); + { + /* Check if we are modifying a key that we are used to search with: */ + used_key_is_modified= is_key_used(table, query_plan.index, + table->write_set); } } } @@ -604,19 +611,20 @@ int mysql_update(THD *thd, B. query_plan.index != MAX_KEY B.1 quick select is used, start the scan with init_read_record B.2 quick select is not used, this is full index scan (with LIMIT) - Full index scan must be started with init_read_record_idx + Full index scan must be started with init_read_record_idx */ if (query_plan.index == MAX_KEY || (select && select->quick)) + error= init_read_record(&info, thd, table, select, 0, 1, FALSE); + else + error= init_read_record_idx(&info, thd, table, 1, query_plan.index, + reverse); + + if (error) { - if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) - { - close_cached_file(&tempfile); - goto err; - } + close_cached_file(&tempfile); + goto err; } - else - init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); THD_STAGE_INFO(thd, stage_searching_rows_for_update); ha_rows tmp_limit= limit; @@ -1115,19 +1123,30 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); - /* Check that we are not using table that we are updating in a sub select */ - { - TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) - { - update_non_unique_table_error(table_list, "UPDATE", duplicate); - DBUG_RETURN(TRUE); - } - } select_lex->fix_prepare_information(thd, conds, &fake_conds); DBUG_RETURN(FALSE); } +/** + Check that we are not using table that we are updating in a sub select + + @param thd Thread handle + @param table_list List of table with first to check + + @retval TRUE Error + @retval FALSE OK +*/ +bool check_unique_table(THD *thd, TABLE_LIST *table_list) +{ + TABLE_LIST *duplicate; + DBUG_ENTER("check_unique_table"); + if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) + { + update_non_unique_table_error(table_list, "UPDATE", duplicate); + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} /*************************************************************************** Update multiple tables from join diff --git a/sql/sql_update.h b/sql/sql_update.h index 64029c5d634..4c6f89d8468 100644 --- a/sql/sql_update.h +++ b/sql/sql_update.h @@ -27,6 +27,7 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT; bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order); +bool check_unique_table(THD *thd, TABLE_LIST *table_list); int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, List<Item> &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, diff --git a/sql/sql_view.cc b/sql/sql_view.cc index b240958898c..85189fa481f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1532,6 +1532,11 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, */ lex->sql_command= old_lex->sql_command; lex->duplicates= old_lex->duplicates; + + /* Fields in this view can be used in upper select in case of merge. */ + if (table->select_lex) + table->select_lex->select_n_where_fields+= + lex->select_lex.select_n_where_fields; } /* This method has a dependency on the proper lock type being set, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6f05a2c6d9e..a5a62aeeafb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -35,7 +35,6 @@ #define Select Lex->current_select #include <my_global.h> #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "sql_parse.h" /* comp_*_creator */ #include "sql_table.h" /* primary_key_name */ #include "sql_partition.h" /* mem_alloc_error, partition_info, HASH_PARTITION */ @@ -10909,6 +10908,15 @@ table_factor: sel->add_joined_table($$); lex->pop_context(); lex->nest_level--; + /* + Fields in derived table can be used in upper select in + case of merge. We do not add HAVING fields because we do + not merge such derived. We do not add union because + also do not merge them + */ + if (!sel->next_select()) + $2->select_n_where_fields+= + sel->select_n_where_fields; } /*else if (($3->select_lex && $3->select_lex->master_unit()->is_union() && @@ -15418,6 +15426,9 @@ current_role: grant_role: ident_or_text { + CHARSET_INFO *cs= system_charset_info; + /* trim end spaces (as they'll be lost in mysql.user anyway) */ + $1.length= cs->cset->lengthsp(cs, $1.str, $1.length); if ($1.length == 0) { my_error(ER_INVALID_ROLE, MYF(0), ""); @@ -15433,7 +15444,7 @@ grant_role: if (check_string_char_length(&$$->user, ER_USERNAME, username_char_length, - system_charset_info, 0)) + cs, 0)) MYSQL_YYABORT; } | current_role diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 682d8039478..b3900dd5208 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -839,30 +839,26 @@ static Sys_var_ulong Sys_delayed_queue_size( VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1)); #ifdef HAVE_EVENT_SCHEDULER -static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED", NullS }; +static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED", + "ORIGINAL", NullS }; static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var) { - /* DISABLED is only accepted on the command line */ - if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED) - return true; - /* - If the scheduler was disabled because there are no/bad - system tables, produce a more meaningful error message - than ER_OPTION_PREVENTS_STATEMENT - */ - if (Events::check_if_system_tables_error()) - return true; if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED or --skip-grant-tables"); return true; } + /* DISABLED is only accepted on the command line */ + if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED) + return true; return false; } + static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type) { int err_no= 0; + bool ret; uint opt_event_scheduler_value= Events::opt_event_scheduler; mysql_mutex_unlock(&LOCK_global_system_variables); /* @@ -881,9 +877,25 @@ static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type) rare and it's difficult to avoid it without opening up possibilities for deadlocks. See bug#51160. */ - bool ret= opt_event_scheduler_value == Events::EVENTS_ON - ? Events::start(&err_no) - : Events::stop(); + + /* EVENTS_ORIGINAL means we should revert back to the startup state */ + if (opt_event_scheduler_value == Events::EVENTS_ORIGINAL) + { + opt_event_scheduler_value= Events::opt_event_scheduler= + Events::startup_state; + } + + /* + If the scheduler was not properly inited (because of wrong system tables), + try to init it again. This is needed for mysql_upgrade to work properly if + the event tables where upgraded. + */ + if (!Events::inited && (Events::init(thd, 0) || !Events::inited)) + ret= 1; + else + ret= opt_event_scheduler_value == Events::EVENTS_ON ? + Events::start(&err_no) : + Events::stop(); mysql_mutex_lock(&LOCK_global_system_variables); if (ret) { @@ -3388,7 +3400,7 @@ static char *server_version_compile_machine_ptr; static Sys_var_charptr Sys_version_compile_machine( "version_compile_machine", "version_compile_machine", READ_ONLY GLOBAL_VAR(server_version_compile_machine_ptr), - CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(MACHINE_TYPE)); + CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(DEFAULT_MACHINE)); static char *server_version_compile_os_ptr; static Sys_var_charptr Sys_version_compile_os( diff --git a/sql/table.cc b/sql/table.cc index 9c90e5026b8..6dedd2f8acc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -19,7 +19,6 @@ #include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" -#include "unireg.h" // REQUIRED: for other includes #include "table.h" #include "key.h" // find_ref_key #include "sql_table.h" // build_table_filename, diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 3932712e8bb..23066ae4d6b 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -169,7 +169,7 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.03.0007 July 05, 2015"; + char version[]= "Version 1.03.0007 October 20, 2015"; #if defined(__WIN__) char compver[]= "Version 1.03.0007 " __DATE__ " " __TIME__; char slash= '\\'; @@ -1134,7 +1134,10 @@ PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s) { TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share; - return (tsp) ? tsp->option_struct : NULL; + return (tsp && (!tsp->db_plugin || + !stricmp(plugin_name(tsp->db_plugin)->str, "connect") || + !stricmp(plugin_name(tsp->db_plugin)->str, "partition"))) + ? tsp->option_struct : NULL; } // end of GetTableOptionStruct /****************************************************************************/ @@ -2471,7 +2474,18 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) !(colp[i]= tdbp->ColDB(g, (PSZ)pField->field->field_name, 0))) return NULL; // Column does not belong to this table - if (trace) { + // These types are not yet implemented (buggy) + switch (pField->field->type()) { + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_NEWDATE: + return NULL; + } // endswitch type + + if (trace) { htrc("Field index=%d\n", pField->field->field_index); htrc("Field name=%s\n", pField->field->field_name); } // endif trace @@ -2486,12 +2500,10 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) if (!i && (ismul)) return NULL; - if ((res= pval->val_str(&tmp)) == NULL) - return NULL; // To be clarified - - switch (args[i]->real_type()) { + switch (args[i]->real_type()) { case COND::STRING_ITEM: - pp->Value= PlugSubAllocStr(g, NULL, res->ptr(), res->length()); + res= pval->val_str(&tmp); + pp->Value= PlugSubAllocStr(g, NULL, res->ptr(), res->length()); pp->Type= (pp->Value) ? TYPE_STRING : TYPE_ERROR; break; case COND::INT_ITEM: @@ -2520,8 +2532,8 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) return NULL; } // endswitch type - if (trace) - htrc("Value=%.*s\n", res->length(), res->ptr()); + if (trace) + htrc("Value type=%hd\n", pp->Type); // Append the value to the argument list if (pprec) diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 6aaa048de81..1ccdf231970 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -2360,9 +2360,11 @@ int ODBConn::GetCatInfo(CATPARM *cap) } // endif rc for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { - if (vlen[n] == SQL_NULL_DATA) + if (vlen[n] == SQL_NO_TOTAL) + ThrowDBX("Unexpected SQL_NO_TOTAL returned from SQLFetch"); + else if (vlen[n] == SQL_NULL_DATA) pval[n]->SetNull(true); - else if (crp->Type == TYPE_STRING && vlen[n] != SQL_NULL_DATA) + else if (crp->Type == TYPE_STRING/* && vlen[n] != SQL_NULL_DATA*/) pval[n]->SetValue_char(pbuf[n], vlen[n]); else pval[n]->SetNull(false); diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index 4aa29037dfc..dada5716dbe 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -193,7 +193,8 @@ class DllExport COLDEF : public COLCRT { /* Column description block friend class COLBLK; friend class DBFFAM; friend class TDBASE; - public: + friend class TDBDOS; +public: COLDEF(void); // Constructor // Implementation diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index a1e58ab3344..527fe55dd89 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -2018,7 +2018,8 @@ int TDBDOS::EstimatedLength(void) // result if we set dep to 1 dep = 1 + cdp->GetLong() / 20; // Why 20 ????? } else for (; cdp; cdp = cdp->GetNext()) - dep = MY_MAX(dep, cdp->GetOffset()); + if (!(cdp->Flags & (U_VIRTUAL|U_SPECIAL))) + dep = MY_MAX(dep, cdp->GetOffset()); return (int)dep; } // end of Estimated Length diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index acd548c86ab..55c254f41ea 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -511,29 +511,29 @@ void BINCOL::ReadColumn(PGLOBAL g) switch (Fmt) { case 'X': // Standard not converted values if (Eds && IsTypeChar(Buf_Type)) - Value->SetValue(*(longlong*)p); + Value->SetValueNonAligned<longlong>(p); else Value->SetBinValue(p); break; case 'S': // Short integer - Value->SetValue(*(short*)p); + Value->SetValueNonAligned<short>(p); break; case 'T': // Tiny integer Value->SetValue(*p); break; case 'I': // Integer - Value->SetValue(*(int*)p); + Value->SetValueNonAligned<int>(p); break; case 'G': // Large (great) integer - Value->SetValue(*(longlong*)p); + Value->SetValueNonAligned<longlong>(p); break; case 'F': // Float case 'R': // Real - Value->SetValue((double)*(float*)p); + Value->SetValueNonAligned<float>(p); break; case 'D': // Double - Value->SetValue(*(double*)p); + Value->SetValueNonAligned<double>(p); break; case 'C': // Text if (Value->SetValue_char(p, Long)) { diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index fafba6228b9..211a58f0344 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -755,7 +755,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } else strcpy(To_Line, s); - Row->Clear(); +// Row->Clear(); return false; } else return true; @@ -979,7 +979,8 @@ bool JSONCOL::ParseJpath(PGLOBAL g) if (!stricmp(Name, colp->GetName())) { Nod = colp->Nod; Nodes = colp->Nodes; - goto fin; + Xpd = colp->Xpd; + goto fin; } // endif Name sprintf(g->Message, "Cannot parse updated column %s", Name); @@ -1347,7 +1348,12 @@ PJSON JSONCOL::GetRow(PGLOBAL g) /***********************************************************************/ void JSONCOL::WriteColumn(PGLOBAL g) { - /*********************************************************************/ + if (Xpd && Tjp->Pretty < 2) { + strcpy(g->Message, "Cannot write expanded column when Pretty is not 2"); + longjmp(g->jumper[g->jump_level], 666); + } // endif Xpd + + /*********************************************************************/ /* Check whether this node must be written. */ /*********************************************************************/ if (Value != To_Val) diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index 098ed1ac114..31854870ed2 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -321,10 +321,21 @@ PSZ TDBODBC::GetFile(PGLOBAL g) { if (Connect) { char *p1, *p2; - size_t n; + int i; + size_t n; - if ((p1 = strstr(Connect, "DBQ="))) { - p1 += 4; // Beginning of file name + if (!(p1 = strstr(Connect, "DBQ="))) { + char *p, *lc = strlwr(PlugDup(g, Connect)); + + if ((p = strstr(lc, "database="))) + p1 = Connect + (p - lc); + + i = 9; + } else + i = 4; + + if (p1) { + p1 += i; // Beginning of file name p2 = strchr(p1, ';'); // End of file path/name // Make the File path/name from the connect string diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 03ec0eb8e40..884ce976a52 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -103,6 +103,7 @@ ulonglong CharToNumber(char *p, int n, ulonglong maxval, if (minus) *minus = false; if (rc) *rc = false; + if (n <= 0) return 0LL; // Eliminate leading blanks or 0 for (p2 = p + n; p < p2 && (*p == ' ' || *p == '0'); p++) ; @@ -705,7 +706,7 @@ bool TYPVAL<TYPE>::SetValue_char(char *p, int n) template <> bool TYPVAL<double>::SetValue_char(char *p, int n) { - if (p) { + if (p && n > 0) { char buf[64]; for (; n > 0 && *p == ' '; p++) @@ -1345,7 +1346,7 @@ bool TYPVAL<PSZ>::SetValue_char(char *p, int n) { bool rc; - if (p) { + if (p && n > 0) { rc = n > Len; if ((n = MY_MIN(n, Len))) { @@ -1804,7 +1805,7 @@ bool DECVAL::SetValue_char(char *p, int n) { bool rc; - if (p) { + if (p && n > 0) { rc = n > Len; if ((n = MY_MIN(n, Len))) { @@ -2095,7 +2096,7 @@ bool BINVAL::SetValue_char(char *p, int n) { bool rc; - if (p) { + if (p && n > 0) { rc = n > Clen; Len = MY_MIN(n, Clen); memcpy(Binp, p, Len); @@ -2672,13 +2673,16 @@ bool DTVAL::SetValue_char(char *p, int n) int ndv; int dval[6]; - // Trim trailing blanks - for (p2 = p + n -1; p < p2 && *p2 == ' '; p2--) ; + if (n > 0) { + // Trim trailing blanks + for (p2 = p + n -1; p < p2 && *p2 == ' '; p2--); - if ((rc = (n = p2 - p + 1) > Len)) - n = Len; + if ((rc = (n = p2 - p + 1) > Len)) + n = Len; + + memcpy(Sdate, p, n); + } // endif n - memcpy(Sdate, p, n); Sdate[n] = '\0'; ndv = ExtractDate(Sdate, Pdtp, DefYear, dval); diff --git a/storage/connect/value.h b/storage/connect/value.h index 780917c9962..471da851423 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -116,6 +116,26 @@ class DllExport VALUE : public BLOCK { virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op); virtual bool FormatValue(PVAL vp, char *fmt) = 0; + /** + Set value from a non-aligned in-memory value in the machine byte order. + TYPE can be either of: + - int, short, longlong + - uint, ushort, ulonglong + - float, double + @param - a pointer to a non-aligned value of type TYPE. + */ + template<typename TYPE> + void SetValueNonAligned(const char *p) + { +#if defined(__i386__) || defined(__x86_64__) + SetValue(*((TYPE*) p)); // x86 can cast non-aligned memory directly +#else + TYPE tmp; // a slower version for non-x86 platforms + memcpy(&tmp, p, sizeof(tmp)); + SetValue(tmp); +#endif + } + protected: virtual bool SetConstFormat(PGLOBAL, FORMAT&) = 0; const char *GetXfmt(void); diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc index 6f551b41311..8f027e1b5e0 100644 --- a/storage/federatedx/federatedx_io_mysql.cc +++ b/storage/federatedx/federatedx_io_mysql.cc @@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ha_federatedx.h" #include "m_string.h" +#include "mysqld_error.h" #include "sql_servers.h" #ifdef USE_PRAGMA_IMPLEMENTATION diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index feea3b33c5e..2726f6233ea 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -30,6 +30,20 @@ MYSQL_CHECK_LZMA() MYSQL_CHECK_BZIP2() MYSQL_CHECK_SNAPPY() +IF(CMAKE_CROSSCOMPILING) + # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when + # cross-compiling. Not as precise, but usually good enough. + # This only make sense for atomic tests in this file, this trick doesn't + # work in a general case. + MACRO(CHECK_C_SOURCE SOURCE VAR) + CHECK_C_SOURCE_COMPILES("${SOURCE}" "${VAR}") + ENDMACRO() +ELSE() + MACRO(CHECK_C_SOURCE SOURCE VAR) + CHECK_C_SOURCE_RUNS("${SOURCE}" "${VAR}") + ENDMACRO() +ENDIF() + # OS tests IF(UNIX) IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -71,15 +85,14 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU) IF(NOT MSVC) -# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not -IF(NOT CMAKE_CROSSCOMPILING) + # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not # workaround for gcc 4.1.2 RHEL5/x86, gcc atomic ops only work under -march=i686 IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.1.3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686") ENDIF() - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( " int main() { @@ -110,7 +123,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( " int main() { @@ -126,7 +139,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS_BYTE ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -146,7 +159,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS_64 ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -155,7 +168,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_SYNC_SYNCHRONISE ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -165,7 +178,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_THREAD_FENCE ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -177,7 +190,6 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_TEST_AND_SET ) -ENDIF() IF(HAVE_IB_GCC_ATOMIC_BUILTINS) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1) @@ -203,28 +215,27 @@ IF(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_TEST_AND_SET=1) ENDIF() - # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not -IF(NOT CMAKE_CROSSCOMPILING) - CHECK_C_SOURCE_RUNS( - " - #include <pthread.h> - #include <string.h> +# either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not +CHECK_C_SOURCE( +" +#include <pthread.h> +#include <string.h> - int main() { - pthread_t x1; - pthread_t x2; - pthread_t x3; +int main() { + pthread_t x1; + pthread_t x2; + pthread_t x3; - memset(&x1, 0x0, sizeof(x1)); - memset(&x2, 0x0, sizeof(x2)); - memset(&x3, 0x0, sizeof(x3)); + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); - __sync_bool_compare_and_swap(&x1, x2, x3); + __sync_bool_compare_and_swap(&x1, x2, x3); + + return(0); +}" +HAVE_IB_ATOMIC_PTHREAD_T_GCC) - return(0); - }" - HAVE_IB_ATOMIC_PTHREAD_T_GCC) -ENDIF() IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() @@ -255,7 +266,6 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ADD_DEFINITIONS(-DHAVE_IB_SOLARIS_ATOMICS=1) ENDIF() - IF(NOT CMAKE_CROSSCOMPILING) # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not CHECK_C_SOURCE_COMPILES( " #include <pthread.h> @@ -294,7 +304,7 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") return(0); }" HAVE_IB_MACHINE_BARRIER_SOLARIS) - ENDIF() + IF(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_SOLARIS=1) ENDIF() diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index f900c55792c..8445a45d6a4 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5717,11 +5717,19 @@ buf_print_io_instance( pool_info->pages_written_rate); if (pool_info->n_page_get_delta) { + double hit_rate = ((1000 * pool_info->page_read_delta) + / pool_info->n_page_get_delta); + + if (hit_rate > 1000) { + hit_rate = 1000; + } + + hit_rate = 1000 - hit_rate; + fprintf(file, "Buffer pool hit rate %lu / 1000," " young-making rate %lu / 1000 not %lu / 1000\n", - (ulong) (1000 - (1000 * pool_info->page_read_delta - / pool_info->n_page_get_delta)), + (ulong) hit_rate, (ulong) (1000 * pool_info->young_making_delta / pool_info->n_page_get_delta), (ulong) (1000 * pool_info->not_young_making_delta diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 8f9feaef77e..131b73bafeb 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -4348,13 +4348,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -4363,13 +4363,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -4377,12 +4377,12 @@ dict_foreign_push_index_error( fprintf(ef, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s\n", + "column '%s' on index is defined as NOT NULL near '%s'.\n", operation, create_name, columns[err_col], latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s", + "column '%s' on index is defined as NOT NULL near '%s'.", operation, create_name, columns[err_col], latest_foreign); break; } @@ -4395,13 +4395,13 @@ dict_foreign_push_index_error( table, dict_col_get_no(field->col)); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s\n", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.\n", operation, create_name, columns[err_col], col_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.", operation, create_name, columns[err_col], col_name, latest_foreign); break; } @@ -4735,14 +4735,14 @@ loop: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4779,16 +4779,16 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4808,14 +4808,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4854,14 +4854,14 @@ col_loop1: if (!success || !my_isspace(cs, *ptr)) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4941,13 +4941,13 @@ col_loop1: ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.", + "near '%s'.", operation, create_name, buf, start_of_latest_foreign); mutex_enter(&dict_foreign_err_mutex); dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.\n", + "near '%s'.\n", operation, create_name, buf, start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -4961,14 +4961,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4989,14 +4989,14 @@ col_loop2: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5016,14 +5016,12 @@ col_loop2: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns.\n", + " failed. Parse error in '%s' near '%s'. Referencing column count does not match referenced column count.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns, you have %d when you should have %d.", + " failed. Parse error in '%s' near '%s'. Referencing column count %d does not match referenced column count %d.\n", operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5054,14 +5052,14 @@ scan_on_conditions: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5104,14 +5102,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5132,14 +5130,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -5150,14 +5148,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5178,15 +5176,15 @@ scan_on_conditions: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.\n", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.\n", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5210,13 +5208,13 @@ try_find_index: fprintf(ef, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.\n", + " in '%s' near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.", + " in '%s' near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 454b2be1755..63ed1ff5b35 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -760,6 +760,12 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG}, {"os_log_written", (char*) &export_vars.innodb_os_log_written, SHOW_LONGLONG}, + {"os_merge_buffers_written", + (char*) &export_vars.innodb_merge_buffers_written, SHOW_LONGLONG}, + {"os_merge_buffers_read", + (char*) &export_vars.innodb_merge_buffers_read, SHOW_LONGLONG}, + {"os_merge_buffers_merged", + (char*) &export_vars.innodb_merge_buffers_merged, SHOW_LONGLONG}, {"page_size", (char*) &export_vars.innodb_page_size, SHOW_LONG}, {"pages_created", diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 5964f2c4819..8673a51b10f 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -2,7 +2,7 @@ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2015, 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 @@ -263,6 +263,9 @@ enum monitor_id_t { MONITOR_OVLD_OS_LOG_FSYNC, MONITOR_OVLD_OS_LOG_PENDING_FSYNC, MONITOR_OVLD_OS_LOG_PENDING_WRITES, + MONITOR_MERGE_BLOCKS_WRITTEN, + MONITOR_MERGE_BLOCKS_READ, + MONITOR_MERGE_BLOCKS_MERGED, /* Transaction related counters */ MONITOR_MODULE_TRX, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 2a055058652..add2c6969d5 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -3,7 +3,7 @@ Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2009, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2015, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -174,6 +174,15 @@ struct srv_stats_t { /** Number of system rows inserted */ ulint_ctr_64_t n_system_rows_inserted; + /** Number of merge buffers written */ + ulint_ctr_64_t merge_buffers_written; + + /** Number of merge buffers read */ + ulint_ctr_64_t merge_buffers_read; + + /** Number of merge buffers merged */ + ulint_ctr_64_t merge_buffers_merged; + /** Number of times secondary index lookup triggered cluster lookup */ ulint_ctr_64_t n_sec_rec_cluster_reads; @@ -990,6 +999,9 @@ struct export_var_t{ ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id - purged view's min trx_id */ #endif /* UNIV_DEBUG */ + ib_int64_t innodb_merge_buffers_written; + ib_int64_t innodb_merge_buffers_read; + ib_int64_t innodb_merge_buffers_merged; ib_int64_t innodb_page_compression_saved;/*!< Number of bytes saved by page compression */ diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 0669dfef34f..c921c5b7318 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, MariaDB Corporation. +Copyright (c) 2014, 2015, 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 @@ -971,6 +971,7 @@ row_merge_read( success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, ofs, srv_sort_buf_size); + srv_stats.merge_buffers_read.inc(); /* For encrypted tables, decrypt data after reading and copy data */ if (crypt_data && crypt_buf) { @@ -1026,7 +1027,7 @@ row_merge_write( } ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), out_buf, ofs, buf_len); - + srv_stats.merge_buffers_written.inc(); #ifdef UNIV_DEBUG if (row_merge_print_block_write) { @@ -1909,7 +1910,7 @@ write_buffers: /* We have enough data tuples to form a block. Sort them and write to disk. */ - if (buf->n_tuples) { + if (UNIV_LIKELY(buf->n_tuples)) { if (dict_index_is_unique(buf->index)) { row_merge_dup_t dup = { buf->index, table, col_map, 0}; @@ -1950,13 +1951,18 @@ write_buffers: dict_index_get_lock(buf->index)); } - row_merge_buf_write(buf, file, block); + /* Do not write empty buffers to temporary file */ + if (buf->n_tuples) { - if (!row_merge_write(file->fd, file->offset++, block, - crypt_data, crypt_block, new_table->space)) { - err = DB_TEMP_FILE_WRITE_FAILURE; - trx->error_key_num = i; - break; + row_merge_buf_write(buf, file, block); + + if (!row_merge_write(file->fd, file->offset++, + block, crypt_data, crypt_block, + new_table->space)) { + err = DB_TEMP_FILE_WRITE_FAILURE; + trx->error_key_num = i; + break; + } } UNIV_MEM_INVALID(&block[0], srv_sort_buf_size); @@ -2273,6 +2279,8 @@ done1: b2, of->fd, &of->offset, crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space); + srv_stats.merge_buffers_merged.inc(); + return(b2 ? DB_SUCCESS : DB_CORRUPTION); } @@ -4092,66 +4100,70 @@ wait_again: DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n"); #endif } else { - char buf[3 * NAME_LEN]; - char *bufend; - row_merge_dup_t dup = { - sort_idx, table, col_map, 0}; - - pct_cost = (COST_BUILD_INDEX_STATIC + - (total_dynamic_cost * merge_files[i].offset / - total_index_blocks)) / - (total_static_cost + total_dynamic_cost) - * PCT_COST_MERGESORT_INDEX * 100; - - bufend = innobase_convert_name(buf, sizeof buf, - indexes[i]->name, strlen(indexes[i]->name), - trx ? trx->mysql_thd : NULL, - FALSE); + /* Sorting and inserting is required only if + there really is records */ + if (UNIV_LIKELY(merge_files[i].n_rec)) { + char buf[3 * NAME_LEN]; + char *bufend; + row_merge_dup_t dup = { + sort_idx, table, col_map, 0}; - buf[bufend - buf]='\0'; - - sql_print_information("InnoDB: Online DDL : Start merge-sorting" - " index %s (%lu / %lu), estimated cost : %2.4f", - buf, (i+1), n_indexes, pct_cost); + pct_cost = (COST_BUILD_INDEX_STATIC + + (total_dynamic_cost * merge_files[i].offset / + total_index_blocks)) / + (total_static_cost + total_dynamic_cost) + * PCT_COST_MERGESORT_INDEX * 100; - error = row_merge_sort( - trx, &dup, &merge_files[i], - block, &tmpfd, true, - pct_progress, pct_cost, - crypt_data, crypt_block, new_table->space); + bufend = innobase_convert_name(buf, sizeof buf, + indexes[i]->name, strlen(indexes[i]->name), + trx ? trx->mysql_thd : NULL, + FALSE); - pct_progress += pct_cost; + buf[bufend - buf]='\0'; - sql_print_information("InnoDB: Online DDL : End of " - " merge-sorting index %s (%lu / %lu)", - buf, (i+1), n_indexes); + sql_print_information("InnoDB: Online DDL : Start merge-sorting" + " index %s (%lu / %lu), estimated cost : %2.4f", + buf, (i+1), n_indexes, pct_cost); - DBUG_EXECUTE_IF( - "ib_merge_wait_after_sort", - os_thread_sleep(20000000);); /* 20 sec */ + error = row_merge_sort( + trx, &dup, &merge_files[i], + block, &tmpfd, true, + pct_progress, pct_cost, + crypt_data, crypt_block, new_table->space); - if (error == DB_SUCCESS) { - pct_cost = (COST_BUILD_INDEX_STATIC + - (total_dynamic_cost * merge_files[i].offset / - total_index_blocks)) / - (total_static_cost + total_dynamic_cost) * - PCT_COST_INSERT_INDEX * 100; - - sql_print_information("InnoDB: Online DDL : Start " - "building index %s (%lu / %lu), estimated " - "cost : %2.4f", buf, (i+1), - n_indexes, pct_cost); - - error = row_merge_insert_index_tuples( - trx->id, sort_idx, old_table, - merge_files[i].fd, block, - merge_files[i].n_rec, pct_progress, pct_cost, - crypt_data, crypt_block, new_table->space); pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : " - "End of building index %s (%lu / %lu)", + sql_print_information("InnoDB: Online DDL : End of " + " merge-sorting index %s (%lu / %lu)", buf, (i+1), n_indexes); + + DBUG_EXECUTE_IF( + "ib_merge_wait_after_sort", + os_thread_sleep(20000000);); /* 20 sec */ + + if (error == DB_SUCCESS) { + pct_cost = (COST_BUILD_INDEX_STATIC + + (total_dynamic_cost * merge_files[i].offset / + total_index_blocks)) / + (total_static_cost + total_dynamic_cost) * + PCT_COST_INSERT_INDEX * 100; + + sql_print_information("InnoDB: Online DDL : Start " + "building index %s (%lu / %lu), estimated " + "cost : %2.4f", buf, (i+1), + n_indexes, pct_cost); + + error = row_merge_insert_index_tuples( + trx->id, sort_idx, old_table, + merge_files[i].fd, block, + merge_files[i].n_rec, pct_progress, pct_cost, + crypt_data, crypt_block, new_table->space); + pct_progress += pct_cost; + + sql_print_information("InnoDB: Online DDL : " + "End of building index %s (%lu / %lu)", + buf, (i+1), n_indexes); + } } } diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index d8254c2b8ed..0054070eed5 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -2,7 +2,7 @@ Copyright (c) 2010, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2014, MariaDB Corporation +Copyright (c) 2013, 2015, 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 @@ -715,6 +715,24 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_PENDING_WRITES}, + {"os_merge_blocks_written", "os", + "Number of merge blocks written (innodb_os_merge_blocks_written)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_WRITTEN}, + + {"os_merge_blocks_read", "os", + "Number of merge blocks read (innodb_os_merge_blocks_read)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_READ}, + + {"os_merge_blocks_merged", "os", + "Number of merge blocks merged (innodb_os_merge_blocks_merged)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_MERGED}, + /* ========== Counters for Transaction Module ========== */ {"module_trx", "transaction", "Transaction Manager", MONITOR_MODULE, @@ -1772,6 +1790,21 @@ srv_mon_process_existing_counter( update_min = TRUE; break; + /* innodb_os_merge_blocks_written */ + case MONITOR_MERGE_BLOCKS_WRITTEN: + value = srv_stats.merge_buffers_written; + break; + + /* innodb_os_merge_blocks_read */ + case MONITOR_MERGE_BLOCKS_READ: + value = srv_stats.merge_buffers_read; + break; + + /* innodb_os_merge_blocks_merged */ + case MONITOR_MERGE_BLOCKS_MERGED: + value = srv_stats.merge_buffers_merged; + break; + /* innodb_log_waits */ case MONITOR_OVLD_LOG_WAITS: value = srv_stats.log_waits; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 82346323254..71dd3bab801 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -3,7 +3,7 @@ Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2015, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1645,6 +1645,10 @@ srv_export_innodb_status(void) } #endif /* UNIV_DEBUG */ + export_vars.innodb_merge_buffers_written = srv_stats.merge_buffers_written; + export_vars.innodb_merge_buffers_read = srv_stats.merge_buffers_read; + export_vars.innodb_merge_buffers_merged = srv_stats.merge_buffers_merged; + export_vars.innodb_sec_rec_cluster_reads = srv_stats.n_sec_rec_cluster_reads; export_vars.innodb_sec_rec_cluster_reads_avoided = diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test index 147d9672eae..b5a7f2c860a 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test @@ -41,6 +41,9 @@ SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting"); FLUSH TABLES; # Error ER_CANT_OPEN_FILE syscall error 'repair_test.mrn.0000104' (No such file or directory) +# The (Error 0)[0]" replaces is for Solaris +# +--replace_result "(Error 0)[0]" "(No such file or directory)" --error ER_CANT_OPEN_FILE SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting"); diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index d86da799bee..422197c51fd 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -5106,7 +5106,7 @@ void spider_oracle_handler::create_tmp_bka_table_name( uint adjust_length, length; DBUG_ENTER("spider_oracle_handler::create_tmp_bka_table_name"); if (spider_param_bka_table_name_type(current_thd, - mysql_share->spider_share-> + oracle_share->spider_share-> bka_table_name_types[spider->conn_link_idx[link_idx]]) == 1) { adjust_length = diff --git a/storage/tokudb/ft-index/portability/portability.cc b/storage/tokudb/ft-index/portability/portability.cc index 09c1ccd50be..a6522b3c5b9 100644 --- a/storage/tokudb/ft-index/portability/portability.cc +++ b/storage/tokudb/ft-index/portability/portability.cc @@ -355,9 +355,16 @@ toku_get_processor_frequency_cpuinfo(uint64_t *hzret) { r = get_error_errno(); } else { uint64_t maxhz = 0; - char *buf = NULL; - size_t n = 0; - while (getline(&buf, &n, fp) >= 0) { + /* + Some lines in the "/proc/cpuinfo" output can be long, e.g.: + "flags : fpu vme de pse tsc ms .... smep erms" + In case a line does not fit into "buf", it will be read + in parts by multiple "fgets" calls. This is ok, as + it is very unlikely that a non-leading substring of a line + will match again the pattern "processor: %u". + */ + char buf[512]; + while (fgets(buf, (int) sizeof(buf), fp) != NULL) { unsigned int cpu; sscanf(buf, "processor : %u", &cpu); unsigned int ma, mb; @@ -367,8 +374,6 @@ toku_get_processor_frequency_cpuinfo(uint64_t *hzret) { maxhz = hz; } } - if (buf) - free(buf); fclose(fp); *hzret = maxhz; r = maxhz == 0 ? ENOENT : 0;; diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 1572c3652e0..f95a17cc9b7 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -356,9 +356,23 @@ static int tokudb_init_func(void *p) { tokudb_hton = (handlerton *) p; #if TOKUDB_CHECK_JEMALLOC - if (tokudb_check_jemalloc && dlsym(RTLD_DEFAULT, "mallctl") == NULL) { - sql_print_error("%s is not initialized because jemalloc is not loaded", tokudb_hton_name); - goto error; + if (tokudb_check_jemalloc) { + typedef int (*mallctl_type)(const char *, void *, size_t *, void *, size_t); + mallctl_type mallctl_func; + mallctl_func= (mallctl_type)dlsym(RTLD_DEFAULT, "mallctl"); + if (!mallctl_func) { + sql_print_error("%s is not initialized because jemalloc is not loaded", tokudb_hton_name); + goto error; + } + char *ver; + size_t len= sizeof(ver); + mallctl_func("version", &ver, &len, NULL, 0); + /* jemalloc 2.2.5 crashes mysql-test */ + if (strcmp(ver, "2.3.") < 0) { + sql_print_error("%s is not initialized because jemalloc is older than 2.3.0", tokudb_hton_name); + goto error; + } + } #endif diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index 0ae3528e512..36751fe7273 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -30,6 +30,20 @@ MYSQL_CHECK_LZMA() MYSQL_CHECK_BZIP2() MYSQL_CHECK_SNAPPY() +IF(CMAKE_CROSSCOMPILING) + # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when + # cross-compiling. Not as precise, but usually good enough. + # This only make sense for atomic tests in this file, this trick doesn't + # work in a general case. + MACRO(CHECK_C_SOURCE SOURCE VAR) + CHECK_C_SOURCE_COMPILES("${SOURCE}" "${VAR}") + ENDMACRO() +ELSE() + MACRO(CHECK_C_SOURCE SOURCE VAR) + CHECK_C_SOURCE_RUNS("${SOURCE}" "${VAR}") + ENDMACRO() +ENDIF() + # OS tests IF(UNIX) @@ -76,15 +90,14 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU) IF(NOT MSVC) -# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not -IF(NOT CMAKE_CROSSCOMPILING) + # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not # workaround for gcc 4.1.2 RHEL5/x86, gcc atomic ops only work under -march=i686 IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.1.3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686") ENDIF() - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( " int main() { @@ -115,7 +128,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( " int main() { @@ -131,7 +144,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS_BYTE ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -151,7 +164,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS_64 ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -160,7 +173,7 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_SYNC_SYNCHRONISE ) - CHECK_C_SOURCE_RUNS( + CHECK_C_SOURCE( "#include<stdint.h> int main() { @@ -170,7 +183,6 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_THREAD_FENCE ) -ENDIF() IF(HAVE_IB_GCC_ATOMIC_BUILTINS) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1) @@ -193,28 +205,27 @@ IF(HAVE_IB_GCC_ATOMIC_THREAD_FENCE) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_THREAD_FENCE=1) ENDIF() - # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not -IF(NOT CMAKE_CROSSCOMPILING) - CHECK_C_SOURCE_RUNS( - " - #include <pthread.h> - #include <string.h> +# either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not +CHECK_C_SOURCE( +" +#include <pthread.h> +#include <string.h> - int main() { - pthread_t x1; - pthread_t x2; - pthread_t x3; +int main() { + pthread_t x1; + pthread_t x2; + pthread_t x3; - memset(&x1, 0x0, sizeof(x1)); - memset(&x2, 0x0, sizeof(x2)); - memset(&x3, 0x0, sizeof(x3)); + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); - __sync_bool_compare_and_swap(&x1, x2, x3); + __sync_bool_compare_and_swap(&x1, x2, x3); + + return(0); +}" +HAVE_IB_ATOMIC_PTHREAD_T_GCC) - return(0); - }" - HAVE_IB_ATOMIC_PTHREAD_T_GCC) -ENDIF() IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() @@ -246,7 +257,6 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") SET(XTRADB_OK 1) ENDIF() - IF(NOT CMAKE_CROSSCOMPILING) # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not CHECK_C_SOURCE_COMPILES( " #include <pthread.h> @@ -285,7 +295,7 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") return(0); }" HAVE_IB_MACHINE_BARRIER_SOLARIS) - ENDIF() + IF(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_SOLARIS=1) ENDIF() @@ -462,10 +472,10 @@ SET(INNOBASE_SOURCES ut/ut0wqueue.cc ut/ut0timer.cc) -IF(XTRADB_OK) - MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE - DEFAULT RECOMPILE_FOR_EMBEDDED - LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) -ELSE() +MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE + DEFAULT RECOMPILE_FOR_EMBEDDED + LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) + +IF(TARGET xtradb AND NOT XTRADB_OK) MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform") ENDIF() diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index ef9a791d631..f4136705da8 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -5829,11 +5829,19 @@ buf_print_io_instance( pool_info->pages_written_rate); if (pool_info->n_page_get_delta) { + double hit_rate = ((1000 * pool_info->page_read_delta) + / pool_info->n_page_get_delta); + + if (hit_rate > 1000) { + hit_rate = 1000; + } + + hit_rate = 1000 - hit_rate; + fprintf(file, "Buffer pool hit rate %lu / 1000," " young-making rate %lu / 1000 not %lu / 1000\n", - (ulong) (1000 - (1000 * pool_info->page_read_delta - / pool_info->n_page_get_delta)), + (ulong) hit_rate, (ulong) (1000 * pool_info->young_making_delta / pool_info->n_page_get_delta), (ulong) (1000 * pool_info->not_young_making_delta diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 12278de5aad..3ae334466c6 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -4310,13 +4310,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -4325,13 +4325,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -4339,12 +4339,12 @@ dict_foreign_push_index_error( fprintf(ef, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s\n", + "column '%s' on index is defined as NOT NULL near '%s'.\n", operation, create_name, columns[err_col], latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s", + "column '%s' on index is defined as NOT NULL near '%s'.", operation, create_name, columns[err_col], latest_foreign); break; } @@ -4357,13 +4357,13 @@ dict_foreign_push_index_error( table, dict_col_get_no(field->col)); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s\n", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.\n", operation, create_name, columns[err_col], col_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.", operation, create_name, columns[err_col], col_name, latest_foreign); break; } @@ -4697,14 +4697,14 @@ loop: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4741,16 +4741,16 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4770,14 +4770,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4816,14 +4816,14 @@ col_loop1: if (!success || !my_isspace(cs, *ptr)) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4903,13 +4903,13 @@ col_loop1: ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.", + "near '%s'.", operation, create_name, buf, start_of_latest_foreign); mutex_enter(&dict_foreign_err_mutex); dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.\n", + "near '%s'.\n", operation, create_name, buf, start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -4923,14 +4923,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4951,14 +4951,14 @@ col_loop2: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4978,14 +4978,12 @@ col_loop2: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns.\n", + " failed. Parse error in '%s' near '%s'. Referencing column count does not match referenced column count.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns, you have %d when you should have %d.", + " failed. Parse error in '%s' near '%s'. Referencing column count %d does not match referenced column count %d.\n", operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5016,14 +5014,14 @@ scan_on_conditions: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5066,14 +5064,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5094,14 +5092,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -5112,14 +5110,14 @@ scan_on_conditions: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5140,15 +5138,15 @@ scan_on_conditions: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.\n", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.\n", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -5172,13 +5170,13 @@ try_find_index: fprintf(ef, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.\n", + " in '%s' near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.", + " in '%s' near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 0a2a4884b56..da66a3f1bc6 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5,6 +5,7 @@ Copyright (c) 2013, 2015, MariaDB Corporation. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2012, Facebook Inc. +Copyright (c) 2013, 2015, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -940,6 +941,12 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG}, {"os_log_written", (char*) &export_vars.innodb_os_log_written, SHOW_LONGLONG}, + {"os_merge_buffers_written", + (char*) &export_vars.innodb_merge_buffers_written, SHOW_LONGLONG}, + {"os_merge_buffers_read", + (char*) &export_vars.innodb_merge_buffers_read, SHOW_LONGLONG}, + {"os_merge_buffers_merged", + (char*) &export_vars.innodb_merge_buffers_merged, SHOW_LONGLONG}, {"page_size", (char*) &export_vars.innodb_page_size, SHOW_LONG}, {"pages_created", diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h index 37d14734c71..658cd94d1ec 100644 --- a/storage/xtradb/include/srv0mon.h +++ b/storage/xtradb/include/srv0mon.h @@ -2,7 +2,7 @@ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2015, 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 @@ -263,6 +263,9 @@ enum monitor_id_t { MONITOR_OVLD_OS_LOG_FSYNC, MONITOR_OVLD_OS_LOG_PENDING_FSYNC, MONITOR_OVLD_OS_LOG_PENDING_WRITES, + MONITOR_MERGE_BLOCKS_WRITTEN, + MONITOR_MERGE_BLOCKS_READ, + MONITOR_MERGE_BLOCKS_MERGED, /* Transaction related counters */ MONITOR_MODULE_TRX, diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 45300bc2ded..f863ba9fe5e 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -186,6 +186,13 @@ struct srv_stats_t { /** Number of lock waits that have been up to max time (i.e.) lock wait timeout */ ulint_ctr_1_t n_lock_max_wait_time; + + /** Number of merge buffers written */ + ulint_ctr_64_t merge_buffers_written; + /** Number of merge buffers read */ + ulint_ctr_64_t merge_buffers_read; + /** Number of merge buffers merged */ + ulint_ctr_64_t merge_buffers_merged; }; extern const char* srv_main_thread_op_info; @@ -1202,7 +1209,9 @@ struct export_var_t{ ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id - purged view's min trx_id */ #endif /* UNIV_DEBUG */ - + ib_int64_t innodb_merge_buffers_written; + ib_int64_t innodb_merge_buffers_read; + ib_int64_t innodb_merge_buffers_merged; ib_int64_t innodb_page_compression_saved;/*!< Number of bytes saved by page compression */ diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 7b8787808d9..3ac18eb95d9 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, MariaDB Corporation. +Copyright (c) 2014, 2015, 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 @@ -973,6 +973,7 @@ row_merge_read( success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, ofs, srv_sort_buf_size); + srv_stats.merge_buffers_read.inc(); /* For encrypted tables, decrypt data after reading and copy data */ if (crypt_data && crypt_buf) { @@ -1028,7 +1029,7 @@ row_merge_write( } ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), out_buf, ofs, buf_len); - + srv_stats.merge_buffers_written.inc(); #ifdef UNIV_DEBUG if (row_merge_print_block_write) { @@ -1917,7 +1918,7 @@ write_buffers: /* We have enough data tuples to form a block. Sort them and write to disk. */ - if (buf->n_tuples) { + if (UNIV_LIKELY(buf->n_tuples)) { if (dict_index_is_unique(buf->index)) { row_merge_dup_t dup = { buf->index, table, col_map, 0}; @@ -1958,13 +1959,17 @@ write_buffers: dict_index_get_lock(buf->index)); } - row_merge_buf_write(buf, file, block); + /* Do not write empty buffers to temporary file */ + if (buf->n_tuples) { - if (!row_merge_write(file->fd, file->offset++, block, - crypt_data, crypt_block, new_table->space)) { - err = DB_TEMP_FILE_WRITE_FAILURE; - trx->error_key_num = i; - break; + row_merge_buf_write(buf, file, block); + + if (!row_merge_write(file->fd, file->offset++, block, + crypt_data, crypt_block, new_table->space)) { + err = DB_TEMP_FILE_WRITE_FAILURE; + trx->error_key_num = i; + break; + } } UNIV_MEM_INVALID(&block[0], srv_sort_buf_size); @@ -2278,8 +2283,10 @@ done1: mem_heap_free(heap); b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size], - b2, of->fd, &of->offset, - crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space); + b2, of->fd, &of->offset, + crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space); + + srv_stats.merge_buffers_merged.inc(); return(b2 ? DB_SUCCESS : DB_CORRUPTION); } @@ -4100,66 +4107,70 @@ wait_again: DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n"); #endif } else { - char buf[3 * NAME_LEN]; - char *bufend; - row_merge_dup_t dup = { - sort_idx, table, col_map, 0}; - - pct_cost = (COST_BUILD_INDEX_STATIC + - (total_dynamic_cost * merge_files[i].offset / - total_index_blocks)) / - (total_static_cost + total_dynamic_cost) - * PCT_COST_MERGESORT_INDEX * 100; - - bufend = innobase_convert_name(buf, sizeof buf, - indexes[i]->name, strlen(indexes[i]->name), - trx ? trx->mysql_thd : NULL, - FALSE); + /* Sorting and inserting is required only if + there really is records */ + if (UNIV_LIKELY(merge_files[i].n_rec)) { + char buf[3 * NAME_LEN]; + char *bufend; + row_merge_dup_t dup = { + sort_idx, table, col_map, 0}; - buf[bufend - buf]='\0'; - - sql_print_information("InnoDB: Online DDL : Start merge-sorting" - " index %s (%lu / %lu), estimated cost : %2.4f", - buf, (i+1), n_indexes, pct_cost); + pct_cost = (COST_BUILD_INDEX_STATIC + + (total_dynamic_cost * merge_files[i].offset / + total_index_blocks)) / + (total_static_cost + total_dynamic_cost) + * PCT_COST_MERGESORT_INDEX * 100; - error = row_merge_sort( - trx, &dup, &merge_files[i], - block, &tmpfd, true, - pct_progress, pct_cost, - crypt_data, crypt_block, new_table->space); + bufend = innobase_convert_name(buf, sizeof buf, + indexes[i]->name, strlen(indexes[i]->name), + trx ? trx->mysql_thd : NULL, + FALSE); - pct_progress += pct_cost; + buf[bufend - buf]='\0'; - sql_print_information("InnoDB: Online DDL : End of " - " merge-sorting index %s (%lu / %lu)", - buf, (i+1), n_indexes); + sql_print_information("InnoDB: Online DDL : Start merge-sorting" + " index %s (%lu / %lu), estimated cost : %2.4f", + buf, (i+1), n_indexes, pct_cost); - DBUG_EXECUTE_IF( - "ib_merge_wait_after_sort", - os_thread_sleep(20000000);); /* 20 sec */ + error = row_merge_sort( + trx, &dup, &merge_files[i], + block, &tmpfd, true, + pct_progress, pct_cost, + crypt_data, crypt_block, new_table->space); - if (error == DB_SUCCESS) { - pct_cost = (COST_BUILD_INDEX_STATIC + - (total_dynamic_cost * merge_files[i].offset / - total_index_blocks)) / - (total_static_cost + total_dynamic_cost) * - PCT_COST_INSERT_INDEX * 100; - - sql_print_information("InnoDB: Online DDL : Start " - "building index %s (%lu / %lu), estimated " - "cost : %2.4f", buf, (i+1), - n_indexes, pct_cost); - - error = row_merge_insert_index_tuples( - trx->id, sort_idx, old_table, - merge_files[i].fd, block, - merge_files[i].n_rec, pct_progress, pct_cost, - crypt_data, crypt_block, new_table->space); pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : " - "End of building index %s (%lu / %lu)", + sql_print_information("InnoDB: Online DDL : End of " + " merge-sorting index %s (%lu / %lu)", buf, (i+1), n_indexes); + + DBUG_EXECUTE_IF( + "ib_merge_wait_after_sort", + os_thread_sleep(20000000);); /* 20 sec */ + + if (error == DB_SUCCESS) { + pct_cost = (COST_BUILD_INDEX_STATIC + + (total_dynamic_cost * merge_files[i].offset / + total_index_blocks)) / + (total_static_cost + total_dynamic_cost) * + PCT_COST_INSERT_INDEX * 100; + + sql_print_information("InnoDB: Online DDL : Start " + "building index %s (%lu / %lu), estimated " + "cost : %2.4f", buf, (i+1), + n_indexes, pct_cost); + + error = row_merge_insert_index_tuples( + trx->id, sort_idx, old_table, + merge_files[i].fd, block, + merge_files[i].n_rec, pct_progress, pct_cost, + crypt_data, crypt_block, new_table->space); + pct_progress += pct_cost; + + sql_print_information("InnoDB: Online DDL : " + "End of building index %s (%lu / %lu)", + buf, (i+1), n_indexes); + } } } diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc index 0b2e29e5f68..597e7cadc6a 100644 --- a/storage/xtradb/srv/srv0mon.cc +++ b/storage/xtradb/srv/srv0mon.cc @@ -2,7 +2,7 @@ Copyright (c) 2010, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2014, MariaDB Corporation +Copyright (c) 2013, 2015, 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 @@ -715,6 +715,24 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_PENDING_WRITES}, + {"os_merge_blocks_written", "os", + "Number of merge blocks written (innodb_os_merge_blocks_written)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_WRITTEN}, + + {"os_merge_blocks_read", "os", + "Number of merge blocks read (innodb_os_merge_blocks_read)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_READ}, + + {"os_merge_blocks_merged", "os", + "Number of merge blocks merged (innodb_os_merge_blocks_merged)", + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_MERGED}, + /* ========== Counters for Transaction Module ========== */ {"module_trx", "transaction", "Transaction Manager", MONITOR_MODULE, @@ -1772,6 +1790,21 @@ srv_mon_process_existing_counter( update_min = TRUE; break; + /* innodb_os_merge_blocks_written */ + case MONITOR_MERGE_BLOCKS_WRITTEN: + value = srv_stats.merge_buffers_written; + break; + + /* innodb_os_merge_blocks_read */ + case MONITOR_MERGE_BLOCKS_READ: + value = srv_stats.merge_buffers_read; + break; + + /* innodb_os_merge_blocks_merged */ + case MONITOR_MERGE_BLOCKS_MERGED: + value = srv_stats.merge_buffers_merged; + break; + /* innodb_log_waits */ case MONITOR_OVLD_LOG_WAITS: value = srv_stats.log_waits; diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index b816d7e90ca..fa5900ec60e 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -2030,6 +2030,10 @@ srv_export_innodb_status(void) } #endif /* UNIV_DEBUG */ + export_vars.innodb_merge_buffers_written = srv_stats.merge_buffers_written; + export_vars.innodb_merge_buffers_read = srv_stats.merge_buffers_read; + export_vars.innodb_merge_buffers_merged = srv_stats.merge_buffers_merged; + export_vars.innodb_sec_rec_cluster_reads = srv_stats.n_sec_rec_cluster_reads; export_vars.innodb_sec_rec_cluster_reads_avoided = diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 6e1784fe530..703d5444718 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -119,12 +119,6 @@ mode=$1 # start or stop [ $# -ge 1 ] && shift - -other_args="$*" # uncommon, but needed when called from an RPM upgrade action - # Expected: "--skip-networking --skip-grant-tables" - # They are not checked here, intentionally, as it is the resposibility - # of the "spec" file author to give correct arguments only. - case `echo "testing\c"`,`echo -n testing` in *c*,-n*) echo_n= echo_c= ;; *c*,*) echo_n=-n echo_c= ;; @@ -216,6 +210,7 @@ else fi parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server` +parse_server_arguments "$@" # wait for the pid file to disappear wait_for_gone () { @@ -313,7 +308,7 @@ case "$mode" in then # Give extra arguments to mysqld with the my.cnf file. This script # may be overwritten at next upgrade. - $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & + $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" "$@" >/dev/null 2>&1 & wait_for_ready; return_value=$? # Make lock for RedHat / SuSE @@ -361,8 +356,8 @@ case "$mode" in 'restart') # Stop the service and regardless of whether it was # running or not, start it again. - if $0 stop $other_args; then - if ! $0 start $other_args; then + if $0 stop "$@"; then + if ! $0 start "$@"; then log_failure_msg "Failed to restart server." exit 1 fi diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 33c6cffe323..0535a486d57 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -17,17 +17,17 @@ IF(NOT WIN32) RETURN() ENDIF() +IF(MSVC_VERSION LESS 1600) + RETURN() +ENDIF() + + + SET(MANUFACTURER "MariaDB Corporation Ab") FIND_PATH(WIX_DIR heat.exe - $ENV{WIX_DIR}/bin - $ENV{ProgramFiles}/wix/bin - "$ENV{ProgramFiles}/Windows Installer XML v3/bin" - "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" - "$ENV{ProgramFiles}/Windows Installer XML v3.6/bin" "$ENV{ProgramFiles}/WiX Toolset v3.9/bin" - "$ENV{WIX}/bin" + "$ENV{ProgramFiles}/WiX Toolset v3.10/bin" ) - SET(CPACK_WIX_PACKAGE_BASE_NAME "MariaDB") IF(CMAKE_SIZEOF_VOID_P EQUAL 4) SET(CPACK_WIX_UPGRADE_CODE "49EB7A6A-1CEF-4A1E-9E89-B9A4993963E3") @@ -37,16 +37,42 @@ ELSE() SET(CPACK_WIX_PACKAGE_NAME "MariaDB ${MAJOR_VERSION}.${MINOR_VERSION} (x64)") ENDIF() +IF(WIX_DIR) +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(WIX_ARCH_SUFFIX "x64") +ELSE() + SET(WIX_ARCH_SUFFIX "x86") +ENDIF() +# Need some Wix SDK libraries to link with customaction +IF(MSVC_VERSION EQUAL 1600 OR MSVC_VERSION EQUAL 1700 ) + SET(WIX_MSVC_SUFFIX "VS2010") +ELSEIF(MSVC_VERSION EQUAL 1800) + SET(WIX_MSVC_SUFFIX "VS2013") +ELSEIF (MSVC_VERSION EQUAL 1900) + SET(WIX_MSVC_SUFFIX "VS2015") +ENDIF() + + +FIND_LIBRARY(WIX_WCAUTIL_LIBRARY + NAMES wcautil${WIX_ARCH_SUFFIX} wcautil${WIX_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + wcautil + PATHS + ${WIX_DIR}/../SDK/${WIX_MSVC_SUFFIX}/lib/${WIX_ARCH_SUFFIX} + ) + +FIND_LIBRARY(WIX_DUTIL_LIBRARY + NAMES dutil${WIX_ARCH_SUFFIX} + dutil + PATHS + ${WIX_DIR}/../SDK/${WIX_MSVC_SUFFIX}/lib/${WIX_ARCH_SUFFIX} + ) +ENDIF() -IF(NOT WIX_DIR) - IF(NOT _WIX_DIR_CHECKED) - SET(_WIX_DIR_CHECKED 1 CACHE INTERNAL "") - MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") - IF(BUILD_RELEASE) +IF(NOT WIX_DUTIL_LIBRARY) + MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") + IF(BUILD_RELEASE) MESSAGE(FATAL_ERROR - "Can't find Wix. It is necessary for producing official package" - ) - ENDIF() + "Can't find Wix. It is necessary for producing official package") ENDIF() RETURN() ENDIF() diff --git a/win/packaging/ca/CMakeLists.txt b/win/packaging/ca/CMakeLists.txt index ccd03130d69..c57ae4b2113 100644 --- a/win/packaging/ca/CMakeLists.txt +++ b/win/packaging/ca/CMakeLists.txt @@ -13,53 +13,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) -LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) - +INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/${WIX_MSVC_SUFFIX}/inc) SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) -IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(WIX_ARCH_SUFFIX "_x64") - SET(WIX36_ARCH_SUFFIX "x64") -ELSE() - SET(WIX_ARCH_SUFFIX) - SET(WIX36_ARCH_SUFFIX "x86") -ENDIF() - -IF(MSVC_VERSION EQUAL 1400) - SET(WIX35_MSVC_SUFFIX "_2005") -ELSEIF(MSVC_VERSION EQUAL 1500) - SET(WIX35_MSVC_SUFFIX "_2008") - SET(WIX36_MSVC_SUFFIX "VS2008") -ELSEIF(MSVC_VERSION EQUAL 1600 OR MSVC_VERSION EQUAL 1700 ) - SET(WIX35_MSVC_SUFFIX "_2010") - SET(WIX36_MSVC_SUFFIX "VS2010") -ELSEIF(MSVC_VERSION EQUAL 1800 OR MSVC_VERSION EQUAL 1900 ) - SET(WIX35_MSVC_SUFFIX "_2013") - SET(WIX36_MSVC_SUFFIX "VS2013") -ELSE() - # When next VS is out, add the correct version here - MESSAGE(FATAL_ERROR "Unknown VS version") -ENDIF() -INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/${WIX36_MSVC_SUFFIX}/inc) -FIND_LIBRARY(WIX_WCAUTIL_LIBRARY - NAMES wcautil${WIX_ARCH_SUFFIX} wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} - wcautil - PATHS - ${WIX_DIR}/../SDK/lib - ${WIX_DIR}/../SDK/${WIX36_MSVC_SUFFIX}/lib/${WIX36_ARCH_SUFFIX} - ) -FIND_LIBRARY(WIX_DUTIL_LIBRARY - NAMES dutil${WIX_ARCH_SUFFIX} dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} - dutil - PATHS - ${WIX_DIR}/../SDK/lib - ${WIX_DIR}/../SDK/${WIX36_MSVC_SUFFIX}/lib/${WIX36_ARCH_SUFFIX} - ) ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES}) |