From c06138e46d6ee789cc9cbdd0f8ed8c5f4cfbc4fb Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 11 Jan 2016 15:00:44 +0100 Subject: [PATCH 01/52] Raise version number after cloning 5.5.48 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4bf30e8600e..ba54e70bc3e 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=48 +MYSQL_VERSION_PATCH=49 MYSQL_VERSION_EXTRA= From 79032a7ae1b4e000028a64ab0d2f216d4c23767b Mon Sep 17 00:00:00 2001 From: Shaohua Wang Date: Tue, 12 Jan 2016 15:08:09 +0800 Subject: [PATCH 02/52] BUG#22530768 Innodb freeze running REPLACE statements we can see from the hang stacktrace, srv_monitor_thread is blocked when getting log_sys::mutex, so that sync_arr_wake_threads_if_sema_free cannot get a change to break the mutex deadlock. The fix is simply removing any mutex wait in srv_monitor_thread. Patch is reviewed by Sunny over IM. --- storage/innobase/buf/buf0flu.c | 7 +++++-- storage/innobase/srv/srv0srv.c | 31 ++++++++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 7abd014a364..d15f2e4601e 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2103,7 +2103,10 @@ buf_flush_stat_update(void) ib_uint64_t lsn; ulint n_flushed; - lsn = log_get_lsn(); + if (!log_peek_lsn(&lsn)) { + return; + } + if (buf_flush_stat_cur.redo == 0) { /* First time around. Just update the current LSN and return. */ diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 573488bebca..f42a4a37c80 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -2413,6 +2413,8 @@ exit_func: /*********************************************************************//** A thread which prints warnings about semaphore waits which have lasted too long. These can be used to track bugs which cause hangs. +Note: In order to make sync_arr_wake_threads_if_sema_free work as expected, +we should avoid waiting any mutexes in this function! @return a dummy parameter */ UNIV_INTERN os_thread_ret_t @@ -2450,23 +2452,22 @@ loop: /* Try to track a strange bug reported by Harald Fuchs and others, where the lsn seems to decrease at times */ + if (log_peek_lsn(&new_lsn)) { + if (new_lsn < old_lsn) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: old log sequence number %llu" + " was greater\n" + "InnoDB: than the new log sequence number %llu!\n" + "InnoDB: Please submit a bug report" + " to http://bugs.mysql.com\n", + old_lsn, new_lsn); + ut_ad(0); + } - new_lsn = log_get_lsn(); - - if (new_lsn < old_lsn) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: old log sequence number %llu" - " was greater\n" - "InnoDB: than the new log sequence number %llu!\n" - "InnoDB: Please submit a bug report" - " to http://bugs.mysql.com\n", - old_lsn, new_lsn); - ut_ad(0); + old_lsn = new_lsn; } - old_lsn = new_lsn; - if (difftime(time(NULL), srv_last_monitor_time) > 60) { /* We referesh InnoDB Monitor values so that averages are printed from at most 60 last seconds */ From 95825fa28a7e84a2f5dbdef5241078f7055c5b04 Mon Sep 17 00:00:00 2001 From: Knut Anders Hatlen Date: Thu, 7 Jan 2016 12:53:18 +0100 Subject: [PATCH 03/52] Bug#21682356: STOP INJECTING DATA ITEMS IN AN ERROR MESSAGE GENERATED BY THE EXP() FUNCTION When generating the error message for numeric overflow, pass a flag to Item::print() that prevents it from expanding constant expressions and parameters to the values they evaluate to. For consistency, also pass the flag to Item::print() when Item_func_spatial_collection::fix_length_and_dec() generates an error message. It doesn't make any difference at the moment, since constant expressions haven't been evaluated yet when this function is called. --- mysql-test/r/func_math.result | 4 ++-- sql/item.cc | 7 +++--- sql/item_func.h | 4 ++-- sql/item_geofunc.h | 4 ++-- sql/mysqld.h | 10 +++++++-- sql/sql_select.cc | 40 ++++++++++++++++++++++++++--------- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index ec0ca748c49..8a505d8bb9d 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -632,9 +632,9 @@ ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 DIV CREATE TABLE t1(a BIGINT, b BIGINT UNSIGNED); INSERT INTO t1 VALUES(-9223372036854775808, 9223372036854775809); SELECT -a FROM t1; -ERROR 22003: BIGINT value is out of range in '-('-9223372036854775808')' +ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`a`)' SELECT -b FROM t1; -ERROR 22003: BIGINT value is out of range in '-('9223372036854775809')' +ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`b`)' DROP TABLE t1; SET @a:=999999999999999999999999999999999999999999999999999999999999999999999999999999999; SELECT @a + @a; diff --git a/sql/item.cc b/sql/item.cc index beb68c5d321..5f02b96e59f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3456,7 +3456,7 @@ Item_param::eq(const Item *arg, bool binary_cmp) const void Item_param::print(String *str, enum_query_type query_type) { - if (state == NO_VALUE) + if (state == NO_VALUE || query_type & QT_NO_DATA_EXPANSION) { str->append('?'); } @@ -6197,7 +6197,8 @@ Item *Item_field::update_value_transformer(uchar *select_arg) void Item_field::print(String *str, enum_query_type query_type) { - if (field && field->table->const_table) + if (field && field->table->const_table && + !(query_type & QT_NO_DATA_EXPANSION)) { char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff),str->charset()); diff --git a/sql/item_func.h b/sql/item_func.h index fc9fa4a65fb..6c83bc179f2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,7 +1,7 @@ #ifndef ITEM_FUNC_INCLUDED #define ITEM_FUNC_INCLUDED -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -217,7 +217,7 @@ public: char buf[256]; String str(buf, sizeof(buf), system_charset_info); str.length(0); - print(&str, QT_ORDINARY); + print(&str, QT_NO_DATA_EXPANSION); my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe()); } inline double raise_float_overflow() diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 903257525f9..fe7ccf10fcc 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -1,7 +1,7 @@ #ifndef ITEM_GEOFUNC_INCLUDED #define ITEM_GEOFUNC_INCLUDED -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -187,7 +187,7 @@ public: if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY) { String str; - args[i]->print(&str, QT_ORDINARY); + args[i]->print(&str, QT_NO_DATA_EXPANSION); str.append('\0'); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric", str.ptr()); diff --git a/sql/mysqld.h b/sql/mysqld.h index 0253c2a0b43..ee9f8c64840 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -431,7 +431,13 @@ enum enum_query_type /// In utf8. QT_TO_SYSTEM_CHARSET= (1 << 0), /// Without character set introducers. - QT_WITHOUT_INTRODUCERS= (1 << 1) + QT_WITHOUT_INTRODUCERS= (1 << 1), + /** + If an expression is constant, print the expression, not the value + it evaluates to. Should be used for error messages, so that they + don't reveal values. + */ + QT_NO_DATA_EXPANSION= (1 << 9), }; /* query_id */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 96271f26b0f..b5ecebdadc8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17427,26 +17427,46 @@ static void print_join(THD *thd, /* List is reversed => we should reverse it before using */ List_iterator_fast ti(*tables); TABLE_LIST **table; - uint non_const_tables= 0; + + /* + If the QT_NO_DATA_EXPANSION flag is specified, we print the + original table list, including constant tables that have been + optimized away, as the constant tables may be referenced in the + expression printed by Item_field::print() when this flag is given. + Otherwise, only non-const tables are printed. + + Example: + + Original SQL: + select * from (select 1) t + + Printed without QT_NO_DATA_EXPANSION: + select '1' AS `1` from dual + + Printed with QT_NO_DATA_EXPANSION: + select `t`.`1` from (select 1 AS `1`) `t` + */ + const bool print_const_tables= (query_type & QT_NO_DATA_EXPANSION); + size_t tables_to_print= 0; for (TABLE_LIST *t= ti++; t ; t= ti++) - if (!t->optimized_away) - non_const_tables++; - if (!non_const_tables) + if (print_const_tables || !t->optimized_away) + tables_to_print++; + if (tables_to_print == 0) { str->append(STRING_WITH_LEN("dual")); return; // all tables were optimized away } ti.rewind(); - if (!(table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) * - non_const_tables))) + if (!(table= static_cast(thd->alloc(sizeof(TABLE_LIST*) * + tables_to_print)))) return; // out of memory - TABLE_LIST *tmp, **t= table + (non_const_tables - 1); + TABLE_LIST *tmp, **t= table + (tables_to_print - 1); while ((tmp= ti++)) { - if (tmp->optimized_away) + if (tmp->optimized_away && !print_const_tables) continue; *t--= tmp; } @@ -17454,7 +17474,7 @@ static void print_join(THD *thd, DBUG_ASSERT(tables->elements >= 1); (*table)->print(thd, str, query_type); - TABLE_LIST **end= table + non_const_tables; + TABLE_LIST **end= table + tables_to_print; for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) { TABLE_LIST *curr= *tbl; From 7d19d4b2dd692deb38d230e64d3c4c3b64570ad6 Mon Sep 17 00:00:00 2001 From: Deepthi Eranti_Sreenivas Date: Wed, 20 Jan 2016 18:23:16 +0530 Subject: [PATCH 04/52] Bug#22086528 : TEST CODE DISABLED THOUGH THE HISTORIC REASONS - BUGS - ARE FIXED Problem: mysql-test/suite/rpl/t/rpl_killed_ddl.test This test contains code which was disabled because of certain bugs. BUG#44041 declared to be a duplicate of Bug#45516 which was fixed 2010 BUG#43353 fixed 2012 BUG#44171 fixed 2010 Fix: Enabled the test code related to the above mentioned bugs. --- mysql-test/suite/rpl/r/rpl_killed_ddl.result | 14 +++++++ mysql-test/suite/rpl/t/rpl_killed_ddl.test | 43 +++++++------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_killed_ddl.result b/mysql-test/suite/rpl/r/rpl_killed_ddl.result index a02c9b599bf..4d9f8b77735 100644 --- a/mysql-test/suite/rpl/r/rpl_killed_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_killed_ddl.result @@ -56,6 +56,10 @@ CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100; CREATE DATABASE d2; source include/kill_query.inc; include/rpl_diff.inc +ALTER DATABASE d1 +DEFAULT CHARACTER SET = 'utf8'; +source include/kill_query.inc; +include/rpl_diff.inc DROP DATABASE d1; source include/kill_query.inc; include/rpl_diff.inc @@ -67,6 +71,10 @@ ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY DO INSERT INTO test.t1 VALUES (2); source include/kill_query.inc; include/rpl_diff.inc +ALTER EVENT e1 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; +source include/kill_query.inc; +include/rpl_diff.inc DROP EVENT e1; source include/kill_query.inc; include/rpl_diff.inc @@ -83,6 +91,9 @@ include/rpl_diff.inc DROP FUNCTION f1; source include/kill_query.inc; include/rpl_diff.inc +DROP FUNCTION IF EXISTS f2; +source include/kill_query.inc; +include/rpl_diff.inc CREATE PROCEDURE p2 (OUT rows INT) BEGIN SELECT COUNT(*) INTO rows FROM t2; @@ -96,6 +107,9 @@ include/rpl_diff.inc DROP PROCEDURE p1; source include/kill_query.inc; include/rpl_diff.inc +DROP PROCEDURE IF EXISTS p2; +source include/kill_query.inc; +include/rpl_diff.inc CREATE TABLE t2 (b int); source include/kill_query.inc; include/rpl_diff.inc diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index a56a39a2784..76e9b3af091 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -26,10 +26,7 @@ # # There are some part of the test are temporarily disabled because of # the following bugs, please enable then once they get fixed: -# - BUG#44041 -# - BUG#43353 -# - BUG#25705 -# - BUG#44171 +# - BUG#22473427 source include/have_debug.inc; source include/master-slave.inc; @@ -145,11 +142,9 @@ let $rpl_diff_statement= SELECT schema_name FROM information_schema.schemata send CREATE DATABASE d2; source include/kill_query_and_diff_master_slave.inc; -# Temporarily disabled, see BUG#44041, the ALTER DATABASE can affect the -# collation of other database on slave -#send ALTER DATABASE d1 -# DEFAULT CHARACTER SET = 'utf8'; -#source include/kill_query_and_diff_master_slave.inc; +send ALTER DATABASE d1 + DEFAULT CHARACTER SET = 'utf8'; +source include/kill_query_and_diff_master_slave.inc; send DROP DATABASE d1; source include/kill_query_and_diff_master_slave.inc; @@ -168,11 +163,9 @@ send CREATE EVENT e2 DO INSERT INTO test.t1 VALUES (2); source include/kill_query_and_diff_master_slave.inc; -# Temporarily disabled because of BUG#44171, killing ALTER EVENT can -# crash the server -#send ALTER EVENT e1 -# ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; -#source include/kill_query_and_diff_master_slave.inc; +send ALTER EVENT e1 + ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; +source include/kill_query_and_diff_master_slave.inc; send DROP EVENT e1; source include/kill_query_and_diff_master_slave.inc; @@ -198,16 +191,8 @@ source include/kill_query_and_diff_master_slave.inc; # function f2 probably does not exist because the CREATE query was # killed -# -# Temporarily disabled. Because of BUG#43353, KILL the query may -# result in function not found, and for 5.1, DROP statements will be -# logged if the function is not found on master, so the following DROP -# FUNCTION statement may be interrupted and not drop the function on -# master, but still get logged and executed on slave and cause -# inconsistence. Also disable the following DROP PROCEDURE IF EXITS -# below. -#send DROP FUNCTION IF EXISTS f2; -#source include/kill_query_and_diff_master_slave.inc; +send DROP FUNCTION IF EXISTS f2; +source include/kill_query_and_diff_master_slave.inc; ######## PROCEDURE ######## @@ -228,9 +213,8 @@ source include/kill_query_and_diff_master_slave.inc; send DROP PROCEDURE p1; source include/kill_query_and_diff_master_slave.inc; -# Temporarily disabled because of bug#43353, see comment above for DROP FUNCTION IF EXISTS -#send DROP PROCEDURE IF EXISTS p2; -#source include/kill_query_and_diff_master_slave.inc; +send DROP PROCEDURE IF EXISTS p2; +source include/kill_query_and_diff_master_slave.inc; ######## TABLE ######## @@ -258,9 +242,10 @@ source include/kill_query_and_diff_master_slave.inc; ######## SERVER ######## -# Tempoarily disabled, see bug#25705 +# Temporarily disabled, see Bug #22473427 - DROP SERVER FAILS +# AFTER ALTER SERVER+KILL QUERY -# --let $rpl_diff_statement= SELECT * FROM mysql.server WHERE name like \'s%\' +# --let $rpl_diff_statement= SELECT * FROM mysql.servers WHERE Server_name like \'s%\' # send CREATE SERVER s2 # FOREIGN DATA WRAPPER mysql From 1624c26d429171c33ad33613e73bba23a5a3cbdd Mon Sep 17 00:00:00 2001 From: Deepthi Eranti_Sreenivas Date: Fri, 22 Jan 2016 16:51:21 +0530 Subject: [PATCH 05/52] Bug#22086528: TEST CODE DISABLED THOUGH THE HISTORIC REASONS - BUGS - ARE FIXED Post push fix for 5.5 and 5.6.Disabled the test code due to Bug#22587377 --- mysql-test/suite/rpl/r/rpl_killed_ddl.result | 4 ---- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 9 ++++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_killed_ddl.result b/mysql-test/suite/rpl/r/rpl_killed_ddl.result index 4d9f8b77735..ed8745ca2c1 100644 --- a/mysql-test/suite/rpl/r/rpl_killed_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_killed_ddl.result @@ -71,10 +71,6 @@ ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY DO INSERT INTO test.t1 VALUES (2); source include/kill_query.inc; include/rpl_diff.inc -ALTER EVENT e1 -ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; -source include/kill_query.inc; -include/rpl_diff.inc DROP EVENT e1; source include/kill_query.inc; include/rpl_diff.inc diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 76e9b3af091..e9f5a5c47c2 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -27,6 +27,7 @@ # There are some part of the test are temporarily disabled because of # the following bugs, please enable then once they get fixed: # - BUG#22473427 +# - Bug#22587377 source include/have_debug.inc; source include/master-slave.inc; @@ -163,9 +164,11 @@ send CREATE EVENT e2 DO INSERT INTO test.t1 VALUES (2); source include/kill_query_and_diff_master_slave.inc; -send ALTER EVENT e1 - ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; -source include/kill_query_and_diff_master_slave.inc; +# Temporarily disabled,see Bug#22587377-RPL.RPL_KILLED_DDL +# FAILS SPORADICALLY ON PB2 IN 5.5 AND 5.6 +#send ALTER EVENT e1 +# ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; +#source include/kill_query_and_diff_master_slave.inc; send DROP EVENT e1; source include/kill_query_and_diff_master_slave.inc; From a204ce5b3f42e6bdc95eac87acff58214bac415f Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 26 Jan 2016 09:18:10 +0100 Subject: [PATCH 06/52] Bug#21770366 backport bug#21657078 to 5.5 and 5.6 Post-push fix: The problem was that condition variable timeouts could in some cases (slow machines and/or short timeouts) be infinite. When the number of milliseconds to wait is computed, the end time is computed before the now() time. This can result in the now() time being later than the end time, leading to negative timeout. Which after conversion to unsigned becomes ~infinite. This patch fixes the problem by explicitly checking if we get negative timeout and then using 0 if this is the case. --- mysys/my_wincond.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c index 567721baf27..cfb05272a6e 100644 --- a/mysys/my_wincond.c +++ b/mysys/my_wincond.c @@ -127,8 +127,12 @@ static DWORD get_milliseconds(const struct timespec *abstime) if (abstime == NULL) return INFINITE; - return (DWORD)(abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000 - - my_getsystime() / 10000); + ulonglong future= abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; + ulonglong now= my_getsystime() / 10000; + /* Don't allow the timeout to be negative. */ + if (future < now) + return 0; + return (DWORD)(future - now); #endif } From 93e6f388860490a6066cc07253a6aab94029e502 Mon Sep 17 00:00:00 2001 From: Shaohua Wang Date: Wed, 27 Jan 2016 09:40:02 +0800 Subject: [PATCH 07/52] Followup:BUG#22530768 Innodb freeze running REPLACE statements Go back to __sync_* operations in TAS on x86. Patch is reviewed by Sunny over IM. --- storage/innobase/include/os0sync.h | 46 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 07628409192..ad661355783 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -318,28 +318,7 @@ amount of increment. */ # define os_atomic_increment_ulint(ptr, amount) \ os_atomic_increment(ptr, amount) -# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) - -/** Do an atomic test-and-set. -@param[in,out] ptr Memory location to set to non-zero -@return the previous value */ -static inline -lock_word_t -os_atomic_test_and_set(volatile lock_word_t* ptr) -{ - return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); -} - -/** Do an atomic clear. -@param[in,out] ptr Memory location to set to zero */ -static inline -void -os_atomic_clear(volatile lock_word_t* ptr) -{ - __atomic_clear(ptr, __ATOMIC_RELEASE); -} - -# elif defined(IB_STRONG_MEMORY_MODEL) +# if defined(IB_STRONG_MEMORY_MODEL) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero @@ -368,6 +347,27 @@ os_atomic_clear(volatile lock_word_t* ptr) return(__sync_lock_test_and_set(ptr, 0)); } +# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) + +/** Do an atomic test-and-set. +@param[in,out] ptr Memory location to set to non-zero +@return the previous value */ +static inline +lock_word_t +os_atomic_test_and_set(volatile lock_word_t* ptr) +{ + return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); +} + +/** Do an atomic clear. +@param[in,out] ptr Memory location to set to zero */ +static inline +void +os_atomic_clear(volatile lock_word_t* ptr) +{ + __atomic_clear(ptr, __ATOMIC_RELEASE); +} + # else # error "Unsupported platform" From a4f2391d8dac3e1c65b269248e5b8a8045211897 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 27 Jan 2016 18:42:52 +0530 Subject: [PATCH 08/52] BUG#22600974 - SYSV INITSCRIPT FOR RHEL DON'T ENABLE MYSQLD SERVICE BY DEFAULT Enable mysqld service by default in sysv initscrips --- packaging/rpm-oel/mysql.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm-oel/mysql.init b/packaging/rpm-oel/mysql.init index 79c8a8daa7d..262d0582f68 100644 --- a/packaging/rpm-oel/mysql.init +++ b/packaging/rpm-oel/mysql.init @@ -3,7 +3,7 @@ # mysqld This shell script takes care of starting and stopping # the MySQL subsystem (mysqld). # -# chkconfig: - 64 36 +# chkconfig: 345 64 36 # description: MySQL database server. # processname: mysqld # config: /etc/my.cnf From 01d41f68b7a6e6cc12565056661f1f28876beff5 Mon Sep 17 00:00:00 2001 From: Ajo Robert Date: Thu, 28 Jan 2016 17:40:17 +0530 Subject: [PATCH 09/52] Bug #16912362 LOAD DATA INFILE CLAIMS TO BE HOLDING 'SYSTEM LOCK' IN PROCESSLIST Analysis ========= Show processlist shows 'System Lock' in 'State' field while LOAD DATA INFILE is running. thd->proc_info update is missing in LOAD DATA INFILE path. Thus any request will get last unpdated status from lock_table() during open_table(). Fix: ======= Update state information from LOAD DATA INFILE path. --- sql/sql_load.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 5f72d3ce520..c084e5e3839 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -253,6 +253,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { DBUG_RETURN(TRUE); } + thd_proc_info(thd, "executing"); /* Let us emit an error if we are loading data to table which is used in subselect in SET clause like we do it for INSERT. From 718c787912e0d498c167e7436d840b2c837e90f9 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 29 Jan 2016 08:29:06 +0530 Subject: [PATCH 10/52] Bug #18823979: PS: UCS2 + CASE WHEN THEN ELSE CRASH IN ITEM_PARAM::SAFE_CHARSET_CONVERTER ISSUE: ------ Charset conversion on a null parameter is not handled correctly. SOLUTION: --------- Item_param's charset converter does not handle the case where it might have to deal with a null value. This is fine for other charset converters since the value is not supplied to them at runtime. The fix is to check if the parameter is now set to null and return an Item_null object. Also, there is no need to initialize Item_param's cnvitem in the constructor to a string. This can be done in ITEM_PARAM::SAFE_CHARSET_CONVERTER itself. Members of Item_param, cnvbuf and cnvstr, have been removed and cnvitem has been made a local variable in ITEM_PARAM::SAFE_CHARSET_CONVERTER. --- sql/item.cc | 35 +++++++++++++++++++++++++---------- sql/item.h | 6 +----- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 5f02b96e59f..c482f0e1a04 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -926,14 +926,31 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs) { if (const_item()) { - uint cnv_errors; - String *ostr= val_str(&cnvstr); - cnvitem->str_value.copy(ostr->ptr(), ostr->length(), - ostr->charset(), tocs, &cnv_errors); - if (cnv_errors) - return NULL; - cnvitem->str_value.mark_as_const(); - cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen; + Item *cnvitem; + String tmp, cstr, *ostr= val_str(&tmp); + + if (null_value) + { + cnvitem= new Item_null(); + if (cnvitem == NULL) + return NULL; + + cnvitem->collation.set(tocs); + } + else + { + uint conv_errors; + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, + &conv_errors); + + if (conv_errors || !(cnvitem= new Item_string(cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation))) + return NULL; + + cnvitem->str_value.copy(); + cnvitem->str_value.mark_as_const(); + } return cnvitem; } return Item::safe_charset_converter(tocs); @@ -2795,8 +2812,6 @@ Item_param::Item_param(uint pos_in_query_arg) : value is set. */ maybe_null= 1; - cnvitem= new Item_string("", 0, &my_charset_bin, DERIVATION_COERCIBLE); - cnvstr.set(cnvbuf, sizeof(cnvbuf), &my_charset_bin); } diff --git a/sql/item.h b/sql/item.h index 831343de7ad..8caa2bc5f9f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1,7 +1,7 @@ #ifndef ITEM_INCLUDED #define ITEM_INCLUDED -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1861,10 +1861,6 @@ public: class Item_param :public Item, private Settable_routine_parameter { - char cnvbuf[MAX_FIELD_WIDTH]; - String cnvstr; - Item *cnvitem; - public: enum enum_item_param_state { From 1fb6d4e6bf3dd79fffb034ca4b014930b0304e1f Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 8 Feb 2016 11:28:20 +0100 Subject: [PATCH 11/52] Bug#22680706: 5.5 DOES NOT BUILD WITH GCC5 Fix the following two build warnings so that 5.5 can be compiled with GCC5. storage/innobase/dict/dict0crea.c:1143:21: error: logical not is only applied to the left hand side of comparison [-Werror=logical-not-parentheses] ut_a(!node->index == (err != DB_SUCCESS)); ^ storage/innobase/log/log0recv.c:1770:20: error: logical not is only applied to the left hand side of comparison [-Werror=logical-not-parentheses] ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); ^ --- storage/innobase/dict/dict0crea.c | 4 ++-- storage/innobase/log/log0recv.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index ac8a1eac03c..e568dfa16c7 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1140,7 +1140,7 @@ dict_create_index_step( >= DICT_TF_FORMAT_ZIP); node->index = dict_index_get_if_in_cache_low(index_id); - ut_a(!node->index == (err != DB_SUCCESS)); + ut_a((node->index == NULL) == (err != DB_SUCCESS)); if (err != DB_SUCCESS) { diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index ae3912da552..846d430c294 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1767,7 +1767,7 @@ loop: goto loop; } - ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); + ut_ad((!allow_ibuf) == mutex_own(&log_sys->mutex)); if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; From d9c541cb1be5b239787833d9d499067d44ea44d3 Mon Sep 17 00:00:00 2001 From: Nisha Gopalakrishnan Date: Wed, 10 Feb 2016 19:57:17 +0530 Subject: [PATCH 12/52] BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN KEY CONSTRAINT. Analysis ======= INSERT and UPDATE operations using the IGNORE keyword which causes FOREIGN KEY constraint violations reports an error despite using the IGNORE keyword. Foreign key violation errors were not ignored and reported as errors instead of warnings even when IGNORE was set. Fix === Added code to ignore the foreign key violation errors and report them as warnings when the IGNORE keyword is used. --- mysql-test/r/insert.result | 38 +++++++++++++++++++++++++++++++++++ mysql-test/t/insert.test | 41 ++++++++++++++++++++++++++++++++++++++ sql/handler.cc | 27 ++++++++++++++++++++++++- sql/handler.h | 10 ++++++++-- sql/sql_insert.cc | 12 +++++++---- sql/sql_update.cc | 26 ++++++++++++++++++------ 6 files changed, 141 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 655303be7f4..1aa22349593 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -686,3 +686,41 @@ ERROR 42000: Column 'a' specified twice INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; ERROR 42000: Column 'a' specified twice DROP TABLE t1; +# +# BUG#22037930: INSERT IGNORE FAILS TO IGNORE +# FOREIGN KEY CONSTRAINT +# Setup. +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fld2 INT, FOREIGN KEY (fld2) REFERENCES t1 (fld1)) +ENGINE=INNODB; +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +# Without fix, an error is reported. +INSERT IGNORE INTO t2 VALUES(1); +Warnings: +Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +UPDATE IGNORE t2 SET fld2=20 WHERE fld2=0; +Warnings: +Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +UPDATE IGNORE t1 SET fld1=20 WHERE fld1=0; +Warnings: +Warning 1451 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +# Test for multi update. +UPDATE IGNORE t1, t2 SET t2.fld2= t2.fld2 + 3; +Warnings: +Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +UPDATE IGNORE t1, t2 SET t1.fld1= t1.fld1 + 3; +Warnings: +Warning 1451 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +# Reports an error since IGNORE is not used. +INSERT INTO t2 VALUES(1); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +UPDATE t2 SET fld2=20 WHERE fld2=0; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +UPDATE t1 SET fld1=20 WHERE fld1=0; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +UPDATE t1, t2 SET t2.fld2= t2.fld2 + 3; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +DROP TABLE t2, t1; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 2bf543511ac..ea89872200c 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -550,3 +550,44 @@ INSERT IGNORE t1 (a, a) SELECT 1,1; INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; DROP TABLE t1; + + +--echo # +--echo # BUG#22037930: INSERT IGNORE FAILS TO IGNORE +--echo # FOREIGN KEY CONSTRAINT + +--echo # Setup. +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fld2 INT, FOREIGN KEY (fld2) REFERENCES t1 (fld1)) +ENGINE=INNODB; +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); + +--echo # Without fix, an error is reported. +--enable_warnings +INSERT IGNORE INTO t2 VALUES(1); +UPDATE IGNORE t2 SET fld2=20 WHERE fld2=0; +UPDATE IGNORE t1 SET fld1=20 WHERE fld1=0; + +--echo # Test for multi update. +UPDATE IGNORE t1, t2 SET t2.fld2= t2.fld2 + 3; +UPDATE IGNORE t1, t2 SET t1.fld1= t1.fld1 + 3; +--disable_warnings + +--echo # Reports an error since IGNORE is not used. +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES(1); + +--error ER_NO_REFERENCED_ROW_2 +UPDATE t2 SET fld2=20 WHERE fld2=0; + +--error ER_ROW_IS_REFERENCED_2 +UPDATE t1 SET fld1=20 WHERE fld1=0; + +--error ER_NO_REFERENCED_ROW_2 +UPDATE t1, t2 SET t2.fld2= t2.fld2 + 3; + +--error ER_ROW_IS_REFERENCED_2 +UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; + +DROP TABLE t2, t1; diff --git a/sql/handler.cc b/sql/handler.cc index 6307e95a194..9d57cba73dc 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -5452,3 +5452,28 @@ fl_create_iterator(enum handler_iterator_type type, } } #endif /*TRANS_LOG_MGM_EXAMPLE_CODE*/ + + +/** + Report a warning for FK constraint violation. + + @param thd Thread handle. + @param table table on which the operation is performed. + @param error handler error number. +*/ +void warn_fk_constraint_violation(THD *thd,TABLE *table, int error) +{ + String str; + switch(error) { + case HA_ERR_ROW_IS_REFERENCED: + table->file->get_error_message(error, &str); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ROW_IS_REFERENCED_2, str.c_ptr_safe()); + break; + case HA_ERR_NO_REFERENCED_ROW: + table->file->get_error_message(error, &str); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_REFERENCED_ROW_2, str.c_ptr_safe()); + break; + } +} diff --git a/sql/handler.h b/sql/handler.h index 17306fe7dd4..29b6a86c030 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2,7 +2,7 @@ #define HANDLER_INCLUDED /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -303,6 +303,7 @@ /* Flags for method is_fatal_error */ #define HA_CHECK_DUP_KEY 1 #define HA_CHECK_DUP_UNIQUE 2 +#define HA_CHECK_FK_ERROR 4 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE) enum legacy_db_type @@ -1485,7 +1486,10 @@ public: if (!error || ((flags & HA_CHECK_DUP_KEY) && (error == HA_ERR_FOUND_DUPP_KEY || - error == HA_ERR_FOUND_DUPP_UNIQUE))) + error == HA_ERR_FOUND_DUPP_UNIQUE)) || + ((flags & HA_CHECK_FK_ERROR) && + (error == HA_ERR_ROW_IS_REFERENCED || + error == HA_ERR_NO_REFERENCED_ROW))) return FALSE; return TRUE; } @@ -2362,4 +2366,6 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); } +void warn_fk_constraint_violation(THD *thd, TABLE *table, int error); + #endif /* HANDLER_INCLUDED */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7bfc7b083ac..a267108c847 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1522,7 +1522,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) else table->file->insert_id_for_cur_row= insert_id_for_cur_row; bool is_duplicate_key_error; - if (table->file->is_fatal_error(error, HA_CHECK_DUP)) + if (table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) goto err; is_duplicate_key_error= table->file->is_fatal_error(error, 0); if (!is_duplicate_key_error) @@ -1620,7 +1620,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) error != HA_ERR_RECORD_IS_THE_SAME) { if (info->ignore && - !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) { goto ok_or_after_trg_err; } @@ -1733,7 +1734,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) { DEBUG_SYNC(thd, "write_row_noreplace"); if (!info->ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP)) + table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) goto err; table->file->restore_auto_increment(prev_insert_id); goto ok_or_after_trg_err; @@ -1751,6 +1752,9 @@ ok_or_after_trg_err: my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH); if (!table->file->has_transactions()) thd->transaction.stmt.modified_non_trans_table= TRUE; + if (info->ignore && + !table->file->is_fatal_error(error, HA_CHECK_FK_ERROR)) + warn_fk_constraint_violation(thd, table, error); DBUG_RETURN(trg_error); err: diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a29d474fbfc..64d1b3e49dc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -735,7 +735,8 @@ int mysql_update(THD *thd, error= 0; } else if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) { /* If (ignore && error is ignorable) we don't have to @@ -743,7 +744,8 @@ int mysql_update(THD *thd, */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); @@ -751,6 +753,9 @@ int mysql_update(THD *thd, error= 1; break; } + else if (ignore && !table->file->is_fatal_error(error, + HA_CHECK_FK_ERROR)) + warn_fk_constraint_violation(thd, table, error); } if (table->triggers && @@ -1883,7 +1888,8 @@ bool multi_update::send_data(List ¬_used_values) { updated--; if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) { /* If (ignore && error == is ignorable) we don't have to @@ -1891,13 +1897,17 @@ bool multi_update::send_data(List ¬_used_values) */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); table->file->print_error(error,MYF(flags)); DBUG_RETURN(1); } + else if (ignore && !table->file->is_fatal_error(error, + HA_CHECK_FK_ERROR)) + warn_fk_constraint_violation(thd, table, error); } else { @@ -2138,8 +2148,12 @@ int multi_update::do_updates() local_error != HA_ERR_RECORD_IS_THE_SAME) { if (!ignore || - table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY | + HA_CHECK_FK_ERROR)) goto err; + else if (ignore && !table->file->is_fatal_error(local_error, + HA_CHECK_FK_ERROR)) + warn_fk_constraint_violation(thd, table, local_error); } if (local_error != HA_ERR_RECORD_IS_THE_SAME) updated++; From b3e9211e48a3fb586e88b0270a175d2348935424 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 19 Feb 2016 23:31:10 +0400 Subject: [PATCH 13/52] WL#9072: Backport WL#8785 to 5.5 --- client/client_priv.h | 36 ++++++++++++++++++- client/mysql.cc | 14 ++++---- client/mysql_upgrade.c | 7 +++- client/mysqladmin.cc | 7 ++-- client/mysqlcheck.c | 8 +++-- client/mysqldump.c | 9 ++--- client/mysqlimport.c | 8 ++--- client/mysqlshow.c | 10 +++--- client/mysqlslap.c | 8 ++--- client/mysqltest.cc | 12 ++++--- include/sslopt-case.h | 15 +++++++- include/sslopt-longopts.h | 5 ++- include/sslopt-vars.h | 12 +++++-- mysql-test/r/ssl_mode.result | 44 +++++++++++++++++++++++ mysql-test/r/ssl_mode_no_ssl.result | 22 ++++++++++++ mysql-test/t/ssl_mode.test | 47 +++++++++++++++++++++++++ mysql-test/t/ssl_mode_no_ssl-master.opt | 1 + mysql-test/t/ssl_mode_no_ssl.test | 41 +++++++++++++++++++++ 18 files changed, 265 insertions(+), 41 deletions(-) create mode 100644 mysql-test/r/ssl_mode.result create mode 100644 mysql-test/r/ssl_mode_no_ssl.result create mode 100644 mysql-test/t/ssl_mode.test create mode 100644 mysql-test/t/ssl_mode_no_ssl-master.opt create mode 100644 mysql-test/t/ssl_mode_no_ssl.test diff --git a/client/client_priv.h b/client/client_priv.h index 593c37b030a..e53ced7e790 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -88,6 +88,7 @@ enum options_client OPT_DEFAULT_AUTH, OPT_DEFAULT_PLUGIN, OPT_ENABLE_CLEARTEXT_PLUGIN, + OPT_SSL_MODE, OPT_MAX_CLIENT_OPTION }; @@ -111,3 +112,36 @@ enum options_client */ #define PERFORMANCE_SCHEMA_DB_NAME "performance_schema" +/** + Wrapper for mysql_real_connect() that checks if SSL connection is establised. + + The function calls mysql_real_connect() first, then if given ssl_required==TRUE + argument (i.e. --ssl-mode=REQUIRED option used) checks current SSL chiper to + ensure that SSL is used for current connection. + Otherwise it returns NULL and sets errno to CR_SSL_CONNECTION_ERROR. + + All clients (except mysqlbinlog which disregards SSL options) use this function + instead of mysql_real_connect() to handle --ssl-mode=REQUIRED option. +*/ +MYSQL *mysql_connect_ssl_check(MYSQL *mysql_arg, const char *host, + const char *user, const char *passwd, + const char *db, uint port, + const char *unix_socket, ulong client_flag, + my_bool ssl_required __attribute__((unused))) +{ + MYSQL *mysql= mysql_real_connect(mysql_arg, host, user, passwd, db, port, + unix_socket, client_flag); +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) + if (mysql && /* connection established. */ + ssl_required && /* --ssl-mode=REQUIRED. */ + !mysql_get_ssl_cipher(mysql)) /* non-SSL connection. */ + { + NET *net= &mysql->net; + net->last_errno= CR_SSL_CONNECTION_ERROR; + strmov(net->last_error, "--ssl-mode=REQUIRED option forbids non SSL connections"); + strmov(net->sqlstate, "HY000"); + return NULL; + } +#endif + return mysql; +} diff --git a/client/mysql.cc b/client/mysql.cc index 84f5f097f06..cdc2ab0d6e0 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1316,8 +1316,9 @@ sig_handler handle_sigint(int sig) } kill_mysql= mysql_init(kill_mysql); - if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password, - "", opt_mysql_port, opt_mysql_unix_port,0)) + if (!mysql_connect_ssl_check(kill_mysql, current_host, current_user, opt_password, + "", opt_mysql_port, opt_mysql_unix_port, 0, + opt_ssl_required)) { tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n"); goto err; @@ -4457,9 +4458,10 @@ sql_real_connect(char *host,char *database,char *user,char *password, mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, (char*) &opt_enable_cleartext_plugin); - if (!mysql_real_connect(&mysql, host, user, password, - database, opt_mysql_port, opt_mysql_unix_port, - connect_flag | CLIENT_MULTI_STATEMENTS)) + if (!mysql_connect_ssl_check(&mysql, host, user, password, + database, opt_mysql_port, opt_mysql_unix_port, + connect_flag | CLIENT_MULTI_STATEMENTS, + opt_ssl_required)) { if (!silent || (mysql_errno(&mysql) != CR_CONN_HOST_ERROR && diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index fcbde2653e8..507df6f7843 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -307,6 +307,7 @@ get_one_option(int optid, const struct my_option *opt, case OPT_DEFAULT_AUTH: /* --default-auth */ add_one_option(&conn_args, opt, argument); break; +#include } if (add_option) @@ -386,6 +387,10 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...) va_end(args); + /* If given --ssl-mode=REQUIRED propagate it to the tool. */ + if (opt_ssl_required) + dynstr_append(&ds_cmdline, "--ssl-mode=REQUIRED"); + #ifdef __WIN__ dynstr_append(&ds_cmdline, "\""); #endif diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index e8bb4a1a27c..f0ae2c12137 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -518,8 +518,9 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) for (;;) { - if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, - unix_port, CLIENT_REMEMBER_OPTIONS)) + if (mysql_connect_ssl_check(mysql, host, user, opt_password, NullS, + tcp_port, unix_port, + CLIENT_REMEMBER_OPTIONS, opt_ssl_required)) { mysql->reconnect= 1; if (info) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 0d5570434e4..a564e871281 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -894,8 +894,10 @@ static int dbConnect(char *host, char *user, char *passwd) (char *) &opt_enable_cleartext_plugin); mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); - if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd, - NULL, opt_mysql_port, opt_mysql_unix_port, 0))) + if (!(sock = mysql_connect_ssl_check(&mysql_connection, host, user, passwd, + NULL, opt_mysql_port, + opt_mysql_unix_port, 0, + opt_ssl_required))) { DBerror(&mysql_connection, "when trying to connect"); return 1; diff --git a/client/mysqldump.c b/client/mysqldump.c index 6bb249134e8..6c4fec313c5 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1498,9 +1498,10 @@ static int connect_to_db(char *host, char *user,char *passwd) mysql_options(&mysql_connection, MYSQL_ENABLE_CLEARTEXT_PLUGIN, (char *) &opt_enable_cleartext_plugin); - if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd, - NULL,opt_mysql_port,opt_mysql_unix_port, - 0))) + if (!(mysql= mysql_connect_ssl_check(&mysql_connection, host, user, + passwd, NULL, opt_mysql_port, + opt_mysql_unix_port, 0, + opt_ssl_required))) { DB_error(&mysql_connection, "when trying to connect"); DBUG_RETURN(1); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index f71111f7e9e..416159abd81 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -449,9 +449,9 @@ static MYSQL *db_connect(char *host, char *database, (char*)&opt_enable_cleartext_plugin); mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); - if (!(mysql_real_connect(mysql,host,user,passwd, - database,opt_mysql_port,opt_mysql_unix_port, - 0))) + if (!(mysql_connect_ssl_check(mysql, host, user, passwd, database, + opt_mysql_port, opt_mysql_unix_port, + 0, opt_ssl_required))) { ignore_errors=0; /* NO RETURN FROM db_error */ db_error(mysql); diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 6cbbc5e2463..4d1df00c8fd 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -139,10 +139,10 @@ int main(int argc, char **argv) mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, (char*)&opt_enable_cleartext_plugin); - if (!(mysql_real_connect(&mysql,host,user,opt_password, - (first_argument_uses_wildcards) ? "" : - argv[0],opt_mysql_port,opt_mysql_unix_port, - 0))) + if (!(mysql_connect_ssl_check(&mysql, host, user, opt_password, + (first_argument_uses_wildcards) ? "" : + argv[0], opt_mysql_port, opt_mysql_unix_port, + 0, opt_ssl_required))) { fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql)); exit(1); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 8c50898fb01..eb2b577948c 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -355,9 +355,9 @@ int main(int argc, char **argv) (char*) &opt_enable_cleartext_plugin); if (!opt_only_print) { - if (!(mysql_real_connect(&mysql, host, user, opt_password, - NULL, opt_mysql_port, - opt_mysql_unix_port, connect_flags))) + if (!(mysql_connect_ssl_check(&mysql, host, user, opt_password, + NULL, opt_mysql_port, opt_mysql_unix_port, + connect_flags, opt_ssl_required))) { fprintf(stderr,"%s: Error when connecting to server: %s\n", my_progname,mysql_error(&mysql)); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 78dcdd77659..79d448cf811 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -5281,8 +5281,9 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host, verbose_msg("Connecting to server %s:%d (socket %s) as '%s'" ", connection '%s', attempt %d ...", host, port, sock, user, name, failed_attempts); - while(!mysql_real_connect(mysql, host,user, pass, db, port, sock, - CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) + while(!mysql_connect_ssl_check(mysql, host,user, pass, db, port, sock, + CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS, + opt_ssl_required)) { /* Connect failed @@ -5382,8 +5383,9 @@ int connect_n_handle_errors(struct st_command *command, dynstr_append_mem(ds, ";\n", 2); } - while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, - CLIENT_MULTI_STATEMENTS)) + while (!mysql_connect_ssl_check(con, host, user, pass, db, port, + sock ? sock: 0, CLIENT_MULTI_STATEMENTS, + opt_ssl_required)) { /* If we have used up all our connections check whether this diff --git a/include/sslopt-case.h b/include/sslopt-case.h index 2da5ff317e1..57702b3b352 100644 --- a/include/sslopt-case.h +++ b/include/sslopt-case.h @@ -1,7 +1,7 @@ #ifndef SSLOPT_CASE_INCLUDED #define SSLOPT_CASE_INCLUDED -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,5 +28,18 @@ */ opt_use_ssl= 1; break; +#ifdef MYSQL_CLIENT + case OPT_SSL_MODE: + if (my_strcasecmp(&my_charset_latin1, argument, "required")) + { + fprintf(stderr, + "Unknown value to --ssl-mode: '%s'. Use --ssl-mode=REQUIRED\n", + argument); + exit(1); + } + else + opt_ssl_required= 1; + break; +#endif /* MYSQL_CLIENT */ #endif #endif /* SSLOPT_CASE_INCLUDED */ diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index db99d1dfa26..fd42e83eb04 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -1,7 +1,7 @@ #ifndef SSLOPT_LONGOPTS_INCLUDED #define SSLOPT_LONGOPTS_INCLUDED -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,6 +44,9 @@ "when connecting. This option is disabled by default.", &opt_ssl_verify_server_cert, &opt_ssl_verify_server_cert, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"ssl-mode", OPT_SSL_MODE, + "SSL connection mode.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif #endif /* HAVE_OPENSSL */ #endif /* SSLOPT_LONGOPTS_INCLUDED */ diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h index 01093feceaf..6c9bd4296ef 100644 --- a/include/sslopt-vars.h +++ b/include/sslopt-vars.h @@ -1,7 +1,7 @@ #ifndef SSLOPT_VARS_INCLUDED #define SSLOPT_VARS_INCLUDED -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,8 +28,14 @@ SSL_STATIC char *opt_ssl_capath = 0; SSL_STATIC char *opt_ssl_cert = 0; SSL_STATIC char *opt_ssl_cipher = 0; SSL_STATIC char *opt_ssl_key = 0; + #ifdef MYSQL_CLIENT SSL_STATIC my_bool opt_ssl_verify_server_cert= 0; -#endif -#endif +SSL_STATIC my_bool opt_ssl_required= 0; +#endif /* MYSQL_CLIENT */ + +#else /* HAVE_OPENSSL */ +#define opt_ssl_required 0 +#endif /* HAVE_OPENSSL */ + #endif /* SSLOPT_VARS_INCLUDED */ diff --git a/mysql-test/r/ssl_mode.result b/mysql-test/r/ssl_mode.result new file mode 100644 index 00000000000..38fc4e1dca2 --- /dev/null +++ b/mysql-test/r/ssl_mode.result @@ -0,0 +1,44 @@ +# positive client tests +# mysql +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(0); +# mysqldump +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t1` VALUES (0); +# mysqladmin +mysqld is alive +# mysqlcheck +test.t1 OK +# mysqlimport +CREATE TABLE words(a VARCHAR(255)); +test.words: Records: 70 Deleted: 0 Skipped: 0 Warnings: 0 +DROP TABLE words; +# mysqlshow +Database: test ++--------+ +| Tables | ++--------+ +| t1 | ++--------+ +# mysqlslap +# mysqltest +Output from mysqltest-x.inc +DROP TABLE t1; +# negative client tests +# mysql +Unknown value to --ssl-mode: ''. Use --ssl-mode=REQUIRED +Unknown value to --ssl-mode: 'DERIUQER'. Use --ssl-mode=REQUIRED +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections + +End of tests diff --git a/mysql-test/r/ssl_mode_no_ssl.result b/mysql-test/r/ssl_mode_no_ssl.result new file mode 100644 index 00000000000..409b7a0fa1b --- /dev/null +++ b/mysql-test/r/ssl_mode_no_ssl.result @@ -0,0 +1,22 @@ +# negative client tests +# mysql +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +ERROR 2026 (HY000): --ssl-mode=REQUIRED option forbids non SSL connections +# mysqldump +mysqldump: Got error: 2026: --ssl-mode=REQUIRED option forbids non SSL connections when trying to connect +# mysqladmin +mysqladmin: error: '--ssl-mode=REQUIRED option forbids non SSL connections' +# mysqlcheck +mysqlcheck: Got error: 2026: --ssl-mode=REQUIRED option forbids non SSL connections when trying to connect +# mysqlimport +mysqlimport: Error: 2026 --ssl-mode=REQUIRED option forbids non SSL connections +# mysqlshow +mysqlshow: --ssl-mode=REQUIRED option forbids non SSL connections +# mysqlslap +mysqlslap: Error when connecting to server: --ssl-mode=REQUIRED option forbids non SSL connections +# mysqltest +mysqltest: Could not open connection 'default': 2026 --ssl-mode=REQUIRED option forbids non SSL connections + +End of tests diff --git a/mysql-test/t/ssl_mode.test b/mysql-test/t/ssl_mode.test new file mode 100644 index 00000000000..ce1f2aa5e0a --- /dev/null +++ b/mysql-test/t/ssl_mode.test @@ -0,0 +1,47 @@ +-- source include/not_embedded.inc +-- source include/have_ssl_communication.inc + +--echo # positive client tests +--echo # mysql +--exec $MYSQL test --ssl-mode=ReQuIrEd --ssl-cipher=DHE-RSA-AES256-SHA -e "SHOW STATUS LIKE 'Ssl_cipher'" 2>&1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl --ssl-cipher=DHE-RSA-AES256-SHA -e "SHOW STATUS LIKE 'Ssl_cipher'" 2>&1 + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(0); + +--echo # mysqldump +--exec $MYSQL_DUMP --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA --compact --skip-comments test 2>&1 +--echo # mysqladmin +--exec $MYSQLADMIN --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 +--echo # mysqlcheck +--exec $MYSQL_CHECK --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA test 2>&1 +--echo # mysqlimport +CREATE TABLE words(a VARCHAR(255)); +--exec $MYSQL_IMPORT --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA test $MYSQLTEST_VARDIR/std_data/words.dat 2>&1 +DROP TABLE words; +--echo # mysqlshow +--exec $MYSQL_SHOW --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA test 2>&1 +--echo # mysqlslap +--exec $MYSQL_SLAP --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA --create-schema=test --query="select * from t1" --silent 2>&1 +--echo # mysqltest +--exec $MYSQL_TEST --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA -x $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1 + +DROP TABLE t1; + +--echo # negative client tests +--echo # mysql +--error 5 +--exec $MYSQL test --ssl-mode +--error 1 +--exec $MYSQL test --ssl-mode= 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=DERIUQER 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA --skip-ssl 2>&1 + +--echo +--echo End of tests diff --git a/mysql-test/t/ssl_mode_no_ssl-master.opt b/mysql-test/t/ssl_mode_no_ssl-master.opt new file mode 100644 index 00000000000..0ca403efdfb --- /dev/null +++ b/mysql-test/t/ssl_mode_no_ssl-master.opt @@ -0,0 +1 @@ +--skip-ssl diff --git a/mysql-test/t/ssl_mode_no_ssl.test b/mysql-test/t/ssl_mode_no_ssl.test new file mode 100644 index 00000000000..65f7d1cd46b --- /dev/null +++ b/mysql-test/t/ssl_mode_no_ssl.test @@ -0,0 +1,41 @@ +-- source include/not_embedded.inc + +--echo # negative client tests +--echo # mysql +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl-cipher=DHE-RSA-AES256-SHA 2>&1 +--error 1 +--exec $MYSQL test --ssl-mode=REQUIRED --ssl --ssl-cipher=DHE-RSA-AES256-SHA 2>&1 +--echo # mysqldump +--error 2 +--exec $MYSQL_DUMP --ssl-mode=REQUIRED test 2>&1 +--echo # mysqladmin +--replace_regex /.*mysqladmin.*/mysqladmin: / +--error 1 +--exec $MYSQLADMIN --ssl-mode=REQUIRED -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 +--echo # mysqlcheck +--replace_regex /.*mysqlcheck(\.exe)*/mysqlcheck/ +--error 2 +--exec $MYSQL_CHECK --ssl-mode=REQUIRED test 2>&1 +--echo # mysqlimport +--replace_regex /.*mysqlimport(\.exe)*/mysqlimport/ +--error 1 +--exec $MYSQL_IMPORT --ssl-mode=REQUIRED test $MYSQLTEST_VARDIR/tmp/t1.txt 2>&1 +--echo # mysqlshow +--replace_regex /.*mysqlshow(\.exe)*/mysqlshow/ +--error 1 +--exec $MYSQL_SHOW --ssl-mode=REQUIRED test 2>&1 +--echo # mysqlslap +--replace_regex /.*mysqlslap(\.exe)*/mysqlslap/ +--error 1 +--exec $MYSQL_SLAP --ssl-mode=REQUIRED 2>&1 +--echo # mysqltest +--error 1 +--exec $MYSQL_TEST --ssl-mode=REQUIRED -x $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1 + +--echo +--echo End of tests From 83d20ca3fbab4ffa160fd3554e9e36a868fb2ab1 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 23 Feb 2016 11:41:03 +0530 Subject: [PATCH 14/52] --- storage/myisam/ft_boolean_search.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index a9ce4436025..fc8713f0d32 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -199,7 +199,8 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param, ftbw= (FTB_WORD *)alloc_root(&ftb_param->ftb->mem_root, sizeof(FTB_WORD) + (info->trunc ? MI_MAX_KEY_BUFF : - word_len * ftb_param->ftb->charset->mbmaxlen + + (word_len + 1) * + ftb_param->ftb->charset->mbmaxlen + HA_FT_WLEN + ftb_param->ftb->info->s->rec_reflength)); ftbw->len= word_len + 1; @@ -362,6 +363,8 @@ static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) MI_INFO *info=ftb->info; uint UNINIT_VAR(off), extra= HA_FT_WLEN + info->s->rec_reflength; uchar *lastkey_buf=ftbw->word+ftbw->off; + uint max_word_length= (ftbw->flags & FTB_FLAG_TRUNC) ? MI_MAX_KEY_BUFF : + ((ftbw->len) * ftb->charset->mbmaxlen) + extra; if (ftbw->flags & FTB_FLAG_TRUNC) lastkey_buf+=ftbw->len; @@ -421,7 +424,7 @@ static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) (my_bool) (ftbw->flags & FTB_FLAG_TRUNC),0); } - if (r) /* not found */ + if (r || info->lastkey_length > max_word_length) /* not found */ { if (!ftbw->off || !(ftbw->flags & FTB_FLAG_TRUNC)) { From 447eaa5bc04761555f066d911397e41187d43af5 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 23 Feb 2016 11:54:59 +0530 Subject: [PATCH 15/52] --- sql/sql_acl.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a939ae72ecb..5ff6f38d18d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -717,7 +717,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, FALSE); table->use_all_columns(); - (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50); while (!(read_record_info.read_record(&read_record_info))) { ACL_HOST host; @@ -766,7 +765,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE); table->use_all_columns(); - (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100); password_length= table->field[2]->field_length / table->field[2]->charset()->mbmaxlen; if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323) @@ -981,7 +979,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE); table->use_all_columns(); - (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100); while (!(read_record_info.read_record(&read_record_info))) { ACL_DB db; @@ -1038,8 +1035,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_dbs); - (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), - 50, 100); if (tables[3].table) { init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, @@ -1075,6 +1070,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) return_val= FALSE; end: + end_read_record(&read_record_info); thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(return_val); } @@ -1089,12 +1085,12 @@ void acl_free(bool end) delete_dynamic(&acl_wild_hosts); delete_dynamic(&acl_proxy_users); my_hash_free(&acl_check_hosts); - plugin_unlock(0, native_password_plugin); - plugin_unlock(0, old_password_plugin); if (!end) acl_cache->clear(1); /* purecov: inspected */ else { + plugin_unlock(0, native_password_plugin); + plugin_unlock(0, old_password_plugin); delete acl_cache; acl_cache=0; } @@ -1168,6 +1164,10 @@ my_bool acl_reload(THD *thd) old_acl_users= acl_users; old_acl_proxy_users= acl_proxy_users; old_acl_dbs= acl_dbs; + my_init_dynamic_array(&acl_hosts, sizeof(ACL_HOST), 20, 50); + my_init_dynamic_array(&acl_users, sizeof(ACL_USER), 50, 100); + my_init_dynamic_array(&acl_dbs, sizeof(ACL_DB), 50, 100); + my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 50, 100); old_mem= mem; delete_dynamic(&acl_wild_hosts); my_hash_free(&acl_check_hosts); From 4ed09d54f53771383b943ee6610dae5faa068cff Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 23 Feb 2016 12:10:41 +0530 Subject: [PATCH 16/52] --- storage/federated/ha_federated.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 8209b5a2fcf..b47c4565743 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1675,6 +1675,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) int ha_federated::close(void) { + THD *thd= current_thd; DBUG_ENTER("ha_federated::close"); free_result(); @@ -1686,7 +1687,7 @@ int ha_federated::close(void) FLUSH TABLES will quit the connection and if connection is broken, it will reconnect again and quit silently. */ - if (mysql && !vio_is_connected(mysql->net.vio)) + if (mysql && (!mysql->net.vio || !vio_is_connected(mysql->net.vio))) mysql->net.error= 2; /* Disconnect from mysql */ @@ -1700,9 +1701,16 @@ int ha_federated::close(void) if the original query was not issued against the FEDERATED table. So, don't propagate errors from mysql_close(). */ - if (table->in_use) + if (table->in_use && thd != table->in_use) table->in_use->clear_error(); + /* + Errors from mysql_close() are silently ignored for flush tables. + Close the connection silently. + */ + if (thd && thd->lex->sql_command == SQLCOM_FLUSH) + thd->clear_error(); + DBUG_RETURN(free_share(share)); } From 29cc2c28832ae4733804ac6b29d650238ee0559c Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Fri, 26 Feb 2016 09:01:49 +0530 Subject: [PATCH 17/52] BUG#20574550 MAIN.MERGE TEST CASE FAILS IF BINLOG_FORMAT=ROW The main.merge test case was failing when tested using row based binlog format. While analyzing the issue it was found the following issues: a) The server is calling binlog related code even when a statement will not be binlogged; b) The child table list was not present into table structure by the time to generate the create table statement; c) The tables in the child table list will not be opened yet when generating table create info using row based replication; d) CREATE TABLE LIKE TEMP_TABLE does not preserve original table storage engine when using row based replication; This patch addressed all above issues. @ sql/sql_class.h Added a function to determine if the binary log is disabled to the current session. This is related with issue (a) above. @ sql/sql_table.cc Added code to skip binary logging related code if the statement will not be binlogged. This is related with issue (a) above. Added code to add the children to the query list of the table that will have its CREATE TABLE generated. This is related with issue (b) above. Added code to force the storage engine to be generated into the CREATE TABLE. This is related with issue (d) above. @ storage/myisammrg/ha_myisammrg.cc Added a test to skip a table getting info about a child table if the child table is not opened. This is related to issue (c) above. --- .../suite/binlog/r/binlog_row_binlog.result | 4 +- .../suite/rpl/r/rpl_row_merge_engine.result | 5 +- .../suite/rpl/r/rpl_tmp_table_and_DDL.result | 10 ++++ .../suite/rpl/t/rpl_row_merge_engine.test | 6 ++- .../suite/rpl/t/rpl_tmp_table_and_DDL.test | 51 +++++++++++++++++++ sql/sql_class.h | 14 ++++- sql/sql_table.cc | 20 +++++++- storage/myisammrg/ha_myisammrg.cc | 4 +- 8 files changed, 104 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 75105689246..1fcc915fa1f 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1203,7 +1203,7 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t2` ( master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t3` ( `a` int(11) DEFAULT NULL -) +) ENGINE=MyISAM master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (mysql.user) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F @@ -1238,7 +1238,7 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t2` ( master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t3` ( `a` int(11) DEFAULT NULL -) +) ENGINE=MyISAM master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (mysql.user) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F diff --git a/mysql-test/suite/rpl/r/rpl_row_merge_engine.result b/mysql-test/suite/rpl/r/rpl_row_merge_engine.result index c61167e84e0..3b2e02bf97c 100644 --- a/mysql-test/suite/rpl/r/rpl_row_merge_engine.result +++ b/mysql-test/suite/rpl/r/rpl_row_merge_engine.result @@ -4,8 +4,9 @@ CREATE TABLE t1 (a int) ENGINE=MyISAM; CREATE TABLE t2 (a int) ENGINE=MyISAM; INSERT INTO t1 VALUES (1), (2), (3); INSERT INTO t2 VALUES (4), (5), (6); -CREATE TABLE IF NOT EXISTS t1_merge LIKE t1; -ALTER TABLE t1_merge ENGINE=MERGE UNION (t2, t1); +CREATE TEMPORARY TABLE IF NOT EXISTS tt1_merge LIKE t1; +ALTER TABLE tt1_merge ENGINE=MERGE UNION (t2, t1); +CREATE TABLE t1_merge LIKE tt1_merge; include/diff_tables.inc [master:test.t1, slave:test.t1] include/diff_tables.inc [master:test.t2, slave:test.t2] UPDATE t1_merge SET a=10 WHERE a=1; diff --git a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result index 0264c9421fc..fb4e8f8ab8a 100644 --- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result +++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result @@ -192,4 +192,14 @@ DROP FUNCTION f2; DROP PROCEDURE p2; DROP EVENT e2; DROP TABLE t1, t2; +CREATE TEMPORARY TABLE temp_t1 (c1 INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE temp_t2 (c1 INT) ENGINE=MyISAM; +CREATE TABLE t1 LIKE temp_t1; +CREATE TABLE t2 LIKE temp_t2; +include/assert.inc ["t1 on master and temp_t1 have the same storage engine"] +include/assert.inc ["t2 on master and temp_t2 have the same storage engine"] +include/assert.inc ["t1 on slave and temp_t1 have the same storage engine"] +include/assert.inc ["t2 on slave and temp_t2 have the same storage engine"] +DROP TEMPORARY TABLE temp_t1, temp_t2; +DROP TABLE t1, t2; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_merge_engine.test b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test index 5add8dc1cda..dcbb8b891d8 100644 --- a/mysql-test/suite/rpl/t/rpl_row_merge_engine.test +++ b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test @@ -20,8 +20,10 @@ CREATE TABLE t1 (a int) ENGINE=MyISAM; CREATE TABLE t2 (a int) ENGINE=MyISAM; INSERT INTO t1 VALUES (1), (2), (3); INSERT INTO t2 VALUES (4), (5), (6); -CREATE TABLE IF NOT EXISTS t1_merge LIKE t1; -ALTER TABLE t1_merge ENGINE=MERGE UNION (t2, t1); +# Changed a little to check also an issue reported on BUG#20574550 +CREATE TEMPORARY TABLE IF NOT EXISTS tt1_merge LIKE t1; +ALTER TABLE tt1_merge ENGINE=MERGE UNION (t2, t1); +CREATE TABLE t1_merge LIKE tt1_merge; --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test index d722a15f255..decbdcc1f99 100644 --- a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test +++ b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test @@ -166,4 +166,55 @@ DROP PROCEDURE p2; DROP EVENT e2; DROP TABLE t1, t2; +--sync_slave_with_master +# +# BUG#20574550 +# CREATE TABLE LIKE does not preserve original table storage +# engine when using row based replication +# +--connection master + +# Define temp_t1 and temp_t2 storage engines +--let $engine_temp_t1= InnoDB +--let $engine_temp_t2= MyISAM + +# Create the two temporary tables +--eval CREATE TEMPORARY TABLE temp_t1 (c1 INT) ENGINE=$engine_temp_t1 +--eval CREATE TEMPORARY TABLE temp_t2 (c1 INT) ENGINE=$engine_temp_t2 + +# Create t1 and t2 based on temporary tables +CREATE TABLE t1 LIKE temp_t1; +CREATE TABLE t2 LIKE temp_t2; +--sync_slave_with_master + +# On master +--connection master +# Assert that t1 and t2 have the same storage engines as temp_t1 and temp_t2 +--let $engine_t1= query_get_value(SHOW TABLE STATUS WHERE Name='t1', Engine, 1) +--let $assert_cond= "$engine_t1" = "$engine_temp_t1" +--let $assert_text= "t1 on master and temp_t1 have the same storage engine" +--source include/assert.inc + +--let $engine_t2= query_get_value(SHOW TABLE STATUS WHERE Name='t2', Engine, 1) +--let $assert_cond= "$engine_t2" = "$engine_temp_t2" +--let $assert_text= "t2 on master and temp_t2 have the same storage engine" +--source include/assert.inc + +# On slave +--connection slave +# Assert that t1 and t2 have the same storage engines as temp_t1 and temp_t2 +--let $engine_t1= query_get_value(SHOW TABLE STATUS WHERE Name='t1', Engine, 1) +--let $assert_cond= "$engine_t1" = "$engine_temp_t1" +--let $assert_text= "t1 on slave and temp_t1 have the same storage engine" +--source include/assert.inc + +--let $engine_t2= query_get_value(SHOW TABLE STATUS WHERE Name='t2', Engine, 1) +--let $assert_cond= "$engine_t2" = "$engine_temp_t2" +--let $assert_text= "t2 on slave and temp_t2 have the same storage engine" +--source include/assert.inc + +# Cleanup +--connection master +DROP TEMPORARY TABLE temp_t1, temp_t2; +DROP TABLE t1, t2; --source include/rpl_end.inc diff --git a/sql/sql_class.h b/sql/sql_class.h index c9900231615..0df8c70e184 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1662,6 +1662,18 @@ public: current_stmt_binlog_format == BINLOG_FORMAT_ROW); return current_stmt_binlog_format == BINLOG_FORMAT_ROW; } + /** + Determine if binlogging is disabled for this session + @retval 0 if the current statement binlogging is disabled + (could be because of binlog closed/binlog option + is set to false). + @retval 1 if the current statement will be binlogged + */ + inline bool is_current_stmt_binlog_disabled() const + { + return (!(variables.option_bits & OPTION_BIN_LOG) || + !mysql_bin_log.is_open()); + } private: /** diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7b4d08613cf..49f05c6116e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4709,7 +4709,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, /* We have to write the query before we unlock the tables. */ - if (thd->is_current_stmt_binlog_format_row()) + if (!thd->is_current_stmt_binlog_disabled() && + thd->is_current_stmt_binlog_format_row()) { /* Since temporary tables are not replicated under row-based @@ -4751,6 +4752,21 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, if (open_table(thd, table, thd->mem_root, &ot_ctx)) goto err; + /* + After opening a MERGE table add the children to the query list of + tables, so that children tables info can be used on "CREATE TABLE" + statement generation by the binary log. + Note that placeholders don't have the handler open. + */ + if (table->table->file->extra(HA_EXTRA_ADD_CHILDREN_LIST)) + goto err; + + /* + As the reference table is temporary and may not exist on slave, we must + force the ENGINE to be present into CREATE TABLE. + */ + create_info->used_fields|= HA_CREATE_USED_ENGINE; + int result __attribute__((unused))= store_create_info(thd, table, &query, create_info, TRUE /* show_database */); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index b7e043c99f1..1ffdd83358d 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1481,6 +1481,8 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info) open_table != file->end_table ; open_table++) { + if (!open_table->table) + continue; TABLE_LIST *ptr; LEX_STRING db, name; LINT_INIT(db.str); From e7061f7e5a96c66cb2e0bf46bec7f6ff35801a69 Mon Sep 17 00:00:00 2001 From: Yashwant Sahu Date: Fri, 26 Feb 2016 11:53:56 +0530 Subject: [PATCH 18/52] Bug #22738607: YASSL FUNCTION X509_NAME_GET_INDEX_BY_NID IS NOT WORKING AS EXPECTED. --- extra/yassl/README | 6 ++++++ extra/yassl/include/openssl/ssl.h | 2 +- extra/yassl/include/yassl_int.hpp | 8 +++++-- extra/yassl/src/cert_wrapper.cpp | 9 ++++++-- extra/yassl/src/ssl.cpp | 10 ++++----- extra/yassl/src/yassl_int.cpp | 31 ++++++++++++++++------------ extra/yassl/taocrypt/include/asn.hpp | 8 +++++++ extra/yassl/taocrypt/src/asn.cpp | 12 +++++++++-- extra/yassl/testsuite/test.hpp | 22 ++++++++++++++++++-- 9 files changed, 80 insertions(+), 28 deletions(-) diff --git a/extra/yassl/README b/extra/yassl/README index 81d573d0b20..b5eb88824fb 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,6 +12,12 @@ before calling SSL_new(); *** end Note *** +yaSSL Release notes, version 2.3.9b (2/03/2016) + This release of yaSSL fixes the OpenSSL compatibility function + X509_NAME_get_index_by_NID() to use the actual index of the common name + instead of searching on the format prefix. Thanks for the report from + yashwant.sahu@oracle.com . Anyone using this function should update. + yaSSL Release notes, version 2.3.9 (12/01/2015) This release of yaSSL fixes two client side Diffie-Hellman problems. yaSSL was only handling the cases of zero or one leading zeros for the key diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 095b3c6aa80..83daf3cc81f 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -35,7 +35,7 @@ #include "rsa.h" -#define YASSL_VERSION "2.3.9" +#define YASSL_VERSION "2.3.9b" #if defined(__cplusplus) diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 573f4f2264f..642afb25368 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -191,14 +191,18 @@ private: class X509_NAME { char* name_; size_t sz_; + int cnPosition_; // start of common name, -1 is none + int cnLen_; // length of above ASN1_STRING entry_; public: - X509_NAME(const char*, size_t sz); + X509_NAME(const char*, size_t sz, int pos, int len); ~X509_NAME(); const char* GetName() const; ASN1_STRING* GetEntry(int i); size_t GetLength() const; + int GetCnPosition() const { return cnPosition_; } + int GetCnLength() const { return cnLen_; } private: X509_NAME(const X509_NAME&); // hide copy X509_NAME& operator=(const X509_NAME&); // and assign @@ -226,7 +230,7 @@ class X509 { StringHolder afterDate_; // not valid after public: X509(const char* i, size_t, const char* s, size_t, - const char* b, int, const char* a, int); + const char* b, int, const char* a, int, int, int, int, int); ~X509() {} X509_NAME* GetIssuer(); diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index ff359c6ad71..f620f5efce0 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -293,7 +293,10 @@ int CertManager::Validate() int aSz = (int)strlen(cert.GetAfterDate()) + 1; peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(), sSz, cert.GetBeforeDate(), bSz, - cert.GetAfterDate(), aSz); + cert.GetAfterDate(), aSz, + cert.GetIssuerCnStart(), cert.GetIssuerCnLength(), + cert.GetSubjectCnStart(), cert.GetSubjectCnLength() + ); if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) { X509_STORE_CTX store; @@ -345,7 +348,9 @@ void CertManager::setPeerX509(X509* x) peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), subject->GetName(), subject->GetLength(), (const char*) before->data, - before->length, (const char*) after->data, after->length); + before->length, (const char*) after->data, after->length, + issuer->GetCnPosition(), issuer->GetCnLength(), + subject->GetCnPosition(), subject->GetCnLength()); } diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 845b35bac8b..cde32df4f43 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -1351,15 +1351,13 @@ int ASN1_STRING_type(ASN1_STRING *x) int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos) { int idx = -1; // not found - const char* start = &name->GetName()[lastpos + 1]; + int cnPos = -1; switch (nid) { case NID_commonName: - const char* found = strstr(start, "/CN="); - if (found) { - found += 4; // advance to str - idx = found - start + lastpos + 1; - } + cnPos = name->GetCnPosition(); + if (lastpos < cnPos) + idx = cnPos; break; } diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 19ba6386efd..f041850f85f 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1555,7 +1555,9 @@ void SSL_SESSION::CopyX509(X509* x) peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), subject->GetName(), subject->GetLength(), (const char*) before->data, - before->length, (const char*) after->data, after->length); + before->length, (const char*) after->data, after->length, + issuer->GetCnPosition(), issuer->GetCnLength(), + subject->GetCnPosition(), subject->GetCnLength()); } @@ -2472,8 +2474,8 @@ void Security::set_resuming(bool b) } -X509_NAME::X509_NAME(const char* n, size_t sz) - : name_(0), sz_(sz) +X509_NAME::X509_NAME(const char* n, size_t sz, int pos, int len) + : name_(0), sz_(sz), cnPosition_(pos), cnLen_(len) { if (sz) { name_ = NEW_YS char[sz]; @@ -2503,8 +2505,9 @@ size_t X509_NAME::GetLength() const X509::X509(const char* i, size_t iSz, const char* s, size_t sSz, - const char* b, int bSz, const char* a, int aSz) - : issuer_(i, iSz), subject_(s, sSz), + const char* b, int bSz, const char* a, int aSz, int issPos, + int issLen, int subPos, int subLen) + : issuer_(i, iSz, issPos, issLen), subject_(s, sSz, subPos, subLen), beforeDate_(b, bSz), afterDate_(a, aSz) {} @@ -2538,17 +2541,19 @@ ASN1_STRING* X509_NAME::GetEntry(int i) if (i < 0 || i >= int(sz_)) return 0; + if (i != cnPosition_ || cnLen_ <= 0) // only entry currently supported + return 0; + + if (cnLen_ > int(sz_-i)) // make sure there's room in read buffer + return 0; + if (entry_.data) ysArrayDelete(entry_.data); - entry_.data = NEW_YS byte[sz_]; // max size; + entry_.data = NEW_YS byte[cnLen_+1]; // max size; - memcpy(entry_.data, &name_[i], sz_ - i); - if (entry_.data[sz_ -i - 1]) { - entry_.data[sz_ - i] = 0; - entry_.length = int(sz_) - i; - } - else - entry_.length = int(sz_) - i - 1; + memcpy(entry_.data, &name_[i], cnLen_); + entry_.data[cnLen_] = 0; + entry_.length = cnLen_; entry_.type = 0; return &entry_; diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index c7d01d00323..9a10064ce02 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -283,6 +283,10 @@ public: const byte* GetHash() const { return subjectHash_; } const char* GetBeforeDate() const { return beforeDate_; } const char* GetAfterDate() const { return afterDate_; } + int GetSubjectCnStart() const { return subCnPos_; } + int GetIssuerCnStart() const { return issCnPos_; } + int GetSubjectCnLength() const { return subCnLen_; } + int GetIssuerCnLength() const { return issCnLen_; } void DecodeToKey(); private: @@ -292,6 +296,10 @@ private: word32 sigLength_; // length of signature word32 signatureOID_; // sum of algorithm object id word32 keyOID_; // sum of key algo object id + int subCnPos_; // subject common name start, -1 is none + int subCnLen_; // length of above + int issCnPos_; // issuer common name start, -1 is none + int issCnLen_; // length of above byte subjectHash_[SHA_SIZE]; // hash of all Names byte issuerHash_[SHA_SIZE]; // hash of all Names byte* signature_; diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index c419ec0a992..a210d805452 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -474,8 +474,9 @@ void DH_Decoder::Decode(DH& key) CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers, bool noVerify, CertType ct) - : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), - signature_(0), verify_(!noVerify) + : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), subCnPos_(-1), + subCnLen_(0), issCnPos_(-1), issCnLen_(0), signature_(0), + verify_(!noVerify) { issuer_[0] = 0; subject_[0] = 0; @@ -796,6 +797,13 @@ void CertDecoder::GetName(NameType nt) case COMMON_NAME: if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen))) return; + if (nt == ISSUER) { + issCnPos_ = (int)(ptr - strLen - issuer_); + issCnLen_ = (int)strLen; + } else { + subCnPos_ = (int)(ptr - strLen - subject_); + subCnLen_ = (int)strLen; + } break; case SUR_NAME: if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen))) diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index 3e15ce81489..5c9dc7ce117 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -470,10 +470,28 @@ inline void showPeer(SSL* ssl) char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0); char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0); - printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer, - subject); + X509_NAME_ENTRY* se = NULL; + ASN1_STRING* sd = NULL; + char* subCN = NULL; + + X509_NAME* sub = X509_get_subject_name(peer); + int lastpos = -1; + if (sub) + lastpos = X509_NAME_get_index_by_NID(sub, NID_commonName, lastpos); + if (lastpos >= 0) { + se = X509_NAME_get_entry(sub, lastpos); + if (se) + sd = X509_NAME_ENTRY_get_data(se); + if (sd) + subCN = (char*)ASN1_STRING_data(sd); + } + + printf("peer's cert info:\n issuer : %s\n subject: %s\n" + " subject cn: %s\n", issuer, subject, subCN); + free(subject); free(issuer); + } else printf("peer has no cert!\n"); From 777c2131dd7aeaf25adbbbbb0c213950e852f22b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sat, 2 Apr 2016 00:04:47 +0400 Subject: [PATCH 19/52] MDEV-9862 Illegal mix of collation, when comparing column with CASE expression --- mysql-test/r/ctype_cp850.result | 14 ++++++++++++++ mysql-test/t/ctype_cp850.test | 16 ++++++++++++++++ sql/item.h | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/ctype_cp850.result create mode 100644 mysql-test/t/ctype_cp850.test diff --git a/mysql-test/r/ctype_cp850.result b/mysql-test/r/ctype_cp850.result new file mode 100644 index 00000000000..c028f72b58a --- /dev/null +++ b/mysql-test/r/ctype_cp850.result @@ -0,0 +1,14 @@ +# +# Start of 5.5 tests +# +# +# MDEV-9862 Illegal mix of collation, when comparing column with CASE expression +# +SET NAMES cp850; +CREATE TABLE t1 (a CHAR(1) CHARACTER SET latin1); +SELECT a FROM t1 WHERE CASE a WHEN 'aaaa' THEN 'Y' WHEN 'aaaa' THEN 'Y' ELSE NULL END <> a; +a +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/ctype_cp850.test b/mysql-test/t/ctype_cp850.test new file mode 100644 index 00000000000..358829eb351 --- /dev/null +++ b/mysql-test/t/ctype_cp850.test @@ -0,0 +1,16 @@ +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-9862 Illegal mix of collation, when comparing column with CASE expression +--echo # +SET NAMES cp850; +CREATE TABLE t1 (a CHAR(1) CHARACTER SET latin1); +SELECT a FROM t1 WHERE CASE a WHEN 'aaaa' THEN 'Y' WHEN 'aaaa' THEN 'Y' ELSE NULL END <> a; +DROP TABLE t1; + + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/item.h b/sql/item.h index d09f6572487..41e6fe0e38e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2175,7 +2175,7 @@ public: max_length= 0; name= name_par ? name_par : (char*) "NULL"; fixed= 1; - collation.set(&my_charset_bin, DERIVATION_IGNORABLE); + collation.set(&my_charset_bin, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII); } enum Type type() const { return NULL_ITEM; } bool eq(const Item *item, bool binary_cmp) const; From c9e56d5ca9ebd0737ed543a7e1b3c990a8ab94fa Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 18 Apr 2016 17:38:05 +0200 Subject: [PATCH 20/52] 5.5.48-37.8 --- storage/xtradb/buf/buf0flu.c | 7 ++++-- storage/xtradb/handler/ha_innodb.cc | 2 +- storage/xtradb/handler/ha_innodb.h | 23 ++++++++++++++++++ storage/xtradb/handler/handler0alter.cc | 16 +++++++++++++ storage/xtradb/include/univ.i | 2 +- storage/xtradb/srv/srv0srv.c | 31 +++++++++++++------------ 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c index 0afdeb3fd02..88c4d29648b 100644 --- a/storage/xtradb/buf/buf0flu.c +++ b/storage/xtradb/buf/buf0flu.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2217,7 +2217,10 @@ buf_flush_stat_update(void) ib_uint64_t lsn; ulint n_flushed; - lsn = log_get_lsn(); + if (!log_peek_lsn(&lsn)) { + return; + } + if (buf_flush_stat_cur.redo == 0) { /* First time around. Just update the current LSN and return. */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index d9df6e6cc27..effff7cf0c4 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -4498,7 +4498,7 @@ building based on the assumption that there is no concurrent index creation/drop and DMLs that requires index lookup. All table handle will be closed before the index creation/drop. @return TRUE if index translation table built successfully */ -static +UNIV_INTERN ibool innobase_build_index_translation( /*=============================*/ diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 2324793767e..4f21dcff7e8 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -347,3 +347,26 @@ innobase_index_name_is_reserved( ulint num_of_keys); /*!< in: Number of indexes to be created. */ +/*******************************************************************//** +This function builds a translation table in INNOBASE_SHARE +structure for fast index location with mysql array number from its +table->key_info structure. This also provides the necessary translation +between the key order in mysql key_info and Innodb ib_table->indexes if +they are not fully matched with each other. +Note we do not have any mutex protecting the translation table +building based on the assumption that there is no concurrent +index creation/drop and DMLs that requires index lookup. All table +handle will be closed before the index creation/drop. +@return TRUE if index translation table built successfully */ +UNIV_INTERN +ibool +innobase_build_index_translation( +/*=============================*/ + const TABLE* table, /*!< in: table in MySQL data + dictionary */ + dict_table_t* ib_table, /*!< in: table in Innodb data + dictionary */ + INNOBASE_SHARE* share); /*!< in/out: share structure + where index translation table + will be constructed in. */ + diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index b4d63fc23b7..1c3c72e6245 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1082,6 +1082,22 @@ ha_innobase::final_add_index( trx_free_for_mysql(trx); + /* Rebuild index translation table now for temporary tables if we are + restoring secondary keys, as ha_innobase::open will not be called for + the next access. */ + if (add->indexed_table == prebuilt->table + && dict_table_is_temporary(prebuilt->table)) + { + if (!innobase_build_index_translation(add_arg->table, + prebuilt->table, share)) + { + /* We don't know whether index translation build failed + because of DD mismatch or OOM, return non-specific + error code. */ + err = -1; + } + } + /* There might be work for utility threads.*/ srv_active_wake_master_thread(); diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 46c1bd1b23c..4814a07d3a4 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 37.7 +#define PERCONA_INNODB_VERSION 37.8 #endif #define INNODB_VERSION_STR MYSQL_SERVER_VERSION diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index a830f22ba7d..26ad32cb1d1 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -2880,6 +2880,8 @@ exit_func: /*********************************************************************//** A thread which prints warnings about semaphore waits which have lasted too long. These can be used to track bugs which cause hangs. +Note: In order to make sync_arr_wake_threads_if_sema_free work as expected, +we should avoid waiting any mutexes in this function! @return a dummy parameter */ UNIV_INTERN os_thread_ret_t @@ -2917,23 +2919,22 @@ loop: /* Try to track a strange bug reported by Harald Fuchs and others, where the lsn seems to decrease at times */ + if (log_peek_lsn(&new_lsn)) { + if (new_lsn < old_lsn) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: old log sequence number %llu" + " was greater\n" + "InnoDB: than the new log sequence number %llu!\n" + "InnoDB: Please submit a bug report" + " to http://bugs.mysql.com\n", + old_lsn, new_lsn); + ut_ad(0); + } - new_lsn = log_get_lsn(); - - if (new_lsn < old_lsn) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: old log sequence number %llu" - " was greater\n" - "InnoDB: than the new log sequence number %llu!\n" - "InnoDB: Please submit a bug report" - " to http://bugs.mysql.com\n", - old_lsn, new_lsn); - ut_ad(0); + old_lsn = new_lsn; } - old_lsn = new_lsn; - if (difftime(time(NULL), srv_last_monitor_time) > 60) { /* We referesh InnoDB Monitor values so that averages are printed from at most 60 last seconds */ From 6fd54c01bb5bc480497b143d63181837148ff47f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 18 Apr 2016 23:15:15 +0400 Subject: [PATCH 21/52] MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null Item_func_ifnull::date_op() and Item_func_coalesce::date_op() could erroneously return 0000-00-00 instead of NULL when get_date() was called with the TIME_FUZZY_DATES flag, e.g. from LEAST(). --- mysql-test/r/type_date.result | 35 +++++++++++++++++++++++++++++++++++ mysql-test/t/type_date.test | 29 +++++++++++++++++++++++++++++ sql/item_cmpfunc.cc | 14 ++++---------- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 4e299ecf0b1..7678f038862 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -440,3 +440,38 @@ id select_type table type possible_keys key key_len ref rows Extra select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1; 1 drop table t1; +# +# MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null +# +CREATE TABLE t1 ( +id BIGINT NOT NULL, +date_debut DATE NOT NULL, +date_fin DATE DEFAULT NULL); +CREATE TABLE t2( +id BIGINT NOT NULL, +date_debut DATE NOT NULL, +date_fin DATE DEFAULT NULL); +INSERT INTO t1 VALUES (1,'2016-01-01','2016-01-31'); +INSERT INTO t1 VALUES (2,'2016-02-01',null); +INSERT INTO t1 VALUES (3,'2016-03-01','2016-03-31'); +INSERT INTO t1 VALUES (4,'2016-04-01',null); +INSERT INTO t2 VALUES (1,'2016-01-01','2016-01-31'); +INSERT INTO t2 VALUES (2,'2016-02-01','2016-01-28'); +INSERT INTO t2 VALUES (3,'2016-03-01',null); +INSERT INTO t2 VALUES (4,'2016-04-01',null); +SELECT t1.id, +GREATEST(t2.date_debut, t1.date_debut) AS date_debut, +LEAST(IFNULL(t2.date_fin, IFNULL(t1.date_fin, NULL)), +IFNULL(t1.date_fin, IFNULL(t2.date_fin, NULL))) AS date_fin +FROM t1 LEFT JOIN t2 ON (t1.id=t2.id); +id date_debut date_fin +1 2016-01-01 2016-01-31 00:00:00 +2 2016-02-01 2016-01-28 00:00:00 +3 2016-03-01 2016-03-31 00:00:00 +4 2016-04-01 NULL +DROP TABLE t1,t2; +SELECT +LEAST(COALESCE(DATE(NULL), DATE(NULL)), COALESCE(DATE(NULL), DATE(NULL))) AS d0, +LEAST(IFNULL(DATE(NULL), DATE(NULL)), IFNULL(DATE(NULL), DATE(NULL))) AS d1; +d0 d1 +NULL NULL diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 0b2ce16b7cc..4b058171ad2 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -386,3 +386,32 @@ select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1; select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1; drop table t1; +--echo # +--echo # MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null +--echo # +CREATE TABLE t1 ( + id BIGINT NOT NULL, + date_debut DATE NOT NULL, + date_fin DATE DEFAULT NULL); +CREATE TABLE t2( + id BIGINT NOT NULL, + date_debut DATE NOT NULL, + date_fin DATE DEFAULT NULL); +INSERT INTO t1 VALUES (1,'2016-01-01','2016-01-31'); +INSERT INTO t1 VALUES (2,'2016-02-01',null); +INSERT INTO t1 VALUES (3,'2016-03-01','2016-03-31'); +INSERT INTO t1 VALUES (4,'2016-04-01',null); + +INSERT INTO t2 VALUES (1,'2016-01-01','2016-01-31'); +INSERT INTO t2 VALUES (2,'2016-02-01','2016-01-28'); +INSERT INTO t2 VALUES (3,'2016-03-01',null); +INSERT INTO t2 VALUES (4,'2016-04-01',null); +SELECT t1.id, + GREATEST(t2.date_debut, t1.date_debut) AS date_debut, + LEAST(IFNULL(t2.date_fin, IFNULL(t1.date_fin, NULL)), + IFNULL(t1.date_fin, IFNULL(t2.date_fin, NULL))) AS date_fin +FROM t1 LEFT JOIN t2 ON (t1.id=t2.id); +DROP TABLE t1,t2; +SELECT + LEAST(COALESCE(DATE(NULL), DATE(NULL)), COALESCE(DATE(NULL), DATE(NULL))) AS d0, + LEAST(IFNULL(DATE(NULL), DATE(NULL)), IFNULL(DATE(NULL), DATE(NULL))) AS d1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 81688f3321c..9287b74a867 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2558,10 +2558,7 @@ bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate) DBUG_ASSERT(fixed == 1); if (!args[0]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) return (null_value= false); - if (!args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) - return (null_value= false); - bzero((char*) ltime,sizeof(*ltime)); - return null_value= !(fuzzydate & TIME_FUZZY_DATES); + return (null_value= args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)); } @@ -3311,15 +3308,12 @@ double Item_func_coalesce::real_op() bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate) { DBUG_ASSERT(fixed == 1); - null_value= 0; for (uint i= 0; i < arg_count; i++) { - bool res= args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES); - if (!args[i]->null_value) - return res; + if (!args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) + return (null_value= false); } - bzero((char*) ltime,sizeof(*ltime)); - return null_value|= !(fuzzydate & TIME_FUZZY_DATES); + return (null_value= true); } From 18ff6f654b1ca595fc5c0eebddbc1d0c5ee0d09e Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 19 Apr 2016 12:38:00 +0400 Subject: [PATCH 22/52] MDEV-9944 - main.events_2 fails sporadically Fixed wait condition in test case to actually wait for get_lock() completion (not for lock acquisition as it was before). This removes sporadic extra row in subsequent processlist queries. --- mysql-test/t/events_2.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/events_2.test b/mysql-test/t/events_2.test index 48949d5630b..5443f76d1a1 100644 --- a/mysql-test/t/events_2.test +++ b/mysql-test/t/events_2.test @@ -67,10 +67,10 @@ select /*2*/ user, host, db, command, state, info select release_lock("test_lock2"); drop event закачка; -# Wait for release_lock("test_lock2") to complete, +# Wait for get_lock("test_lock2") to complete, # to avoid polluting the next test information_schema.processlist let $wait_condition= select count(*) = 0 from information_schema.processlist - where (state like 'User lock%' AND info like 'select get_lock%'); + where info='select get_lock("test_lock2", 20)'; --source include/wait_condition.inc From 9c64735986042432a207d9183b61c6d675beaf71 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 29 Mar 2016 12:50:56 +0200 Subject: [PATCH 23/52] MDEV-9748 Include Twin (mysys_err.h is included twice in mysys/my_copy.c) --- mysys/my_copy.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 21de1e953a2..82cb2cc2f5f 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -18,7 +18,6 @@ #include "mysys_err.h" #include /* for stat */ #include -#include "mysys_err.h" #if defined(HAVE_UTIME_H) #include #elif defined(HAVE_SYS_UTIME_H) From edf71fd1d7b2d93c7f550d7b2cfecaf6b048fcec Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Apr 2016 10:28:03 +0200 Subject: [PATCH 24/52] MDEV-9928 LC_TIME_NAMES=de_AT; unusual name for february s/Feber/Februar/ --- mysql-test/r/locale.result | 11 +++++++++++ mysql-test/t/locale.test | 9 +++++++++ sql/sql_locale.cc | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result index aa61d8cd86f..195468c4c12 100644 --- a/mysql-test/r/locale.result +++ b/mysql-test/r/locale.result @@ -90,3 +90,14 @@ SELECT DATE_FORMAT('2001-01-07', '%w %a %W'); DATE_FORMAT('2001-01-07', '%w %a %W') 0 Du Duminică End of 5.4 tests +SET NAMES utf8; +SET lc_time_names=de_AT; +SELECT monthname('2001-01-01'); +monthname('2001-01-01') +Jänner +SELECT monthname('2001-02-01'); +monthname('2001-02-01') +Februar +SELECT monthname('2001-03-01'); +monthname('2001-03-01') +März diff --git a/mysql-test/t/locale.test b/mysql-test/t/locale.test index 04ac95cea06..899d293545d 100644 --- a/mysql-test/t/locale.test +++ b/mysql-test/t/locale.test @@ -54,3 +54,12 @@ SELECT DATE_FORMAT('2001-01-05', '%w %a %W'); SELECT DATE_FORMAT('2001-01-06', '%w %a %W'); SELECT DATE_FORMAT('2001-01-07', '%w %a %W'); --echo End of 5.4 tests + +# +# MDEV-9928 LC_TIME_NAMES=de_AT; unusual name for february +# +SET NAMES utf8; +SET lc_time_names=de_AT; +SELECT monthname('2001-01-01'); +SELECT monthname('2001-02-01'); +SELECT monthname('2001-03-01'); diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index 13e00c99f19..3123474a59b 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -426,7 +426,7 @@ MY_LOCALE my_locale_da_DK /***** LOCALE BEGIN de_AT: German - Austria *****/ static const char *my_locale_month_names_de_AT[13] = - {"Jänner","Feber","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember", NullS }; + {"Jänner","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember", NullS }; static const char *my_locale_ab_month_names_de_AT[13] = {"Jän","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez", NullS }; static const char *my_locale_day_names_de_AT[8] = From 4f133fbf7951d0f48860cdefe79416f930615dab Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Apr 2016 12:39:20 +0200 Subject: [PATCH 25/52] MDEV-9493 --tc-heuristic-recover option values off by one fix typelib to match defines: #define TC_HEURISTIC_RECOVER_COMMIT 1 #define TC_HEURISTIC_RECOVER_ROLLBACK 2 --- mysql-test/r/mysqld--help.result | 2 +- sql/mysqld.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 8bcad2a3cf5..ef68c064dd4 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1091,7 +1091,7 @@ sysdate-is-now FALSE table-cache 400 table-definition-cache 400 table-open-cache 400 -tc-heuristic-recover COMMIT +tc-heuristic-recover OFF thread-cache-size 0 thread-stack 294912 time-format %H:%i:%s diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 45fb49f9cd9..fb52041fbc2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -279,7 +279,7 @@ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *tc_heuristic_recover_names[]= { - "COMMIT", "ROLLBACK", NullS + "OFF", "COMMIT", "ROLLBACK", NullS }; static TYPELIB tc_heuristic_recover_typelib= { From 3294cd11f852357b638cac74ba32578ffb456fc7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Apr 2016 17:36:47 +0200 Subject: [PATCH 26/52] MDEV-9929 MariaDB segfaults on command "mysqld --version" with ignore-db-dir option on /etc/my.cnf don't put command-line arguments into opt_ignore_db_dirs - it is supposed to contain a malloc()'ed accumulated list of all ignored dirs --- sql/mysqld.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fb52041fbc2..3450447ceb9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7800,6 +7800,7 @@ mysqld_get_one_option(int optid, case OPT_IGNORE_DB_DIRECTORY: + opt_ignore_db_dirs= NULL; // will be set in ignore_db_dirs_process_additions if (*argument == 0) ignore_db_dirs_reset(); else From 95fe71afa6f1243af63429c5295b8b4bd74d6459 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 17 Apr 2016 18:51:54 +0200 Subject: [PATCH 27/52] MDEV-9707 MAX(timestamp(6) column) in correlated sub-query returns non-existent row data in original table special treatment for temporal values in create_tmp_field_from_item(). old code only did it when result_type() was STRING_RESULT, but Item_cache_temporal::result_type() is INT_RESULT --- mysql-test/r/cache_temporal_4265.result | 13 +++++++++++++ mysql-test/t/cache_temporal_4265.test | 11 +++++++++++ sql/sql_select.cc | 17 +++++++++-------- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/cache_temporal_4265.result b/mysql-test/r/cache_temporal_4265.result index 1b4b3c2c4aa..7f215de43fb 100644 --- a/mysql-test/r/cache_temporal_4265.result +++ b/mysql-test/r/cache_temporal_4265.result @@ -7,4 +7,17 @@ a 2002-03-04 Warnings: Note 1003 2000-01-01 +set debug_dbug=''; +drop table t1; +create table t1 (id int not null, ut timestamp(6) not null); +insert into t1 values(1, '2001-01-01 00:00:00.2'); +insert into t1 values(1, '2001-01-01 00:00:00.1'); +select * from t1; +id ut +1 2001-01-01 00:00:00.200000 +1 2001-01-01 00:00:00.100000 +select (select max(m2.ut) from t1 m2 where m1.id <> 0) from t1 m1; +(select max(m2.ut) from t1 m2 where m1.id <> 0) +2001-01-01 00:00:00.200000 +2001-01-01 00:00:00.200000 drop table t1; diff --git a/mysql-test/t/cache_temporal_4265.test b/mysql-test/t/cache_temporal_4265.test index 6135438f023..c62f3c3c506 100644 --- a/mysql-test/t/cache_temporal_4265.test +++ b/mysql-test/t/cache_temporal_4265.test @@ -7,5 +7,16 @@ create table t1 (a date); insert t1 values ('2000-01-02'), ('2001-02-03'), ('2002-03-04'); set debug_dbug='d,str_to_datetime_warn'; select * from t1 where a > date_add('2000-01-01', interval 5 day); +set debug_dbug=''; +drop table t1; + +# +# MDEV-9707 MAX(timestamp(6) column) in correlated sub-query returns non-existent row data in original table +# +create table t1 (id int not null, ut timestamp(6) not null); +insert into t1 values(1, '2001-01-01 00:00:00.2'); +insert into t1 values(1, '2001-01-01 00:00:00.1'); +select * from t1; +select (select max(m2.ut) from t1 m2 where m1.id <> 0) from t1 m1; drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b1e22537b37..828dab7ef99 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14544,6 +14544,14 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, Field *new_field; LINT_INIT(new_field); + /* + To preserve type or DATE/TIME and GEOMETRY fields, + they need to be handled separately. + */ + if (item->cmp_type() == TIME_RESULT || + item->field_type() == MYSQL_TYPE_GEOMETRY) + new_field= item->tmp_table_field_from_field_type(table, 1); + else switch (item->result_type()) { case REAL_RESULT: new_field= new Field_double(item->max_length, maybe_null, @@ -14566,18 +14574,11 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, case STRING_RESULT: DBUG_ASSERT(item->collation.collation); - /* - DATE/TIME and GEOMETRY fields have STRING_RESULT result type. - To preserve type they needed to be handled separately. - */ - if (item->cmp_type() == TIME_RESULT || - item->field_type() == MYSQL_TYPE_GEOMETRY) - new_field= item->tmp_table_field_from_field_type(table, 1); /* Make sure that the blob fits into a Field_varstring which has 2-byte lenght. */ - else if (item->max_length/item->collation.collation->mbmaxlen > 255 && + if (item->max_length/item->collation.collation->mbmaxlen > 255 && convert_blob_length <= Field_varstring::MAX_SIZE && convert_blob_length) new_field= new Field_varstring(convert_blob_length, maybe_null, From ce355304e6ecd47c4e65d437267842acb8aae6b7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 17 Apr 2016 19:52:15 +0200 Subject: [PATCH 28/52] MDEV-9885 Client doesn't start if 'TERM' unknown 1. don't exit if setupterm() failed 2. don't use vidattr() if setupterm() failed --- client/mysql.cc | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index d33f8b186a0..65af4b8ddb8 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -95,9 +95,16 @@ extern "C" { #endif } -#if !defined(HAVE_VIDATTR) -#undef vidattr -#define vidattr(A) {} // Can't get this to work +#ifdef HAVE_VIDATTR +static int have_curses= 0; +static void my_vidattr(chtype attrs) +{ + if (have_curses) + vidattr(attrs); +} +#else +#undef HAVE_SETUPTERM +#define my_vidattr(A) {} // Can't get this to work #endif #ifdef FN_NO_CASE_SENSE @@ -4726,9 +4733,9 @@ com_status(String *buffer __attribute__((unused)), if (skip_updates) { - vidattr(A_BOLD); + my_vidattr(A_BOLD); tee_fprintf(stdout, "\nAll updates ignored to this database\n"); - vidattr(A_NORMAL); + my_vidattr(A_NORMAL); } #ifdef USE_POPEN tee_fprintf(stdout, "Current pager:\t\t%s\n", pager); @@ -4796,9 +4803,9 @@ com_status(String *buffer __attribute__((unused)), } if (safe_updates) { - vidattr(A_BOLD); + my_vidattr(A_BOLD); tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n"); - vidattr(A_NORMAL); + my_vidattr(A_NORMAL); tee_fprintf(stdout, "\ UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\ (One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n\ @@ -4891,9 +4898,10 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) { if (!inited) { + int errret; inited=1; #ifdef HAVE_SETUPTERM - (void) setupterm((char *)0, 1, (int *) 0); + have_curses= setupterm((char *)0, 1, &errret) != ERR; #endif } if (info_type == INFO_ERROR) @@ -4906,7 +4914,7 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) putchar('\a'); /* This should make a bell */ #endif } - vidattr(A_STANDOUT); + my_vidattr(A_STANDOUT); if (error) { if (sqlstate) @@ -4925,9 +4933,9 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) tee_fputs(": ", file); } else - vidattr(A_BOLD); + my_vidattr(A_BOLD); (void) tee_puts(str, file); - vidattr(A_NORMAL); + my_vidattr(A_NORMAL); } if (unbuffered) fflush(file); From 608c0e1c22ea6e2348bbb64d92d8c62d9c3410e8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 18 Apr 2016 11:57:34 +0200 Subject: [PATCH 29/52] MDEV-5982 `make` fail @ ".../libmysql_versions.ld:155:9: invalid use of VERSION in input file" add a workaround for gold --- libmysql/CMakeLists.txt | 46 +++++++++++++++++++++++++++++--- libmysql/libmysql_versions.ld.in | 16 ++--------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index e611efae65a..76156302c12 100644 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -251,6 +251,25 @@ SET(CLIENT_API_FUNCTIONS ) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + IF (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING) + + INCLUDE (CheckCSourceCompiles) + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.ld" + "VERSION {\nlibmysqlclient_18 {\nglobal: *;\n};\n}\n") + SET(CMAKE_REQUIRED_LIBRARIES "-Wl,src.ld") + CHECK_C_SOURCE_COMPILES("int main() { return 0; }" + SUPPORTS_VERSION_IN_LINK_SCRIPT) + SET(CMAKE_REQUIRED_LIBRARIES) + + IF (NOT SUPPORTS_VERSION_IN_LINK_SCRIPT) + # https://sourceware.org/bugzilla/show_bug.cgi?id=16895 + MESSAGE(SEND_ERROR "Your current linker does not support VERSION " + "command in linker scripts like a GNU ld or any compatible linker " + "should. Perhaps you're using gold? Either switch to GNU ld compatible " + "linker or run cmake with -DDISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING=TRUE " + "to be able to complete the build") + ENDIF (NOT SUPPORTS_VERSION_IN_LINK_SCRIPT) + # When building RPM, or DEB package on Debian, use ELF symbol versioning # for compatibility with distribution packages, so client shared library can # painlessly replace the one supplied by the distribution. @@ -335,14 +354,26 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") make_scrambled_password_323 ) - # Linker script to version symbols in Fedora- and Debian- compatible way, MDEV-5529 - SET(VERSION_SCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/libmysql_versions.ld.in) - # Generate version script. # Create semicolon separated lists of functions to export from # Since RPM packages use separate versioning for 5.1 API # and 5.5 API (libmysqlclient_16 vs libmysqlclient_18), # we need 2 lists. + SET (VERSION_HEADER +"VERSION { + libmysqlclient_18 { + global:") + SET (VERSION_FOOTER +" local: + *; + }; + + libmysqlclient_16 { + /* empty here. aliases are added above */ + }; +} +") + SET (CLIENT_API_5_1_LIST) SET (CLIENT_API_5_1_ALIASES) FOREACH (f ${CLIENT_API_FUNCTIONS_5_1} ${CLIENT_API_5_1_EXTRA}) @@ -355,6 +386,13 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(CLIENT_API_5_5_LIST "${CLIENT_API_5_5_LIST}\t${f};\n") ENDFOREACH() + ELSE (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING) + SET (CLIENT_API_5_1_ALIASES "/* Versioning disabled per user request. MDEV-5982 */") + ENDIF (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING) + + # Linker script to version symbols in Fedora- and Debian- compatible way, MDEV-5529 + SET(VERSION_SCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/libmysql_versions.ld.in) + CONFIGURE_FILE( ${VERSION_SCRIPT_TEMPLATE} ${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld @@ -363,7 +401,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(VERSION_SCRIPT_LINK_FLAGS "-Wl,${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld") -ENDIF() +ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(CLIENT_SOURCES diff --git a/libmysql/libmysql_versions.ld.in b/libmysql/libmysql_versions.ld.in index 8d97da5b2eb..0cf5b45cc18 100644 --- a/libmysql/libmysql_versions.ld.in +++ b/libmysql/libmysql_versions.ld.in @@ -27,19 +27,7 @@ mysql_get_charset_by_csname = get_charset_by_csname; mysql_net_realloc = net_realloc; mysql_client_errors = client_errors; -VERSION { - -libmysqlclient_18 { - global: +@VERSION_HEADER@ @CLIENT_API_5_1_LIST@ @CLIENT_API_5_5_LIST@ - - local: - *; -}; - -libmysqlclient_16 { - /* empty here. aliases are added above */ -}; - -} +@VERSION_FOOTER@ From cc04a9fc0f60610d900f27ef60f8916a4ce1bb4c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 18 Apr 2016 18:30:42 +0200 Subject: [PATCH 30/52] MDEV-9835 Valid password is not working after server restart On SET PASSWORD if the plugin is mysql_native_password or mysql_old_password, do reset plugin and auth_str fields. --- mysql-test/r/set_password_plugin-9835.result | 158 +++++++++++++++++++ mysql-test/t/set_password_plugin-9835.test | 128 +++++++++++++++ sql/sql_acl.cc | 17 +- 3 files changed, 298 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/set_password_plugin-9835.result create mode 100644 mysql-test/t/set_password_plugin-9835.test diff --git a/mysql-test/r/set_password_plugin-9835.result b/mysql-test/r/set_password_plugin-9835.result new file mode 100644 index 00000000000..e9ee09fe952 --- /dev/null +++ b/mysql-test/r/set_password_plugin-9835.result @@ -0,0 +1,158 @@ +create user natauth@localhost identified via 'mysql_native_password' using '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user newpass@localhost identified by password '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user newpassnat@localhost identified via 'mysql_native_password'; +set password for newpassnat@localhost = '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user oldauth@localhost identified with 'mysql_old_password' using '378b243e220ca493'; +create user oldpass@localhost identified by password '378b243e220ca493'; +create user oldpassold@localhost identified with 'mysql_old_password'; +set password for oldpassold@localhost = '378b243e220ca493'; +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; +user host password plugin authentication_string +natauth localhost mysql_native_password *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +newpass localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +newpassnat localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +oldauth localhost mysql_old_password 378b243e220ca493 +oldpass localhost 378b243e220ca493 +oldpassold localhost 378b243e220ca493 +connect con,localhost,natauth,test,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +flush privileges; +connect con,localhost,natauth,test,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +set password for natauth@localhost = PASSWORD('test2'); +set password for newpass@localhost = PASSWORD('test2'); +set password for newpassnat@localhost = PASSWORD('test2'); +set password for oldauth@localhost = PASSWORD('test2'); +set password for oldpass@localhost = PASSWORD('test2'); +set password for oldpassold@localhost = PASSWORD('test2'); +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; +user host password plugin authentication_string +natauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpassnat localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpassold localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +connect con,localhost,natauth,test2,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test2,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test2,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test2,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test2,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test2,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +flush privileges; +connect con,localhost,natauth,test2,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test2,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test2,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test2,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test2,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test2,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +drop user natauth@localhost, newpass@localhost, newpassnat@localhost; +drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; diff --git a/mysql-test/t/set_password_plugin-9835.test b/mysql-test/t/set_password_plugin-9835.test new file mode 100644 index 00000000000..a10a339540f --- /dev/null +++ b/mysql-test/t/set_password_plugin-9835.test @@ -0,0 +1,128 @@ +# +# MDEV-9835 Valid password is not working after server restart. +# +# Various combinations of SET PASSWORD and not-empty mysql.user.plugin field +# +--source include/not_embedded.inc + +--enable_connect_log + +# The hash (old and new) is for 'test' +create user natauth@localhost identified via 'mysql_native_password' using '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user newpass@localhost identified by password '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user newpassnat@localhost identified via 'mysql_native_password'; +set password for newpassnat@localhost = '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user oldauth@localhost identified with 'mysql_old_password' using '378b243e220ca493'; + +create user oldpass@localhost identified by password '378b243e220ca493'; + +create user oldpassold@localhost identified with 'mysql_old_password'; +set password for oldpassold@localhost = '378b243e220ca493'; + +--sorted_result +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; + +--connect(con,localhost,natauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test,) +select current_user(); +--disconnect con + +--connection default + +flush privileges; + +--connect(con,localhost,natauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test,) +select current_user(); +--disconnect con + +--connection default + +# changing to the NEW password hash +set password for natauth@localhost = PASSWORD('test2'); +set password for newpass@localhost = PASSWORD('test2'); +set password for newpassnat@localhost = PASSWORD('test2'); +set password for oldauth@localhost = PASSWORD('test2'); +set password for oldpass@localhost = PASSWORD('test2'); +set password for oldpassold@localhost = PASSWORD('test2'); + +--sorted_result +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; + +--connect(con,localhost,natauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test2,) +select current_user(); +--disconnect con + +--connection default + +flush privileges; + +--connect(con,localhost,natauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test2,) +select current_user(); +--disconnect con + +--connection default +drop user natauth@localhost, newpass@localhost, newpassnat@localhost; +drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; + diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index da7c3f17c63..de76f27dee6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -557,9 +557,8 @@ static void init_check_host(void); static void rebuild_check_host(void); static ACL_USER *find_acl_user(const char *host, const char *user, my_bool exact); -static bool update_user_table(THD *thd, TABLE *table, const char *host, - const char *user, const char *new_password, - uint new_password_len); +static bool update_user_table(THD *, TABLE *, const char *, const char *, const + char *, uint, bool); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); static inline void get_grantor(THD *thd, char* grantor); @@ -1912,6 +1911,7 @@ bool change_password(THD *thd, const char *host, const char *user, bool save_binlog_row_based; uint new_password_len= (uint) strlen(new_password); bool result= 1; + bool use_salt= 0; DBUG_ENTER("change_password"); DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", host,user,new_password)); @@ -1967,6 +1967,7 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->auth_string.length= new_password_len; set_user_salt(acl_user, new_password, new_password_len); set_user_plugin(acl_user, new_password_len); + use_salt= 1; } else push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -1975,7 +1976,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (update_user_table(thd, table, acl_user->host.hostname ? acl_user->host.hostname : "", acl_user->user ? acl_user->user : "", - new_password, new_password_len)) + new_password, new_password_len, use_salt)) { mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */ goto end; @@ -2223,7 +2224,8 @@ bool hostname_requires_resolving(const char *hostname) static bool update_user_table(THD *thd, TABLE *table, const char *host, const char *user, - const char *new_password, uint new_password_len) + const char *new_password, uint new_password_len, + bool reset_plugin) { char user_key[MAX_KEY_LENGTH]; int error; @@ -2246,6 +2248,11 @@ static bool update_user_table(THD *thd, TABLE *table, } store_record(table,record[1]); table->field[2]->store(new_password, new_password_len, system_charset_info); + if (reset_plugin && table->s->fields >= 41) + { + table->field[40]->reset(); + table->field[41]->reset(); + } if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { From 1bc0b0b5245977172e2c3a3c64a42a2c4e762e06 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 19 Apr 2016 11:08:16 +0200 Subject: [PATCH 31/52] fix a couple of dbug tests not to write to /tmp --- mysql-test/r/mdev6830.result | 3 +-- mysql-test/r/select_debug.result | 2 +- mysql-test/t/mdev6830-master.opt | 1 - mysql-test/t/mdev6830.test | 10 +++++----- mysql-test/t/select_debug.test | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 mysql-test/t/mdev6830-master.opt diff --git a/mysql-test/r/mdev6830.result b/mysql-test/r/mdev6830.result index 0570659e860..d1cf8c98ac1 100644 --- a/mysql-test/r/mdev6830.result +++ b/mysql-test/r/mdev6830.result @@ -1,5 +1,4 @@ -drop table if exists t1,t2,t3; -drop view if exists v2,v3; +set @@debug_dbug= 'd,opt'; CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM; CREATE TABLE t2 ( f1 DATE, diff --git a/mysql-test/r/select_debug.result b/mysql-test/r/select_debug.result index a056affc2cd..55882ad337a 100644 --- a/mysql-test/r/select_debug.result +++ b/mysql-test/r/select_debug.result @@ -6,7 +6,7 @@ insert into t1 values (2,2), (1,1); create table t2 (a int); insert into t2 values (2), (3); set session join_cache_level=3; -set @@debug_dbug= 'd:t:O,/tmp/trace.out'; +set @@debug_dbug= 'd,opt'; explain select t1.b from t1,t2 where t1.b=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where diff --git a/mysql-test/t/mdev6830-master.opt b/mysql-test/t/mdev6830-master.opt deleted file mode 100644 index 2a8c27d4731..00000000000 --- a/mysql-test/t/mdev6830-master.opt +++ /dev/null @@ -1 +0,0 @@ ---debug diff --git a/mysql-test/t/mdev6830.test b/mysql-test/t/mdev6830.test index 24565d04fed..3898d5bbef6 100644 --- a/mysql-test/t/mdev6830.test +++ b/mysql-test/t/mdev6830.test @@ -1,10 +1,10 @@ - +# +# MDEV-6830 Server crashes in best_access_path after a sequence of SELECTs invollving a temptable view +# --source include/have_debug.inc ---disable_warnings -drop table if exists t1,t2,t3; -drop view if exists v2,v3; ---enable_warnings +set @@debug_dbug= 'd,opt'; + CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM; CREATE TABLE t2 ( diff --git a/mysql-test/t/select_debug.test b/mysql-test/t/select_debug.test index 4b77f9fd047..49415400db3 100644 --- a/mysql-test/t/select_debug.test +++ b/mysql-test/t/select_debug.test @@ -10,7 +10,7 @@ create table t2 (a int); insert into t2 values (2), (3); set session join_cache_level=3; -set @@debug_dbug= 'd:t:O,/tmp/trace.out'; +set @@debug_dbug= 'd,opt'; explain select t1.b from t1,t2 where t1.b=t2.a; select t1.b from t1,t2 where t1.b=t2.a; From 6c0e231c0282b43d6a46a4983f5971e960d3b8ca Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 19 Apr 2016 14:05:52 +0400 Subject: [PATCH 32/52] MDEV-9945 - main.kill_processlist-6619 fails sporadically SHOW PROCESSLIST output can be affected by not completed concurrent queries. Removed this affected SHOW PROCESSLIST since it doesn't seem to affect original problem. --- mysql-test/r/kill_processlist-6619.result | 4 ---- mysql-test/t/kill_processlist-6619.test | 2 -- 2 files changed, 6 deletions(-) diff --git a/mysql-test/r/kill_processlist-6619.result b/mysql-test/r/kill_processlist-6619.result index 588c8e6d139..a3d971e2115 100644 --- a/mysql-test/r/kill_processlist-6619.result +++ b/mysql-test/r/kill_processlist-6619.result @@ -1,8 +1,4 @@ connect con1,localhost,root,,; -SHOW PROCESSLIST; -Id User Host db Command Time State Info Progress -# root # test Sleep # # NULL 0.000 -# root # test Query # # SHOW PROCESSLIST 0.000 connection default; KILL QUERY con_id; connection con1; diff --git a/mysql-test/t/kill_processlist-6619.test b/mysql-test/t/kill_processlist-6619.test index 2333f02eac6..d73859ce8cd 100644 --- a/mysql-test/t/kill_processlist-6619.test +++ b/mysql-test/t/kill_processlist-6619.test @@ -5,8 +5,6 @@ --enable_connect_log --connect (con1,localhost,root,,) --let $con_id = `SELECT CONNECTION_ID()` ---replace_column 1 # 3 # 6 # 7 # -SHOW PROCESSLIST; --connection default --replace_result $con_id con_id eval KILL QUERY $con_id; From 9a987142f93756b37b2ff02d513034cc4079c978 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 20 Apr 2016 08:53:30 +0400 Subject: [PATCH 33/52] MDEV-9745 Crash with CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 4 END This is a backport of the patch for MDEV-9653 (fixed earlier in 10.1.13). The code in Item_func_case::fix_length_and_dec() did not calculate max_length and decimals properly. In case of any numeric result (DECIMAL, REAL, INT) a generic method Item_func_case::agg_num_lengths() was called, which could erroneously result into a DECIMAL item with max_length==0 and decimals==0, so the constructor of Field_new_decimals tried to create a field of DECIMAL(0,0) type, which caused a crash. Unlike Item_func_case, the code responsible for merging attributes in Item_func_coalesce::fix_length_and_dec() works fine: it has specific execution branches for all distinct numeric types and correctly creates a DECIMAL(1,0) column instead of DECIMAL(0,0) for the same set of arguments. The fix does the following: - Moves the attribute merging code from Item_func_coalesce::fix_length_and_dec() to a new method Item_func_hybrid_result_type::fix_attributes() - Removes the wrong code from Item_func_case::fix_length_and_dec() and reuses fix_attributes() in both Item_func_coalesce::fix_length_and_dec() and Item_func_case::fix_length_and_dec() - Fixes count_real_length() and count_decimal_length() to get an array of Items as an argument, instead of using Item::args directly. This is needed for Item_func_case::fix_length_and_dec(). - Moves methods Item_func::count_xxx_length() from "public" to "protected". - Removes Item_func_case::agg_num_length(), as it's not used any more. - Additionally removes Item_func_case::agg_str_length(), as it also was not used (dead code). --- mysql-test/r/case.result | 13 ++++++++++ mysql-test/t/case.test | 9 +++++++ sql/item_cmpfunc.cc | 51 ++++++++++++++-------------------------- sql/item_cmpfunc.h | 2 -- sql/item_func.cc | 22 ++++++++--------- sql/item_func.h | 15 ++++++------ 6 files changed, 59 insertions(+), 53 deletions(-) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 3852da5d4b0..274d5da7d1c 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -231,3 +231,16 @@ case t1.f1 when '00:00:00' then 1 end 1 NULL drop table t1; +# +# MDEV-9745 Crash with CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 4 END +# +CREATE TABLE t1 SELECT CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 4 END AS a; +DESCRIBE t1; +Field Type Null Key Default Extra +a decimal(1,0) YES NULL +DROP TABLE t1; +CREATE TABLE t1 SELECT CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 40 END AS a; +DESCRIBE t1; +Field Type Null Key Default Extra +a decimal(2,0) YES NULL +DROP TABLE t1; diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index f536f556780..c127836d352 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -193,3 +193,12 @@ insert t1 values ('00:00:00'),('00:01:00'); select case t1.f1 when '00:00:00' then 1 end from t1; drop table t1; +--echo # +--echo # MDEV-9745 Crash with CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 4 END +--echo # +CREATE TABLE t1 SELECT CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 4 END AS a; +DESCRIBE t1; +DROP TABLE t1; +CREATE TABLE t1 SELECT CASE WHEN TRUE THEN COALESCE(CAST(NULL AS UNSIGNED)) ELSE 40 END AS a; +DESCRIBE t1; +DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 9287b74a867..fb75c9af794 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3015,24 +3015,6 @@ bool Item_func_case::fix_fields(THD *thd, Item **ref) } -void Item_func_case::agg_str_lengths(Item* arg) -{ - fix_char_length(max(max_char_length(), arg->max_char_length())); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - -void Item_func_case::agg_num_lengths(Item *arg) -{ - uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, - arg->unsigned_flag) - arg->decimals; - set_if_bigger(max_length, len); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - /** Check if (*place) and new_value points to different Items and call THD::change_item_tree() if needed. @@ -3098,17 +3080,7 @@ void Item_func_case::fix_length_and_dec() } else { - collation.set_numeric(); - max_length=0; - decimals=0; - unsigned_flag= TRUE; - for (uint i= 0; i < ncases; i+= 2) - agg_num_lengths(args[i + 1]); - if (else_expr_num != -1) - agg_num_lengths(args[else_expr_num]); - max_length= my_decimal_precision_to_length_no_truncation(max_length + - decimals, decimals, - unsigned_flag); + fix_attributes(agg, nagg); } /* @@ -3336,19 +3308,32 @@ void Item_func_coalesce::fix_length_and_dec() { cached_field_type= agg_field_type(args, arg_count); agg_result_type(&cached_result_type, args, arg_count); + fix_attributes(args, arg_count); +} + + +#if MYSQL_VERSION_ID > 100100 +#error Rename this to Item_hybrid_func::fix_attributes() when mering to 10.1 +#endif +void Item_func_hybrid_result_type::fix_attributes(Item **items, uint nitems) +{ switch (cached_result_type) { case STRING_RESULT: - if (count_string_result_length(cached_field_type, args, arg_count)) + if (count_string_result_length(field_type(), + items, nitems)) return; break; case DECIMAL_RESULT: - count_decimal_length(); + collation.set_numeric(); + count_decimal_length(items, nitems); break; case REAL_RESULT: - count_real_length(); + collation.set_numeric(); + count_real_length(items, nitems); break; case INT_RESULT: - count_only_length(args, arg_count); + collation.set_numeric(); + count_only_length(items, nitems); decimals= 0; break; case ROW_RESULT: diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 0faba016ba8..0194f9cd0e0 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1255,8 +1255,6 @@ public: Item *find_item(String *str); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } void cleanup(); - void agg_str_lengths(Item *arg); - void agg_num_lengths(Item *arg); }; /* diff --git a/sql/item_func.cc b/sql/item_func.cc index 252ca9e504b..bd6553d45d4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -641,16 +641,16 @@ void Item_func::count_datetime_length(Item **item, uint nitems) result length/precision depends on argument ones. */ -void Item_func::count_decimal_length() +void Item_func::count_decimal_length(Item **item, uint nitems) { int max_int_part= 0; decimals= 0; unsigned_flag= 1; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=0 ; i < nitems ; i++) { - set_if_bigger(decimals, args[i]->decimals); - set_if_bigger(max_int_part, args[i]->decimal_int_part()); - set_if_smaller(unsigned_flag, args[i]->unsigned_flag); + set_if_bigger(decimals, item[i]->decimals); + set_if_bigger(max_int_part, item[i]->decimal_int_part()); + set_if_smaller(unsigned_flag, item[i]->unsigned_flag); } int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION); fix_char_length(my_decimal_precision_to_length_no_truncation(precision, @@ -681,19 +681,19 @@ void Item_func::count_only_length(Item **item, uint nitems) result length/precision depends on argument ones. */ -void Item_func::count_real_length() +void Item_func::count_real_length(Item **item, uint nitems) { uint32 length= 0; decimals= 0; max_length= 0; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=0 ; i < nitems ; i++) { if (decimals != NOT_FIXED_DEC) { - set_if_bigger(decimals, args[i]->decimals); - set_if_bigger(length, (args[i]->max_length - args[i]->decimals)); + set_if_bigger(decimals, item[i]->decimals); + set_if_bigger(length, (item[i]->max_length - item[i]->decimals)); } - set_if_bigger(max_length, args[i]->max_length); + set_if_bigger(max_length, item[i]->max_length); } if (decimals != NOT_FIXED_DEC) { @@ -811,7 +811,7 @@ void Item_num_op::fix_length_and_dec(void) if (r0 == REAL_RESULT || r1 == REAL_RESULT || r0 == STRING_RESULT || r1 ==STRING_RESULT) { - count_real_length(); + count_real_length(args, arg_count); max_length= float_length(decimals); cached_result_type= REAL_RESULT; } diff --git a/sql/item_func.h b/sql/item_func.h index 33fa49f9168..9776ec0a5b7 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -39,6 +39,13 @@ protected: 0 means get this number from first argument */ uint allowed_arg_cols; + + void count_only_length(Item **item, uint nitems); + void count_real_length(Item **item, uint nitems); + void count_decimal_length(Item **item, uint nitems); + void count_datetime_length(Item **item, uint nitems); + bool count_string_result_length(enum_field_types field_type, + Item **item, uint nitems); public: uint arg_count; table_map used_tables_cache, not_null_tables_cache; @@ -146,16 +153,10 @@ public: virtual void print(String *str, enum_query_type query_type); void print_op(String *str, enum_query_type query_type); void print_args(String *str, uint from, enum_query_type query_type); - void count_only_length(Item **item, uint nitems); - void count_real_length(); - void count_decimal_length(); inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { return (null_value=args[0]->get_date(ltime, fuzzy_date)); } - void count_datetime_length(Item **item, uint nitems); - bool count_string_result_length(enum_field_types field_type, - Item **item, uint nitems); inline bool get_arg0_time(MYSQL_TIME *ltime) { null_value= args[0]->get_time(ltime); @@ -436,7 +437,7 @@ class Item_func_hybrid_result_type: public Item_func } protected: Item_result cached_result_type; - + void fix_attributes(Item **item, uint nitems); public: Item_func_hybrid_result_type() :Item_func(), cached_result_type(REAL_RESULT) { collation.set_numeric(); } From 2564650fb91faec3e409d6ffe369c82252042710 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 20 Apr 2016 11:02:34 +0400 Subject: [PATCH 34/52] MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) The patch for MDEV-9745 earlier fixed the problem reported in MDEV-9662 as well. Only adding tests. --- mysql-test/include/ctype_numconv.inc | 6 ++++++ mysql-test/r/ctype_binary.result | 9 +++++++++ mysql-test/r/ctype_cp1251.result | 9 +++++++++ mysql-test/r/ctype_latin1.result | 9 +++++++++ mysql-test/r/ctype_ucs.result | 9 +++++++++ mysql-test/r/ctype_utf8.result | 9 +++++++++ 6 files changed, 51 insertions(+) diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 25314d53fba..9b21e7f38c1 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -1794,6 +1794,12 @@ SELECT f1() FROM t1 LEFT JOIN (SELECT 1 AS a FROM t1 LIMIT 0) AS d ON 1 GROUP BY DROP FUNCTION f1; DROP TABLE t1; +--echo # +--echo # MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +--echo # +SELECT @@collation_connection; +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; + --echo # --echo # MDEV-5702 Incorrect results are returned with NULLIF() --echo # diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 73c81c4eb06..e7bf1238210 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -2849,6 +2849,15 @@ f1() DROP FUNCTION f1; DROP TABLE t1; # +# MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +# +SELECT @@collation_connection; +@@collation_connection +binary +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; +CASE 1 WHEN 2 THEN ( - '3' ) END +NULL +# # MDEV-5702 Incorrect results are returned with NULLIF() # CREATE TABLE t1 (d DATE); diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index 313f60ef276..2a7d4ed1fb4 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -3241,6 +3241,15 @@ f1() DROP FUNCTION f1; DROP TABLE t1; # +# MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +# +SELECT @@collation_connection; +@@collation_connection +cp1251_general_ci +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; +CASE 1 WHEN 2 THEN ( - '3' ) END +NULL +# # MDEV-5702 Incorrect results are returned with NULLIF() # CREATE TABLE t1 (d DATE); diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 11a9479afa3..dc96495b1ac 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -3423,6 +3423,15 @@ f1() DROP FUNCTION f1; DROP TABLE t1; # +# MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +# +SELECT @@collation_connection; +@@collation_connection +latin1_swedish_ci +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; +CASE 1 WHEN 2 THEN ( - '3' ) END +NULL +# # MDEV-5702 Incorrect results are returned with NULLIF() # CREATE TABLE t1 (d DATE); diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index f9e9a69de42..96e0970e4a6 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -4239,6 +4239,15 @@ f1() DROP FUNCTION f1; DROP TABLE t1; # +# MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +# +SELECT @@collation_connection; +@@collation_connection +ucs2_general_ci +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; +CASE 1 WHEN 2 THEN ( - '3' ) END +NULL +# # MDEV-5702 Incorrect results are returned with NULLIF() # CREATE TABLE t1 (d DATE); diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 09bb5195b74..217d3ca26d8 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -5060,6 +5060,15 @@ f1() DROP FUNCTION f1; DROP TABLE t1; # +# MDEV-9662 Assertion `precision || !scale' failed in my_decimal_precision_to_length_no_truncation(uint, uint8, bool) +# +SELECT @@collation_connection; +@@collation_connection +utf8_general_ci +SELECT CASE 1 WHEN 2 THEN ( - '3' ) END; +CASE 1 WHEN 2 THEN ( - '3' ) END +NULL +# # MDEV-5702 Incorrect results are returned with NULLIF() # CREATE TABLE t1 (d DATE); From e90f8b7a683a47b47417d847b69c52e2138e2259 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 20 Apr 2016 11:11:13 +0400 Subject: [PATCH 35/52] MDEV-9413 "datetime >= coalesce(c1(NULL))" doesn't return expected NULL The patch for MDEV-9521 earlier fixed the problem reported in MDEV-9413. Only adding tests. --- mysql-test/r/type_timestamp.result | 9 +++++++++ mysql-test/t/type_timestamp.test | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 52c7f05839e..1f17247b02a 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -644,4 +644,13 @@ SELECT MAX(dt) = '2011-01-06 12:34:30' FROM t1; MAX(dt) = '2011-01-06 12:34:30' 1 DROP TABLE t1; +# +# MDEV-9413 "datetime >= coalesce(c1(NULL))" doesn't return expected NULL +# +CREATE TABLE t1(c1 TIMESTAMP(6) NULL DEFAULT NULL); +INSERT INTO t1 VALUES(NULL); +SELECT c1, '2016-06-13 20:00:00.000003' >= COALESCE( c1 ) FROM t1; +c1 '2016-06-13 20:00:00.000003' >= COALESCE( c1 ) +NULL NULL +DROP TABLE t1; End of 5.5 tests diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 575c30431b6..0cc9c37fee9 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -446,4 +446,12 @@ SELECT MAX(ts) = '2011-01-06 12:34:30' FROM t1; SELECT MAX(dt) = '2011-01-06 12:34:30' FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-9413 "datetime >= coalesce(c1(NULL))" doesn't return expected NULL +--echo # +CREATE TABLE t1(c1 TIMESTAMP(6) NULL DEFAULT NULL); +INSERT INTO t1 VALUES(NULL); +SELECT c1, '2016-06-13 20:00:00.000003' >= COALESCE( c1 ) FROM t1; +DROP TABLE t1; + --echo End of 5.5 tests From 62122ba5d5f02a731742af233a858da3ff4ad426 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Wed, 20 Apr 2016 00:36:58 +0300 Subject: [PATCH 36/52] MDEV-9953 Debian packages install broken 'maria' test suite which cannot be run Debian packages create empty maria/t and maria/r directories, and MTR cannot run maria.* tests --- debian/mariadb-test-5.5.dirs | 2 -- 1 file changed, 2 deletions(-) diff --git a/debian/mariadb-test-5.5.dirs b/debian/mariadb-test-5.5.dirs index f45bf43f7e9..65dbbc81c2a 100644 --- a/debian/mariadb-test-5.5.dirs +++ b/debian/mariadb-test-5.5.dirs @@ -50,8 +50,6 @@ usr/share/mysql/mysql-test/suite/ndb usr/share/mysql/mysql-test/suite/ndb/t usr/share/mysql/mysql-test/suite/ndb/r usr/share/mysql/mysql-test/suite/maria -usr/share/mysql/mysql-test/suite/maria/t -usr/share/mysql/mysql-test/suite/maria/r usr/share/mysql/mysql-test/suite/funcs_2 usr/share/mysql/mysql-test/suite/funcs_2/lib usr/share/mysql/mysql-test/suite/funcs_2/t From 0c0a865fad6c59b141892bfcb5be2dc2c11ae1a7 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 19 Apr 2016 16:16:13 +0400 Subject: [PATCH 37/52] MDEV-9943 - TokuDB fails to compile with gcc 5.2.1 For some reason check_cxx_compiler_flag() passes result variable name down to compiler: https://github.com/Kitware/CMake/blob/master/Modules/CheckCXXSourceCompiles.cmake#L57 But compiler doesn't permit dashes in macro name, like in -DHAVE_CXX_-fimplicit-templates. Workarounded by renaming HAVE_CXX_-fimplicit-templates to HAVE_CXX_IMPLICIT_TEMPLAES. --- .../cmake_modules/TokuSetupCompiler.cmake | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake index 99629e40bdb..fe99c9167d3 100644 --- a/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake +++ b/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake @@ -61,12 +61,13 @@ endmacro(set_cflags_if_supported_named) ## adds a compiler flag if the compiler supports it macro(set_cflags_if_supported) foreach(flag ${ARGN}) - check_c_compiler_flag(${flag} HAVE_C_${flag}) - if (HAVE_C_${flag}) + STRING(REGEX REPLACE "[-,= ]" "_" res ${flag}) + check_c_compiler_flag(${flag} HAVE_C_${res}) + if (HAVE_C_${res}) set(CMAKE_C_FLAGS "${flag} ${CMAKE_C_FLAGS}") endif () - check_cxx_compiler_flag(${flag} HAVE_CXX_${flag}) - if (HAVE_CXX_${flag}) + check_cxx_compiler_flag(${flag} HAVE_CXX_${res}) + if (HAVE_CXX_${res}) set(CMAKE_CXX_FLAGS "${flag} ${CMAKE_CXX_FLAGS}") endif () endforeach(flag) @@ -75,8 +76,9 @@ endmacro(set_cflags_if_supported) ## adds a linker flag if the compiler supports it macro(set_ldflags_if_supported) foreach(flag ${ARGN}) - check_cxx_compiler_flag(${flag} HAVE_${flag}) - if (HAVE_${flag}) + STRING(REGEX REPLACE "[-,= ]" "_" res ${flag}) + check_cxx_compiler_flag(${flag} HAVE_${res}) + if (HAVE_${res}) set(CMAKE_EXE_LINKER_FLAGS "${flag} ${CMAKE_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${flag} ${CMAKE_SHARED_LINKER_FLAGS}") endif () @@ -103,8 +105,8 @@ set_cflags_if_supported( if (CMAKE_CXX_FLAGS MATCHES -fno-implicit-templates) # must append this because mysql sets -fno-implicit-templates and we need to override it - check_cxx_compiler_flag(-fimplicit-templates HAVE_CXX_-fimplicit-templates) - if (HAVE_CXX_-fimplicit-templates) + check_cxx_compiler_flag(-fimplicit-templates HAVE_CXX_IMPLICIT_TEMPLATES) + if (HAVE_CXX_IMPLICIT_TEMPLATES) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fimplicit-templates") endif () endif() From 8f1f869f68581238b7718169fd50e9d7b6c7f0a3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Apr 2016 15:26:37 +0200 Subject: [PATCH 38/52] another test case for ER_DATA_OUT_OF_RANGE on insert tests it with a non-const table too --- mysql-test/r/func_math.result | 5 +++++ mysql-test/t/func_math.test | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 3f8ab6c78d9..d122d435ac7 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -663,6 +663,11 @@ SELECT -a FROM t1; ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`a`)' SELECT -b FROM t1; ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`b`)' +INSERT INTO t1 VALUES(0,0); +SELECT -a FROM t1; +ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`a`)' +SELECT -b FROM t1; +ERROR 22003: BIGINT value is out of range in '-(`test`.`t1`.`b`)' DROP TABLE t1; SET @a:=999999999999999999999999999999999999999999999999999999999999999999999999999999999; SELECT @a + @a; diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index b843cf8c364..cd90184ebf5 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -484,6 +484,14 @@ SELECT -a FROM t1; --error ER_DATA_OUT_OF_RANGE SELECT -b FROM t1; +# try with two rows now +INSERT INTO t1 VALUES(0,0); + +--error ER_DATA_OUT_OF_RANGE +SELECT -a FROM t1; +--error ER_DATA_OUT_OF_RANGE +SELECT -b FROM t1; + DROP TABLE t1; # Decimal overflows From 9e826bfa36a57f10540ca6ea649cb450add48cf4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Apr 2016 15:28:44 +0200 Subject: [PATCH 39/52] trivial optimization don't call write_bin_log() when binlog is known to be disable --- sql/sql_table.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d161ebc0de..024ca9b58e1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4880,8 +4880,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, /* We have to write the query before we unlock the tables. */ - if (!thd->is_current_stmt_binlog_disabled() && - thd->is_current_stmt_binlog_format_row()) + if (thd->is_current_stmt_binlog_disabled()) + goto err; + + if (thd->is_current_stmt_binlog_format_row()) { /* Since temporary tables are not replicated under row-based From 24ac546d0f16d5f56b11c068e4f187a9c4c56bd0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Apr 2016 18:27:23 +0200 Subject: [PATCH 40/52] use consistent error messaging for IGNORE 1. the same message text for INSERT and INSERT IGNORE 2. no new warnings in UPDATE IGNORE yet (big change for 5.5) and replace a commonly used expression with a named constant --- mysql-test/r/insert_innodb.result | 9 --------- sql/handler.cc | 25 ------------------------- sql/handler.h | 3 +-- sql/sql_insert.cc | 13 +++++-------- sql/sql_update.cc | 24 +++++------------------- 5 files changed, 11 insertions(+), 63 deletions(-) diff --git a/mysql-test/r/insert_innodb.result b/mysql-test/r/insert_innodb.result index e7a133a8945..ffba9388ec4 100644 --- a/mysql-test/r/insert_innodb.result +++ b/mysql-test/r/insert_innodb.result @@ -11,20 +11,11 @@ INSERT INTO t2 VALUES(0); INSERT IGNORE INTO t2 VALUES(1); Warnings: Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) -Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) UPDATE IGNORE t2 SET fld2=20 WHERE fld2=0; -Warnings: -Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) UPDATE IGNORE t1 SET fld1=20 WHERE fld1=0; -Warnings: -Warning 1451 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) # Test for multi update. UPDATE IGNORE t1, t2 SET t2.fld2= t2.fld2 + 3; -Warnings: -Warning 1452 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) UPDATE IGNORE t1, t2 SET t1.fld1= t1.fld1 + 3; -Warnings: -Warning 1451 `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) # Reports an error since IGNORE is not used. INSERT INTO t2 VALUES(1); ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) diff --git a/sql/handler.cc b/sql/handler.cc index 1a318334ef3..d528c0aea7a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5463,28 +5463,3 @@ fl_create_iterator(enum handler_iterator_type type, } } #endif /*TRANS_LOG_MGM_EXAMPLE_CODE*/ - - -/** - Report a warning for FK constraint violation. - - @param thd Thread handle. - @param table table on which the operation is performed. - @param error handler error number. -*/ -void warn_fk_constraint_violation(THD *thd,TABLE *table, int error) -{ - String str; - switch(error) { - case HA_ERR_ROW_IS_REFERENCED: - table->file->get_error_message(error, &str); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ROW_IS_REFERENCED_2, str.c_ptr_safe()); - break; - case HA_ERR_NO_REFERENCED_ROW: - table->file->get_error_message(error, &str); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_NO_REFERENCED_ROW_2, str.c_ptr_safe()); - break; - } -} diff --git a/sql/handler.h b/sql/handler.h index 11718ba775c..3d6c8dea2bf 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -335,6 +335,7 @@ #define HA_CHECK_DUP_UNIQUE 2 #define HA_CHECK_FK_ERROR 4 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE) +#define HA_CHECK_ALL (~0U) enum legacy_db_type { @@ -3110,6 +3111,4 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); } -void warn_fk_constraint_violation(THD *thd, TABLE *table, int error); - #endif /* HANDLER_INCLUDED */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7e3a898b3da..c60ef6fcc6e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1609,9 +1609,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) else table->file->insert_id_for_cur_row= insert_id_for_cur_row; bool is_duplicate_key_error; - if (table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) goto err; - is_duplicate_key_error= table->file->is_fatal_error(error, 0); + is_duplicate_key_error= + table->file->is_fatal_error(error, HA_CHECK_ALL & ~HA_CHECK_DUP); if (!is_duplicate_key_error) { /* @@ -1712,8 +1713,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) error != HA_ERR_RECORD_IS_THE_SAME) { if (info->ignore && - !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + !table->file->is_fatal_error(error, HA_CHECK_ALL)) { if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) @@ -1845,7 +1845,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) { DEBUG_SYNC(thd, "write_row_noreplace"); if (!info->ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) goto err; if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) @@ -1866,9 +1866,6 @@ ok_or_after_trg_err: my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH); if (!table->file->has_transactions()) thd->transaction.stmt.modified_non_trans_table= TRUE; - if (info->ignore && - !table->file->is_fatal_error(error, HA_CHECK_FK_ERROR)) - warn_fk_constraint_violation(thd, table, error); DBUG_RETURN(trg_error); err: diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d1b6e945b23..f134e0ba266 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -774,8 +774,7 @@ int mysql_update(THD *thd, error= 0; } else if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) { /* If (ignore && error is ignorable) we don't have to @@ -783,8 +782,7 @@ int mysql_update(THD *thd, */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); @@ -792,9 +790,6 @@ int mysql_update(THD *thd, error= 1; break; } - else if (ignore && !table->file->is_fatal_error(error, - HA_CHECK_FK_ERROR)) - warn_fk_constraint_violation(thd, table, error); } if (table->triggers && @@ -1974,8 +1969,7 @@ int multi_update::send_data(List ¬_used_values) { updated--; if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) { /* If (ignore && error == is ignorable) we don't have to @@ -1983,17 +1977,13 @@ int multi_update::send_data(List ¬_used_values) */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); table->file->print_error(error,MYF(flags)); DBUG_RETURN(1); } - else if (ignore && !table->file->is_fatal_error(error, - HA_CHECK_FK_ERROR)) - warn_fk_constraint_violation(thd, table, error); } else { @@ -2266,15 +2256,11 @@ int multi_update::do_updates() local_error != HA_ERR_RECORD_IS_THE_SAME) { if (!ignore || - table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY | - HA_CHECK_FK_ERROR)) + table->file->is_fatal_error(local_error, HA_CHECK_ALL)) { err_table= table; goto err; } - else if (ignore && !table->file->is_fatal_error(local_error, - HA_CHECK_FK_ERROR)) - warn_fk_constraint_violation(thd, table, local_error); } if (local_error != HA_ERR_RECORD_IS_THE_SAME) updated++; From 2a45fa900b5916e9b789b1a4052ffd7c724f4166 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 20 Apr 2016 19:03:59 +0200 Subject: [PATCH 41/52] MDEV-9836 Connection lost when using SSL Don't read from socket in yassl in SSL_pending(). Just return size of the buffered processed data. This is what OpenSSL is documented to do too: SSL_pending() returns the number of bytes which have been processed, buffered and are available inside ssl for immediate read. --- extra/yassl/src/ssl.cpp | 4 ---- mysql-test/r/ssl_timeout-9836.result | 7 +++++++ mysql-test/t/ssl_timeout-9836.opt | 1 + mysql-test/t/ssl_timeout-9836.test | 11 +++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/ssl_timeout-9836.result create mode 100644 mysql-test/t/ssl_timeout-9836.opt create mode 100644 mysql-test/t/ssl_timeout-9836.test diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 9516e8b985e..23465335922 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -1471,10 +1471,6 @@ int SSL_peek(SSL* ssl, void* buffer, int sz) int SSL_pending(SSL* ssl) { - // Just in case there's pending data that hasn't been processed yet... - char c; - SSL_peek(ssl, &c, 1); - return ssl->bufferedData(); } diff --git a/mysql-test/r/ssl_timeout-9836.result b/mysql-test/r/ssl_timeout-9836.result new file mode 100644 index 00000000000..bc2e19e1475 --- /dev/null +++ b/mysql-test/r/ssl_timeout-9836.result @@ -0,0 +1,7 @@ +SET @@net_read_timeout=1; +SELECT 1; +1 +1 +SELECT 1; +1 +1 diff --git a/mysql-test/t/ssl_timeout-9836.opt b/mysql-test/t/ssl_timeout-9836.opt new file mode 100644 index 00000000000..7a2696875b8 --- /dev/null +++ b/mysql-test/t/ssl_timeout-9836.opt @@ -0,0 +1 @@ +--loose-thread-handling=pool-of-threads diff --git a/mysql-test/t/ssl_timeout-9836.test b/mysql-test/t/ssl_timeout-9836.test new file mode 100644 index 00000000000..5b57917f3b8 --- /dev/null +++ b/mysql-test/t/ssl_timeout-9836.test @@ -0,0 +1,11 @@ +# +# MDEV-9836 Connection lost when using SSL +# +-- source include/have_ssl_communication.inc +connect(con1,localhost,root,,,,,SSL); +SET @@net_read_timeout=1; +SELECT 1; +# MDEV-9836 - YASSL bug - SSL connection lost if it has been idle, for longer than net_read_timeout +-- sleep 2 +SELECT 1; +disconnect con1; From 3f0d07e55b0a2ab8c7bdc1209d55ec2f66542830 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 22 Apr 2016 16:04:20 +0400 Subject: [PATCH 42/52] MDEV-9372 select 100 between 1 and 9223372036854775808 returns false Integer comparison of INT expressions with different signess in BETWEEN is not safe. Switching to DECIMAL comparison in case if INT arguments have different signess. --- mysql-test/r/bigint.result | 6 ++++++ mysql-test/t/bigint.test | 5 +++++ sql/item_cmpfunc.cc | 11 +++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 505d655b6bb..b06ec5805a0 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -502,3 +502,9 @@ a SELECT * FROM t1 WHERE a IN (0.8,0.9); a DROP TABLE t1; +# +# MDEV-9372 select 100 between 1 and 9223372036854775808 returns false +# +SELECT 100 BETWEEN 1 AND 9223372036854775808; +100 BETWEEN 1 AND 9223372036854775808 +1 diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 41f33b8a7f2..fb18d60edd9 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -409,3 +409,8 @@ SELECT * FROM t1 WHERE a=0.9; SELECT * FROM t1 WHERE a IN (0.8,0.9); DROP TABLE t1; + +--echo # +--echo # MDEV-9372 select 100 between 1 and 9223372036854775808 returns false +--echo # +SELECT 100 BETWEEN 1 AND 9223372036854775808; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fb75c9af794..3bd0b5b3fa2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -160,10 +160,11 @@ static int cmp_row_type(Item* item1, Item* item2) static int agg_cmp_type(Item_result *type, Item **items, uint nitems) { - uint i; + uint unsigned_count= items[0]->unsigned_flag; type[0]= items[0]->cmp_type(); - for (i= 1 ; i < nitems ; i++) + for (uint i= 1 ; i < nitems ; i++) { + unsigned_count+= items[i]->unsigned_flag; type[0]= item_cmp_type(type[0], items[i]->cmp_type()); /* When aggregating types of two row expressions we have to check @@ -175,6 +176,12 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems) if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i])) return 1; // error found: invalid usage of rows } + /** + If all arguments are of INT type but have different unsigned_flag values, + switch to DECIMAL_RESULT. + */ + if (type[0] == INT_RESULT && unsigned_count != nitems && unsigned_count != 0) + type[0]= DECIMAL_RESULT; return 0; } From bd75ee748ba9c2f7a06481668ff064cb5217d265 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Fri, 22 Apr 2016 09:10:00 -0400 Subject: [PATCH 43/52] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ba54e70bc3e..58a6b369de9 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=49 +MYSQL_VERSION_PATCH=50 MYSQL_VERSION_EXTRA= From 618e300bce133cd4b4379b9f456d65144ae4c62b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Apr 2016 12:57:39 +0400 Subject: [PATCH 44/52] MDEV-9970 - main.sp-threads fails sporadically Added proper waiting for thread to enter required state. Also reduced amount of information dumped from processlist. --- mysql-test/r/sp-threads.result | 9 +++------ mysql-test/t/sp-threads.test | 9 ++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result index 4dc4d81224b..ddf709d462b 100644 --- a/mysql-test/r/sp-threads.result +++ b/mysql-test/r/sp-threads.result @@ -32,12 +32,9 @@ update t1, t2 set val= 1 where id1=id2; call bug9486(); lock tables t2 write; call bug9486(); -show processlist; -Id User Host db Command Time State Info Progress -# root localhost test Sleep # NULL 0.000 -# root localhost test Query # Waiting for table metadata lock update t1, t2 set val= 1 where id1=id2 0.000 -# root localhost test Query # NULL show processlist 0.000 -# root localhost test Sleep # NULL 0.000 +SELECT state,info FROM information_schema.processlist WHERE id=con1root_id; +state info +Waiting for table metadata lock update t1, t2 set val= 1 where id1=id2 unlock tables; drop procedure bug9486; drop table t1, t2; diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test index e1012e2b72d..7a6d1258331 100644 --- a/mysql-test/t/sp-threads.test +++ b/mysql-test/t/sp-threads.test @@ -77,12 +77,15 @@ call bug9486(); connection con2root; lock tables t2 write; connection con1root; +let $con1root_id=`SELECT CONNECTION_ID()`; send call bug9486(); connection con2root; ---sleep 2 # There should be call statement in locked state. ---replace_column 1 # 3 localhost 6 # -show processlist; +let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist WHERE + id=$con1root_id AND state='Waiting for table metadata lock'; +--source include/wait_condition.inc +--replace_result $con1root_id con1root_id +eval SELECT state,info FROM information_schema.processlist WHERE id=$con1root_id; unlock tables; connection con1root; reap; From 0ea4c73dae689fb80e2c1c1cc347a917534edfae Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sat, 23 Apr 2016 12:15:18 +0400 Subject: [PATCH 45/52] Fixed compilation failure due to unused var. --- client/mysql.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 43c09cafe9e..9d255b55430 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4898,11 +4898,11 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) { if (!inited) { - int errret; - inited=1; #ifdef HAVE_SETUPTERM + int errret; have_curses= setupterm((char *)0, 1, &errret) != ERR; #endif + inited=1; } if (info_type == INFO_ERROR) { From 19e3597e0c718a4cfdfe8789c7b4b11a4e0ba0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 7 Apr 2016 10:47:46 +0300 Subject: [PATCH 46/52] MDEV-9142 :Adding Constraint with no database reference results in ERROR 1046 (3D000) at line 13: No database selected. Use database from create table to foreign key database if nothing else is given. --- mysql-test/suite/innodb/r/innodb-fk.result | 44 ++++++++++++++++++++++ mysql-test/suite/innodb/t/innodb-fk.test | 41 ++++++++++++++++++++ sql/sql_parse.cc | 30 ++++++++++++--- sql/sql_parse.h | 3 +- sql/sql_table.cc | 2 +- 5 files changed, 113 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result index 6c3306f5c15..7ba300b245e 100644 --- a/mysql-test/suite/innodb/r/innodb-fk.result +++ b/mysql-test/suite/innodb/r/innodb-fk.result @@ -68,3 +68,47 @@ Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referen Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t2; drop table t1; +CREATE DATABASE kg_test1; +CREATE DATABASE kg_test2; +CREATE TABLE `kg_test1`.`group` ( +Id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `kg_test1`.`person` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; +show create table `kg_test1`.`person`; +Table Create Table +person CREATE TABLE `person` ( + `Id` int(11) NOT NULL AUTO_INCREMENT, + `Name` varchar(50) NOT NULL, + PRIMARY KEY (`Id`), + CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `group` (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 +CREATE TABLE `kg_test2`.`person2` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; +ERROR HY000: Can't create table 'kg_test2.person2' (errno: 150) +CREATE TABLE `kg_test2`.`person2` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; +show create table `kg_test2`.`person2`; +Table Create Table +person2 CREATE TABLE `person2` ( + `Id` int(11) NOT NULL AUTO_INCREMENT, + `Name` varchar(50) NOT NULL, + PRIMARY KEY (`Id`), + CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 +SHOW WARNINGS; +Level Code Message +DROP DATABASE kg_test2; +DROP DATABASE kg_test1; diff --git a/mysql-test/suite/innodb/t/innodb-fk.test b/mysql-test/suite/innodb/t/innodb-fk.test index 9bfd16b88e9..fd8dce7594c 100644 --- a/mysql-test/suite/innodb/t/innodb-fk.test +++ b/mysql-test/suite/innodb/t/innodb-fk.test @@ -124,3 +124,44 @@ show warnings; drop table t2; drop table t1; + +# +# MDEV-9142 :Adding Constraint with no database reference +# results in ERROR 1046 (3D000) at line 13: No database selected +# +CREATE DATABASE kg_test1; +CREATE DATABASE kg_test2; + +CREATE TABLE `kg_test1`.`group` ( + Id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `kg_test1`.`person` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; + +show create table `kg_test1`.`person`; + +--error 1005 +CREATE TABLE `kg_test2`.`person2` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; + +CREATE TABLE `kg_test2`.`person2` ( +`Id` INT(11) NOT NULL AUTO_INCREMENT, +`Name` VARCHAR(50) NOT NULL, +PRIMARY KEY (`Id`), +CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8; + +show create table `kg_test2`.`person2`; + +SHOW WARNINGS; +DROP DATABASE kg_test2; +DROP DATABASE kg_test1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a52d55b47e9..a3114aba7d3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5395,6 +5395,7 @@ bool check_global_access(THD *thd, ulong want_access, bool no_errors) temporary table flag) @param alter_info [in] Initial list of columns and indexes for the table to be created + @param create_db [in] Database of the created table @retval false ok. @@ -5403,7 +5404,8 @@ bool check_global_access(THD *thd, ulong want_access, bool no_errors) */ bool check_fk_parent_table_access(THD *thd, HA_CREATE_INFO *create_info, - Alter_info *alter_info) + Alter_info *alter_info, + const char* create_db) { Key *key; List_iterator key_iterator(alter_info->key_list); @@ -5443,10 +5445,28 @@ bool check_fk_parent_table_access(THD *thd, return true; } } - else if (thd->lex->copy_db_to(&db_name.str, &db_name.length)) - return true; else - is_qualified_table_name= false; + { + if (!thd->db) + { + db_name.str= (char *) thd->memdup(create_db, strlen(create_db)+1); + db_name.length= strlen(create_db); + is_qualified_table_name= true; + + if(create_db && check_db_name(&db_name)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); + return true; + } + } + else + { + if (thd->lex->copy_db_to(&db_name.str, &db_name.length)) + return true; + else + is_qualified_table_name= false; + } + } // if lower_case_table_names is set then convert tablename to lower case. if (lower_case_table_names) @@ -7462,7 +7482,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, goto err; } - if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info)) + if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info, create_table->db)) goto err; error= FALSE; diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 60d5925c573..4c3070d197d 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -47,7 +47,8 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); bool check_fk_parent_table_access(THD *thd, HA_CREATE_INFO *create_info, - Alter_info *alter_info); + Alter_info *alter_info, + const char* create_db); bool parse_sql(THD *thd, Parser_state *parser_state, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 024ca9b58e1..2cd36ceb4de 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6305,7 +6305,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, till this point for the alter operation. */ if ((alter_info->flags & ALTER_FOREIGN_KEY) && - check_fk_parent_table_access(thd, create_info, alter_info)) + check_fk_parent_table_access(thd, create_info, alter_info, new_db)) goto err; /* From 2b7573ecdda4e542fc65e5d0992f5c05474975c0 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 24 Apr 2016 13:36:51 +0400 Subject: [PATCH 47/52] MDEV-9975 - main.partition_innodb_plugin fails sporadically Fixed wait condition to wait for InnoDB to actually acquire row locks instead of waiting for thread to enter "Searching rows for update" state (which happens earlier). Also use default wait timeout, 2 seconds can be too few for threads to enter appropriate state. --- mysql-test/t/partition_innodb_plugin.test | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test index 4693288a4dd..a951945a87c 100644 --- a/mysql-test/t/partition_innodb_plugin.test +++ b/mysql-test/t/partition_innodb_plugin.test @@ -124,12 +124,8 @@ SEND; UPDATE `t``\""e` SET a = 12 WHERE a = 0; --echo # default connection connection default; -let $wait_timeout= 2; -let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST -WHERE ID = $id_1 AND STATE = 'Searching rows for update'; +let $wait_condition= SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.INNODB_LOCKS; --source include/wait_condition.inc -#--echo # tested wait condition $wait_condition_reps times -# INNODB_LOCKS only exists in innodb_plugin --sorted_result SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS GROUP BY lock_table; From a98ecc2aafcbc08f27a2f7faba872e7a0d25fee2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 23 Apr 2016 12:19:40 +0200 Subject: [PATCH 48/52] support SEARCH_RANGE in search_pattern_in_file.inc Backport a part of commit 439f75f Author: Kristian Nielsen Date: Mon Jun 30 13:59:21 2014 +0200 Fix test failures in rpl.rpl_checksum and rpl.rpl_gtid_errorlog. --- mysql-test/include/search_pattern_in_file.inc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index c047b5bc499..0d09cdcd36e 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -10,6 +10,10 @@ # The environment variables SEARCH_FILE and SEARCH_PATTERN must be set # before sourcing this routine. # +# Optionally, SEARCH_RANGE can be set to the max number of bytes of the file +# to search. If negative, it will search that many bytes at the end of the +# file. The default is to search only the first 50000 bytes of the file. +# # In case of # - SEARCH_FILE and/or SEARCH_PATTERN is not set # - SEARCH_FILE cannot be opened @@ -38,6 +42,7 @@ # --error 0,1 # --remove_file $error_log # let SEARCH_FILE= $error_log; +# let SEARCH_RANGE= -50000; # # Stop the server # let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; # --exec echo "wait" > $restart_file @@ -57,8 +62,18 @@ perl; use strict; my $search_file= $ENV{'SEARCH_FILE'} or die "SEARCH_FILE not set"; my $search_pattern= $ENV{'SEARCH_PATTERN'} or die "SEARCH_PATTERN not set"; + my $search_range= $ENV{'SEARCH_RANGE'}; + my $file_content; + $search_range= 50000 unless $search_range =~ /-?[0-9]+/; open(FILE, "$search_file") or die("Unable to open '$search_file': $!\n"); - read(FILE, my $file_content, 50000, 0); + if ($search_range >= 0) { + read(FILE, $file_content, $search_range, 0); + } else { + my $size= -s $search_file; + $search_range = -$size if $size > -$search_range; + seek(FILE, $search_range, 2); + read(FILE, $file_content, -$search_range, 0); + } close(FILE); if ( not $file_content =~ m{$search_pattern} ) { die("# ERROR: The file '$search_file' does not contain the expected pattern $search_pattern\n->$file_content<-\n"); From 22204807317c467b2f09dd0dcd13898a48501b10 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 25 Apr 2016 18:59:41 +0200 Subject: [PATCH 49/52] MDEV-7775 Wrong error message (Unknown error) when idle sessions are killed after wait_timeout restore the error message that was removed by mistake in ec38c1bbd709 --- mysql-test/r/wait_timeout_not_windows.result | 3 +++ mysql-test/t/wait_timeout_not_windows.test | 15 +++++++++++++++ sql/sql_connect.cc | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/wait_timeout_not_windows.result create mode 100644 mysql-test/t/wait_timeout_not_windows.test diff --git a/mysql-test/r/wait_timeout_not_windows.result b/mysql-test/r/wait_timeout_not_windows.result new file mode 100644 index 00000000000..df70aa99221 --- /dev/null +++ b/mysql-test/r/wait_timeout_not_windows.result @@ -0,0 +1,3 @@ +set global log_warnings=2; +set @@wait_timeout=1; +set global log_warnings=@@log_warnings; diff --git a/mysql-test/t/wait_timeout_not_windows.test b/mysql-test/t/wait_timeout_not_windows.test new file mode 100644 index 00000000000..43ba48e4c43 --- /dev/null +++ b/mysql-test/t/wait_timeout_not_windows.test @@ -0,0 +1,15 @@ +source include/not_windows.inc; + +# +# MDEV-7775 Wrong error message (Unknown error) when idle sessions are killed after wait_timeout +# +set global log_warnings=2; +connect (foo,localhost,root); +set @@wait_timeout=1; +sleep 2; +connection default; +let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_RANGE= -50; +let SEARCH_PATTERN= Aborted.*Got timeout reading communication packets; +source include/search_pattern_in_file.inc; +set global log_warnings=@@log_warnings; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 16b53da1ebd..61f8b4081eb 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1092,7 +1092,8 @@ void end_connection(THD *thd) } if (!thd->killed && (net->error && net->vio != 0)) - thd->print_aborted_warning(1, ER(ER_UNKNOWN_ERROR)); + thd->print_aborted_warning(1, + thd->stmt_da->is_error() ? thd->stmt_da->message() : ER(ER_UNKNOWN_ERROR)); } From 7f5ceb77689d4858875bfae7c4f2abc11534b7f1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Apr 2016 11:49:35 +0200 Subject: [PATCH 50/52] disable main.wait_timeout_not_windows for embedded --- mysql-test/t/wait_timeout_not_windows.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/wait_timeout_not_windows.test b/mysql-test/t/wait_timeout_not_windows.test index 43ba48e4c43..de4904fada2 100644 --- a/mysql-test/t/wait_timeout_not_windows.test +++ b/mysql-test/t/wait_timeout_not_windows.test @@ -1,3 +1,4 @@ +source include/not_embedded.inc; source include/not_windows.inc; # From 29868de2fff62c3ebd8af5cf533d3d224da1b332 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Apr 2016 12:58:14 +0200 Subject: [PATCH 51/52] MDEV-9986 Full-text search of the utf8mb4 column causes crash take into account that agg_arg_charsets_for_comparison() can replace Item_field's with Item_func_conv_charset --- mysql-test/r/fulltext3.result | 12 ++++++++++++ mysql-test/t/fulltext3.test | 15 +++++++++++++++ sql/item_func.cc | 2 ++ 3 files changed, 29 insertions(+) diff --git a/mysql-test/r/fulltext3.result b/mysql-test/r/fulltext3.result index 4ec48369ad1..c0b871cd5a7 100644 --- a/mysql-test/r/fulltext3.result +++ b/mysql-test/r/fulltext3.result @@ -15,3 +15,15 @@ CREATE TABLE t1(a VARCHAR(2) CHARACTER SET big5 COLLATE big5_chinese_ci, FULLTEXT(a)); INSERT INTO t1 VALUES(0xA3C2); DROP TABLE t1; +create table t1 ( +id varchar(255), +business_name text null collate utf8mb4_unicode_ci, +street_address text, +fulltext index ft (business_name), +fulltext index ft2 (street_address) +); +select * from t1 where match (business_name, street_address) against ('some business name and address here'); +ERROR HY000: Can't find FULLTEXT index matching the column list +select * from t1 where match (business_name, street_address) against ('some business name and address here' in boolean mode); +id business_name street_address +drop table t1; diff --git a/mysql-test/t/fulltext3.test b/mysql-test/t/fulltext3.test index 1b6a07c540f..66f940b495e 100644 --- a/mysql-test/t/fulltext3.test +++ b/mysql-test/t/fulltext3.test @@ -32,3 +32,18 @@ INSERT INTO t1 VALUES(0xA3C2); DROP TABLE t1; # End of 5.1 tests + +# +# MDEV-9986 Full-text search of the utf8mb4 column causes crash +# +create table t1 ( + id varchar(255), + business_name text null collate utf8mb4_unicode_ci, + street_address text, + fulltext index ft (business_name), + fulltext index ft2 (street_address) +); +--error ER_FT_MATCHING_KEY_NOT_FOUND +select * from t1 where match (business_name, street_address) against ('some business name and address here'); +select * from t1 where match (business_name, street_address) against ('some business name and address here' in boolean mode); +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index bd6553d45d4..cabba7a666c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6366,6 +6366,8 @@ bool Item_func_match::fix_index() for (i=1; i < arg_count; i++) { + if (args[i]->type() != FIELD_ITEM) + goto err; item=(Item_field*)args[i]; for (keynr=0 ; keynr < fts ; keynr++) { From 4f1ad43992d75676687f29da96dd7c4147247a8f Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 26 Apr 2016 16:15:15 +0400 Subject: [PATCH 52/52] MDEV-9987 - gen_lex_hash leaks memory, making LeakSanitizer builds fail Fixed memory leaks in gen_lex_hash. --- sql/gen_lex_hash.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index c37f4f145cf..3a3273d279b 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -310,6 +310,7 @@ void print_find_structs() add_structs_to_map(root_by_len,max_len); set_links(root_by_len,max_len); print_hash_map("sql_functions_map"); + free(hash_map); hash_map= 0; size_hash_map= 0; @@ -319,6 +320,7 @@ void print_find_structs() add_structs_to_map(root_by_len2,max_len2); set_links(root_by_len2,max_len2); print_hash_map("symbols_map"); + free(hash_map); }