From 6d30383e78c8b9aba56f645421f437af63706efe Mon Sep 17 00:00:00 2001 From: Murthy Narkedimilli Date: Mon, 31 Aug 2015 20:36:03 +0200 Subject: [PATCH 01/66] Raise version number after cloning 5.5.46 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 45f770d8f07..b85da230659 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=46 +MYSQL_VERSION_PATCH=47 MYSQL_VERSION_EXTRA= From 97ea06e807628b6d079ae5f72f5ee0c0ea391caf Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Tue, 1 Sep 2015 08:53:15 +0200 Subject: [PATCH 02/66] Raise version number after tagging 5.1.77 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index be169e073bd..cf433796fea 100644 --- a/configure.in +++ b/configure.in @@ -29,7 +29,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.77], [], [mysql]) +AC_INIT([MySQL Server], [5.1.78], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From ddcad361d6ff2c3336221f27c4e31bfc8d1913b1 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Fri, 4 Sep 2015 11:10:57 +0530 Subject: [PATCH 03/66] Bug #21503595 : --QUERY-ALLOC-BLOCK-SIZE=-1125899906842624 + PID_FILE CHECK LEADS TO OOM SIG 11 Description:- A server started with 'query_alloc_block_size' option set to a certain range of negative values on a machine without enough memory may lead to OOM. Analysis:- Server uses 'strtoull()' to convert server variable values of type 'GET_UINT', 'GET_ULONG' or 'GET_ULL' from string to unsigned long long. According to the man page, 'strtoull()' function returns either the result of the conversion or, if there was a leading minus sign, the negation of the result of the conversion represented as an unsigned value, unless the original(nonnegated) value would overflow; in the latter case, strtoull() returns ULLONG_MAX and sets errno to ERANGE. So 'strtoull()' converts a small negative value to a larger postive value. For example string '-1125899906842624' will be converted to an unsigned value, '18445618173802708992' (ulonglong typecast of '-1125899906842624'). So a server started with 'query_alloc_block_size' set to "-1125899906842624" on a machine without enough memory will lead to OOM since server allocates '18445618173802708992' bytes(17178820608 GB) for query allocation block. Fix:- When server is started with any server variable, of type "GET_UINT", "GET_ULONG" or "GET_ULL", set to a negative value, a warning, "option xxx: value -yyy adjusted to zzz" is thrown and the value is adjusted to the lowest possible value for that variable. The dynamic server variable which is configured through the client exhibit the same behavior as fix made for variables configured during the server start up. --- mysys/my_getopt.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 03469589173..6d27c9a9e73 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2015, 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 @@ -1005,6 +1005,14 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, return num; } +static inline my_bool is_negative_num(char* num) +{ + while (my_isspace(&my_charset_latin1, *num)) + num++; + + return (*num == '-'); +} + /* function: getopt_ull @@ -1014,7 +1022,20 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { - ulonglong num= eval_num_suffix(arg, err, (char*) optp->name); + char buf[255]; + ulonglong num; + + /* If a negative number is specified as a value for the option. */ + if (arg == NULL || is_negative_num(arg) == TRUE) + { + num= (ulonglong) optp->min_value; + my_getopt_error_reporter(WARNING_LEVEL, + "option '%s': value %s adjusted to %s", + optp->name, arg, ullstr(num, buf)); + } + else + num= eval_num_suffix(arg, err, (char*) optp->name); + return getopt_ull_limit_value(num, optp, NULL); } From adf12e6e1704dbf4f5e06fa45f40ab5b71514cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 11 Sep 2015 10:32:10 +0300 Subject: [PATCH 04/66] Adapt to WL#8845 Implement an InnoDB redo log format version identifier recv_find_max_checkpoint(): Amend the error message to give advice about downgrading. The 5.7.9 redo log format was intentionally changed so that older MySQL versions will not find a valid redo log checkpoint. --- storage/innobase/log/log0recv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 5dfb0c9defd..ae3912da552 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1997, 2015, 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 @@ -736,6 +736,10 @@ not_consistent: fprintf(stderr, "InnoDB: No valid checkpoint found.\n" + "InnoDB: If you are attempting downgrade" + " from MySQL 5.7.9 or later,\n" + "InnoDB: please refer to " REFMAN + "upgrading-downgrading.html\n" "InnoDB: If this error appears when you are" " creating an InnoDB database,\n" "InnoDB: the problem may be that during" From 17387bc574a4054a9aeac7ba4aa60e25588dc7bf Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Wed, 16 Sep 2015 18:58:43 +0530 Subject: [PATCH 05/66] Bug #21467458 - UNINSTALL PLUGIN DAEMON_EXAMPLE CRASHES MYSQLD. DESCRIPTION =========== Crash occurs when daemon_example plugin is uninstalled immediately after its installed. This can be reproduced by installing and uninstalling the plugin repeatedly. ANALYSIS ======== The daemon_example_plugin_deinit() function of the daemon example plugin calls pthread_cancel() but doesn't wait for the worker thread to actually complete before deallocating the data buffer and closing the file that it writes to. This is causing SEGFAULT! FIX === Added a pthread_join() to wait for the thread to complete before doing the cleanup work. Removed a stray 'x' variable from the example code. NOTE ==== Have made an entry in .opt file as given below: --plugin-dir=$DAEMONEXAMPLE_DIR This is done so that the program takes plugin directory as ..//plugin/daemon_example/ instead of ../lib/plugin/ --- plugin/daemon_example/daemon_example.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc index ac4841b10b2..129469405b8 100644 --- a/plugin/daemon_example/daemon_example.cc +++ b/plugin/daemon_example/daemon_example.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2015, 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 @@ -46,7 +47,6 @@ pthread_handler_t mysql_heartbeat(void *p) DBUG_ENTER("mysql_heartbeat"); struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p; char buffer[HEART_STRING_BUFFER]; - unsigned int x= 0; time_t result; struct tm tm_tmp; @@ -65,7 +65,6 @@ pthread_handler_t mysql_heartbeat(void *p) tm_tmp.tm_min, tm_tmp.tm_sec); my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0)); - x++; } DBUG_RETURN(0); @@ -173,6 +172,13 @@ static int daemon_example_plugin_deinit(void *p) tm_tmp.tm_min, tm_tmp.tm_sec); my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0)); + + /* + Need to wait for the hearbeat thread to terminate before closing + the file it writes to and freeing the memory it uses. + */ + pthread_join(con->heartbeat_thread, NULL); + my_close(con->heartbeat_file, MYF(0)); my_free(con); From 4acc7615eedc167fbad6fcc14966a054de35fd75 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 18 Sep 2015 07:34:32 +0530 Subject: [PATCH 06/66] Bug #19929406: HANDLE_FATAL_SIGNAL (SIG=11) IN __MEMMOVE_SSSE3_BACK FROM STRING::COPY Issue: ----- While using row comparators, the store_value functions call val_xxx functions in the prepare phase. This can cause valgrind issues. SOLUTION: --------- Setting up of the comparators should be done by alloc_comparators in the prepare phase. Also, make sure store_value will be called only during execute phase. This is a backport of the fix for Bug#17755540. --- sql/item_cmpfunc.cc | 37 ++++++++++++++++++++++--------------- sql/item_cmpfunc.h | 4 ++-- sql/table.cc | 17 +---------------- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 42e79754b95..e6cc3272ceb 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, 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 @@ -3708,29 +3708,39 @@ cmp_item_row::~cmp_item_row() } -void cmp_item_row::alloc_comparators() +void cmp_item_row::alloc_comparators(Item *item) { + n= item->cols(); + DBUG_ASSERT(comparators == NULL); if (!comparators) comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n); + if (comparators) + { + for (uint i= 0; i < n; i++) + { + DBUG_ASSERT(comparators[i] == NULL); + Item *item_i= item->element_index(i); + if (!(comparators[i]= + cmp_item::get_comparator(item_i->result_type(), + item_i->collation.collation))) + break; // new failed + if (item_i->result_type() == ROW_RESULT) + static_cast(comparators[i])->alloc_comparators(item_i); + } + } } void cmp_item_row::store_value(Item *item) { DBUG_ENTER("cmp_item_row::store_value"); - n= item->cols(); - alloc_comparators(); + DBUG_ASSERT(comparators); if (comparators) { item->bring_value(); item->null_value= 0; - for (uint i=0; i < n; i++) + for (uint i= 0; i < n; i++) { - if (!comparators[i]) - if (!(comparators[i]= - cmp_item::get_comparator(item->element_index(i)->result_type(), - item->element_index(i)->collation.collation))) - break; // new failed comparators[i]->store_value(item->element_index(i)); item->null_value|= item->element_index(i)->null_value; } @@ -3991,7 +4001,7 @@ void Item_func_in::fix_length_and_dec() cmp_items[ROW_RESULT]= cmp; } cmp->n= args[0]->cols(); - cmp->alloc_comparators(); + cmp->alloc_comparators(args[0]); } /* All DATE/DATETIME fields/functions has the STRING result type. */ if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT) @@ -4102,11 +4112,8 @@ void Item_func_in::fix_length_and_dec() break; case ROW_RESULT: /* - The row comparator was created at the beginning but only DATETIME - items comparators were initialized. Call store_value() to setup - others. + The row comparator was created at the beginning. */ - ((in_row*)array)->tmp.store_value(args[0]); break; case DECIMAL_RESULT: array= new in_decimal(arg_count - 1); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 38a88d88715..115d6db300d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1,7 +1,7 @@ #ifndef ITEM_CMPFUNC_INCLUDED #define ITEM_CMPFUNC_INCLUDED -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, 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 @@ -1288,7 +1288,7 @@ public: cmp_item_row(): comparators(0), n(0) {} ~cmp_item_row(); void store_value(Item *item); - inline void alloc_comparators(); + inline void alloc_comparators(Item *item); int cmp(Item *arg); int compare(cmp_item *arg); cmp_item *make_same(); diff --git a/sql/table.cc b/sql/table.cc index c17ee39fe9e..750b870da75 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, 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 @@ -1910,21 +1910,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, outparam->record[1]= outparam->record[0]; // Safety } -#ifdef HAVE_purify - /* - We need this because when we read var-length rows, we are not updating - bytes after end of varchar - */ - if (records > 1) - { - memcpy(outparam->record[0], share->default_values, share->rec_buff_length); - memcpy(outparam->record[1], share->default_values, share->null_bytes); - if (records > 2) - memcpy(outparam->record[1], share->default_values, - share->rec_buff_length); - } -#endif - if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, (uint) ((share->fields+1)* sizeof(Field*))))) From 0632dae73fe3379cba00beeb65585f0d61f10d8c Mon Sep 17 00:00:00 2001 From: Robert Golebiowski Date: Fri, 18 Sep 2015 10:35:09 +0200 Subject: [PATCH 07/66] Bug #21025377 CAN'T CONNECT TO SSL ENABLED SERVER FIRST 30 SEC AFTER INITIAL STARTUP Updated yassl to yassl-2.3.7e --- extra/yassl/README | 7 +++++++ extra/yassl/include/openssl/ssl.h | 2 +- extra/yassl/taocrypt/src/asn.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/extra/yassl/README b/extra/yassl/README index 2560c09addd..47ec1a66ea3 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,6 +12,13 @@ before calling SSL_new(); *** end Note *** +yaSSL Patch notes, version 2.3.7e (6/26/2015) + This release of yaSSL includes a fix for Date less than comparison. + Previously yaSSL would return true on less than comparisons if the Dates + were equal. Reported by Oracle. No security problem, but if a cert was + generated right now, a server started using it in the same second, and a + client tried to verify it in the same second it would report not yet valid. + yaSSL Patch notes, version 2.3.7d (6/22/2015) This release of yaSSL includes a fix for input_buffer set_current with index 0. SSL_peek() at front of waiting data could trigger. Robert diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 692d8b270d2..9e16f9278a7 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.7d" +#define YASSL_VERSION "2.3.7e" #if defined(__cplusplus) diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 342255c91b8..c419ec0a992 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -71,7 +71,7 @@ bool operator>(tm& a, tm& b) bool operator<(tm& a, tm&b) { - return !(a>b); + return (b>a); } From 259cf3dc607dd0112d44c4647b07a3024cee268e Mon Sep 17 00:00:00 2001 From: Robert Golebiowski Date: Fri, 18 Sep 2015 11:18:25 +0200 Subject: [PATCH 08/66] Updated yassl to yassl-2.3.8 --- extra/yassl/README | 8 ++++++++ extra/yassl/include/openssl/ssl.h | 2 +- extra/yassl/include/yassl_error.hpp | 3 ++- extra/yassl/src/handshake.cpp | 2 ++ extra/yassl/src/yassl_error.cpp | 4 ++++ extra/yassl/src/yassl_imp.cpp | 15 ++++++++++++++- 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/extra/yassl/README b/extra/yassl/README index 47ec1a66ea3..bf0e1c9f40f 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,6 +12,14 @@ before calling SSL_new(); *** end Note *** +yaSSL Release notes, version 2.3.8 (9/17/2015) + This release of yaSSL fixes a high security vulnerability. All users + SHOULD update. If using yaSSL for TLS on the server side with private + RSA keys allowing ephemeral key exchange you MUST update and regenerate + the RSA private keys. This report is detailed in: + https://people.redhat.com/~fweimer/rsa-crt-leaks.pdf + yaSSL now detects RSA signature faults and returns an error. + yaSSL Patch notes, version 2.3.7e (6/26/2015) This release of yaSSL includes a fix for Date less than comparison. Previously yaSSL would return true on less than comparisons if the Dates diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 9e16f9278a7..b0a7592f870 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.7e" +#define YASSL_VERSION "2.3.8" #if defined(__cplusplus) diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index beba7b0b5dd..d63244dca90 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -53,7 +53,8 @@ enum YasslError { compress_error = 118, decompress_error = 119, pms_version_error = 120, - sanityCipher_error = 121 + sanityCipher_error = 121, + rsaSignFault_error = 122 // !!!! add error message to .cpp !!!! diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 33303b1106d..aa2de39333c 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -1172,6 +1172,8 @@ void sendCertificateVerify(SSL& ssl, BufferOutput buffer) CertificateVerify verify; verify.Build(ssl); + if (ssl.GetError()) return; + RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr out(NEW_YS output_buffer); diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index e5d69367339..5169b7dd5d0 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -148,6 +148,10 @@ void SetErrorString(YasslError error, char* buffer) strncpy(buffer, "sanity check on cipher text size error", max); break; + case rsaSignFault_error: + strncpy(buffer, "rsa signature fault error", max); + break; + // openssl errors case SSL_ERROR_WANT_READ : strncpy(buffer, "the read operation would block", max); diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 69ba469b928..1baa5adedf8 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -196,9 +196,16 @@ void DH_Server::build(SSL& ssl) sha.update(tmp.get_buffer(), tmp.get_size()); sha.get_digest(&hash[MD5_LEN]); - if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) + if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) { auth->sign(signature_, hash, sizeof(hash), ssl.getCrypto().get_random()); + // check for rsa signautre fault + if (!auth->verify(hash, sizeof(hash), signature_, + auth->get_signatureLength())) { + ssl.SetError(rsaSignFault_error); + return; + } + } else { auth->sign(signature_, &hash[MD5_LEN], SHA_LEN, ssl.getCrypto().get_random()); @@ -2159,6 +2166,12 @@ void CertificateVerify::Build(SSL& ssl) memcpy(sig.get(), len, VERIFY_HEADER); rsa.sign(sig.get() + VERIFY_HEADER, hashes_.md5_, sizeof(Hashes), ssl.getCrypto().get_random()); + // check for rsa signautre fault + if (!rsa.verify(hashes_.md5_, sizeof(Hashes), sig.get() + VERIFY_HEADER, + rsa.get_cipherLength())) { + ssl.SetError(rsaSignFault_error); + return; + } } else { // DSA DSS dss(cert.get_privateKey(), cert.get_privateKeyLength(), false); From 8ea80ecfeb88846ee47c65011eb9ff7eddab84b3 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Tue, 22 Sep 2015 06:21:13 +0200 Subject: [PATCH 09/66] Bug #19929435 DROP DATABASE HANGS WITH MALFORMED TABLE Note: Backporting the patch from mysql-5.6. Problem: A CREATE TABLE with an invalid table name is detected at SQL layer. So the table name is reset to an empty string. But the storage engine is called with this empty table name. The table name is specified as "database/table". So, in the given scenario we get only "database/". Solution: Within InnoDB, detect this error and report it to higher layer. rb#9274 approved by jimmy. --- mysql-test/suite/innodb/r/dropdb.result | 9 +++++++++ mysql-test/suite/innodb/t/dropdb.test | 12 ++++++++++++ storage/innobase/handler/ha_innodb.cc | 12 +++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/dropdb.result create mode 100644 mysql-test/suite/innodb/t/dropdb.test diff --git a/mysql-test/suite/innodb/r/dropdb.result b/mysql-test/suite/innodb/r/dropdb.result new file mode 100644 index 00000000000..f8890784bfc --- /dev/null +++ b/mysql-test/suite/innodb/r/dropdb.result @@ -0,0 +1,9 @@ +# +# Bug #19929435 DROP DATABASE HANGS WITH MALFORMED TABLE +# +set session default_storage_engine=innodb; +create database `b`; +use `b`; +create table `#mysql50#q.q` select 1; +ERROR HY000: Can't create table 'b.#mysql50#q.q' (errno: 1103) +drop database `b`; diff --git a/mysql-test/suite/innodb/t/dropdb.test b/mysql-test/suite/innodb/t/dropdb.test new file mode 100644 index 00000000000..d275b809d00 --- /dev/null +++ b/mysql-test/suite/innodb/t/dropdb.test @@ -0,0 +1,12 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19929435 DROP DATABASE HANGS WITH MALFORMED TABLE +--echo # + +set session default_storage_engine=innodb; +create database `b`; +use `b`; +--error ER_CANT_CREATE_TABLE +create table `#mysql50#q.q` select 1; +drop database `b`; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b8ec8f60f28..1c6763ef93a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6529,7 +6529,8 @@ create_table_def( /* MySQL does the name length check. But we do additional check on the name length here */ - if (strlen(table_name) > MAX_FULL_NAME_LEN) { + const size_t table_name_len = strlen(table_name); + if (table_name_len > MAX_FULL_NAME_LEN) { push_warning_printf( (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TABLE_NAME, @@ -6538,6 +6539,15 @@ create_table_def( DBUG_RETURN(ER_TABLE_NAME); } + if (table_name[table_name_len - 1] == '/') { + push_warning_printf( + (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TABLE_NAME, + "InnoDB: Table name is empty"); + + DBUG_RETURN(ER_WRONG_TABLE_NAME); + } + n_cols = form->s->fields; /* We pass 0 as the space id, and determine at a lower level the space From 86375f7fa6a428bfc405f85335685cd1dff25302 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 22 Sep 2015 14:51:48 +0530 Subject: [PATCH 10/66] Bug #21370329 : FLUSH DES_KEY_FILE MAY NOT WORK Description: The command FLUSH DES_KEY_FILE is expected to reload the DES keys from the file that was specified with the "--des-key-file" option at server startup. But it is not behaving as expected. Analysis: The des file reload is defined within a wrong conditional directive, rendering the command ineffective. Macro "OPENSSL" was used instead of "HAVE_OPENSSL" macro. Fix: "OPENSSL" macro is changed to "HAVE_OPENSSL". --- sql/mysqld.h | 3 ++- sql/sql_reload.cc | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sql/mysqld.h b/sql/mysqld.h index 655fb93df73..0253c2a0b43 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2015, 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 @@ -349,6 +349,7 @@ extern mysql_mutex_t extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thd_remove; #ifdef HAVE_OPENSSL +extern char* des_key_file; extern mysql_mutex_t LOCK_des_key_file; #endif extern mysql_mutex_t LOCK_server_started; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index b0665a9ea6b..40e350c4ddd 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -25,6 +25,7 @@ #include "hostname.h" // hostname_cache_refresh #include "sql_repl.h" // reset_master, reset_slave #include "debug_sync.h" +#include "des_key_file.h" /** @@ -297,7 +298,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, } } #endif -#ifdef OPENSSL +#ifdef HAVE_OPENSSL if (options & REFRESH_DES_KEY_FILE) { if (des_key_file && load_des_key_file(des_key_file)) From ea9dbef661efdf5079b1b0e33679a863408e3166 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Tue, 22 Sep 2015 16:52:18 +0530 Subject: [PATCH 11/66] Bug#20755615 CREATING INDEX ON A RENAMED COLUMN WITH CASE CRASH .FRM FILE PROBLEM In 5.5 when doing doing a rename of a column ,we ignore the case between old and new column names while comparing them,so if the change is just the case then we don't even mark the field FIELD_IS_RENAMED ,we just update the frm file ,but don't recreate the table as is the norm when alter is used.This leads to inconsistency in the innodb data dictionary which causes index creation to fail. FIX According to the documentation any innodb column rename should trigger rebuild of the table. Therefore for innodb tables we will do a strcmp() between the column names and if there is case change in column name we will trigger a rebuild. --- mysql-test/r/alter_table.result | 17 +++++++++++++++++ mysql-test/t/alter_table.test | 19 +++++++++++++++++++ sql/sql_table.cc | 20 ++++++++++++++++---- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 236d07bccbc..725f2528c29 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1488,3 +1488,20 @@ CREATE TABLE help_topic (dummy int) ENGINE=innodb; ERROR HY000: Storage engine 'InnoDB' does not support system tables. [mysql.help_topic] use test; # End of Bug#11815557 +# +# Bug#20755615 CREATING INDEX ON A RENAMED +# COLUMN WITH CASE CRASH .FRM FILE +# +CREATE TABLE t1 (D INT) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 MODIFY COLUMN d INT; +ALTER TABLE t1 ADD INDEX (d); +DROP TABLE t1; +CREATE TABLE t1 (`é` int) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 CHANGE `é` `É` INT; +ALTER TABLE t1 ADD INDEX (`É`); +SELECT * FROM t1; +É +10 +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index f5d5538c217..8768cd4975c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1261,3 +1261,22 @@ CREATE TABLE time_zone (dummy int) ENGINE=merge; CREATE TABLE help_topic (dummy int) ENGINE=innodb; use test; --echo # End of Bug#11815557 + +--echo # +--echo # Bug#20755615 CREATING INDEX ON A RENAMED +--echo # COLUMN WITH CASE CRASH .FRM FILE +--echo # + +CREATE TABLE t1 (D INT) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 MODIFY COLUMN d INT; +ALTER TABLE t1 ADD INDEX (d); +DROP TABLE t1; + +CREATE TABLE t1 (`é` int) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 CHANGE `é` `É` INT; +ALTER TABLE t1 ADD INDEX (`É`); +SELECT * FROM t1; +DROP TABLE t1; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2951d921e15..0a58d9ade5b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5048,10 +5048,22 @@ mysql_compare_tables(TABLE *table, /* Check if field was renamed */ field->flags&= ~FIELD_IS_RENAMED; - if (my_strcasecmp(system_charset_info, - field->field_name, - tmp_new_field->field_name)) - field->flags|= FIELD_IS_RENAMED; + + /* + InnoDB data dictionary is case sensitive so we should use string case + sensitive comparison between fields. Note: strcmp branch is to be + removed in future when we fix it in InnoDB. + */ + if ((table->s->db_type())->db_type == DB_TYPE_INNODB && + strcmp(field->field_name,tmp_new_field->field_name)) + field->flags|= FIELD_IS_RENAMED; + else + { + if (my_strcasecmp(system_charset_info, + field->field_name, + tmp_new_field->field_name)) + field->flags|= FIELD_IS_RENAMED; + } /* Evaluate changes bitmap and send to check_if_incompatible_data() */ if (!(tmp= field->is_equal(tmp_new_field))) From 8ea58c474fbbcd79e9716379d226b8a46062b350 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 30 Sep 2015 10:27:26 +0530 Subject: [PATCH 12/66] BUG 21900800 - ADD OBSOLETE ON MYSQL-CONNECTOR-C-SHARED AND MYSQL-CONNECTOR-C-DEVEL As MySQL Connector C 6.1 is end of life, added conflict with mysql-connector-c-shared dependencies --- packaging/rpm-oel/mysql.spec.in | 5 +++++ packaging/rpm-sles/mysql.spec.in | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index bb232fb404d..2d91975f56c 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -301,6 +301,7 @@ Obsoletes: mysql-devel < %{version}-%{release} Obsoletes: mariadb-devel Provides: mysql-devel = %{version}-%{release} Provides: mysql-devel%{?_isa} = %{version}-%{release} +Conflicts: mysql-connector-c-shared-devel < 6.2 %description devel This package contains the development header files and libraries necessary @@ -323,6 +324,7 @@ Obsoletes: mysql-libs < %{version}-%{release} Obsoletes: mariadb-libs Provides: mysql-libs = %{version}-%{release} Provides: mysql-libs%{?_isa} = %{version}-%{release} +Conflicts: mysql-connector-c-shared < 6.2 %description libs This package contains the shared libraries for MySQL client @@ -913,6 +915,9 @@ fi %endif %changelog +* Tue Sep 29 2015 Balasubramanian Kandasamy - 5.5.47-1 +- Added conflicts to mysql-connector-c-shared dependencies + * Tue Jul 22 2014 Balasubramanian Kandasamy - 5.5.39-5 - Provide mysql-compat-server dependencies diff --git a/packaging/rpm-sles/mysql.spec.in b/packaging/rpm-sles/mysql.spec.in index 23c076332b0..b5fb5b77642 100644 --- a/packaging/rpm-sles/mysql.spec.in +++ b/packaging/rpm-sles/mysql.spec.in @@ -268,6 +268,7 @@ Obsoletes: mariadb-devel Obsoletes: libmysqlclient-devel Provides: mysql-devel = %{version}-%{release} Provides: libmysqlclient-devel = %{version}-%{release} +Conflicts: mysql-connector-c-shared-devel < 6.2 %description devel This package contains the development header files and libraries necessary @@ -293,6 +294,7 @@ Obsoletes: libmysqlclient_r18 < %{version}-%{release} Provides: mysql-libs = %{version}-%{release} Provides: libmysqlclient18 = %{version}-%{release} Provides: libmysqlclient_r18 = %{version}-%{release} +Conflicts: mysql-connector-c-shared < 6.2 %description libs This package contains the shared libraries for MySQL client @@ -779,6 +781,9 @@ fi %attr(755, root, root) %{_libdir}/mysql/libmysqld.so %changelog +* Tue Sep 29 2015 Balasubramanian Kandasamy - 5.5.47-1 +- Added conflicts to mysql-connector-c-shared dependencies + * Mon Oct 06 2014 Balasubramanian Kandasamy - 5.5.41-1 - Backport to 5.5.41 From 415faa122b9c683661dafac82fff414fa6864151 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Thu, 1 Oct 2015 07:45:27 +0530 Subject: [PATCH 13/66] Bug #19434916: FATAL_SIGNAL IN ADD_KEY_EQUAL_FIELDS() WITH UPDATE VIEW USING OUTER SUBQUERY Issue: ----- While resolving a column which refers to a table/view in an outer query, it's respecitve item object is marked with the outer query's select_lex object. But when the column refers to a view or if the column is part of a subquery in the HAVING clause, an Item_ref object is created. While the reference to the outer query is stored by the Item_ref object, the same is not stored in it's real_item. This creates a problem with the IN-TO-EXISTS optmization. When there is an index over the column in the inner query, it will be considered since the column's real_item object will be mistaken for a local field. This will lead to a crash. SOLUTION: --------- Under the current design, the only way to fix this issue is to check the reginfo.join_tab for a NULL value. If yes, the query should not be worrying about the key use. The testcase and comments added as part of the fix for Bug#17766653 have been backported. --- sql/item_subselect.cc | 26 +++++++++++++++++++++++++- sql/sql_select.cc | 12 ++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c9c625db083..43af0b5a3f6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2015, 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 @@ -1072,6 +1072,27 @@ Item_in_subselect::single_value_transformer(JOIN *join, runtime created Ref item which is deleted at the end of the statement. Thus one of 'substitution' arguments can be broken in case of PS. + + @todo + Why do we use real_item()/substitutional_item() instead of the plain + left_expr? + Because left_expr might be a rollbackable item, and we fail to properly + rollback all copies of left_expr at end of execution, so we want to + avoid creating copies of left_expr as much as possible, so we use + real_item() instead. + Doing a proper rollback is difficult: the change was registered for the + original item which was the left argument of IN. Then this item was + copied to left_expr, which is copied below to substitution->args[0]. To + do a proper rollback, we would have to restore the content + of both copies as well as the original item. There might be more copies, + if AND items have been constructed. + The same applies to the right expression. + However, using real_item()/substitutional_item() brings its own + problems: for example, we lose information that the item is an outer + reference; the item can thus wrongly be considered for a Keyuse (causing + bug#17766653). + When WL#6570 removes the "rolling back" system, all + real_item()/substitutional_item() in this file should be removed. */ substitution= func->create(left_expr->real_item(), subs); DBUG_RETURN(RES_OK); @@ -1157,6 +1178,9 @@ Item_in_subselect::single_value_transformer(JOIN *join, } else { + /* + Grep for "WL#6570" to see the relevant comment about real_item. + */ Item *item= (Item*) select_lex->item_list.head()->real_item(); if (select_lex->table_list.elements) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fa85f3108f2..956551a0786 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3335,6 +3335,18 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, table_map usable_tables, SARGABLE_PARAM **sargables) { uint exists_optimize= 0; + + if (field->table->reginfo.join_tab == NULL) + { + /* + Due to a bug in IN-to-EXISTS (grep for real_item() in item_subselect.cc + for more info), an index over a field from an outer query might be + considered here, which is incorrect. Their query has been fully + optimized already so their reginfo.join_tab is NULL and we reject them. + */ + return; + } + if (!(field->flags & PART_KEY_FLAG)) { // Don't remove column IS NULL on a LEFT JOIN table From 130b5fbf91520e504194eb59c16a6ce38006ff7a Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 6 Oct 2015 07:09:36 +0530 Subject: [PATCH 14/66] Bug #19894161: FATAL SIGNAL 11 IN CONVERT_CHARSET_PARTITION_CONSTANT: SQL/SQL_PARTITION..CC:202 Issue: ----- This problem happens under the following conditions: 1) A table partitioned with a character column as the key. 2) The expressions specified in the partition definition requires a charset conversion. This can happen when the server's default collation is different from the expression's collation. 3) INSERT DELAYED is used to insert data into the table. SOLUTION: --------- While creating the delayed_insert object, initialize it with the relevant select_lex. --- sql/sql_insert.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 731aa82fe6e..7bfc7b083ac 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1887,7 +1887,7 @@ public: */ MDL_request grl_protection; - Delayed_insert() + Delayed_insert(SELECT_LEX *current_select) :locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0), status(0), handler_thread_initialized(FALSE), group_count(0) { @@ -1898,7 +1898,7 @@ public: USERNAME_LENGTH); thd.current_tablenr=0; thd.command=COM_DELAYED_INSERT; - thd.lex->current_select= 0; // for my_message_sql + thd.lex->current_select= current_select; thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() /* Prevent changes to global.lock_wait_timeout from affecting @@ -2078,7 +2078,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, */ if (! (di= find_handler(thd, table_list))) { - if (!(di= new Delayed_insert())) + if (!(di= new Delayed_insert(thd->lex->current_select))) goto end_create; mysql_mutex_lock(&LOCK_thread_count); thread_count++; @@ -2663,6 +2663,16 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->open_and_lock_table()) goto err; + /* + INSERT DELAYED generally expects thd->lex->current_select to be NULL, + since this is not an attribute of the current thread. This can lead to + problems if the thread that spawned the current one disconnects. + current_select will then point to freed memory. But current_select is + required to resolve the partition function. So, after fulfilling that + requirement, we set the current_select to 0. + */ + thd->lex->current_select= NULL; + /* Tell client that the thread is initialized */ mysql_cond_signal(&di->cond_client); From ecfc7c26166687d4ffb0ae13f518f44f256b9d65 Mon Sep 17 00:00:00 2001 From: "mysql-builder@oracle.com" <> Date: Thu, 8 Oct 2015 15:58:03 +0530 Subject: [PATCH 15/66] From 978c2a37c01a3adece280d7e9d560fcd67a48cb4 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Sun, 11 Oct 2015 17:06:03 -0400 Subject: [PATCH 16/66] MDEV-7640: CHANGE MASTER TO doesn't work with prepared statements When CHANGE MASTER was executed as a PS, its attributes were wrongly getting reset toward the end of PREPARE. As a result, the subsequent executions had no effect. Fixed by making sure that the CHANGE MASTER attributes are preserved during the lifetime of the PS. --- mysql-test/r/ps_change_master.result | 22 ++++++++++++++ mysql-test/t/ps_change_master.test | 45 ++++++++++++++++++++++++++++ sql/sql_lex.cc | 23 ++++++++++++++ sql/sql_lex.h | 2 ++ sql/sql_prepare.cc | 7 ++++- 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/ps_change_master.result create mode 100644 mysql-test/t/ps_change_master.test diff --git a/mysql-test/r/ps_change_master.result b/mysql-test/r/ps_change_master.result new file mode 100644 index 00000000000..25069a537a5 --- /dev/null +++ b/mysql-test/r/ps_change_master.result @@ -0,0 +1,22 @@ +# +# CHANGE MASTER TO doesn't work with prepared statements +# +CHANGE MASTER TO MASTER_HOST='host1', MASTER_USER='user1'; +# Master_Host : host1 +# Master_User : user1 +SET @s := "CHANGE MASTER TO MASTER_HOST='host2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +# Master_Host : host2 +# Master_User : user1 +SET @s := "CHANGE MASTER TO MASTER_USER='user2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +# Master_Host : host2 +# Master_User : user2 +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +# End of test diff --git a/mysql-test/t/ps_change_master.test b/mysql-test/t/ps_change_master.test new file mode 100644 index 00000000000..d756b8cd4fb --- /dev/null +++ b/mysql-test/t/ps_change_master.test @@ -0,0 +1,45 @@ +--source include/not_embedded.inc +--source include/have_log_bin.inc + +--echo # +--echo # CHANGE MASTER TO doesn't work with prepared statements +--echo # + +CHANGE MASTER TO MASTER_HOST='host1', MASTER_USER='user1'; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + +SET @s := "CHANGE MASTER TO MASTER_HOST='host2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + +SET @s := "CHANGE MASTER TO MASTER_USER='user2'"; +PREPARE stmt FROM @s; +EXECUTE stmt; +# Multiple executions should not hurt. +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); + +--echo # Master_Host : $master_host +--echo # Master_User : $master_user + + +# Reset +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; + +--echo # End of test diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9ccafa75ca7..957764c56bb 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -545,6 +545,16 @@ void lex_end(LEX *lex) DBUG_ENTER("lex_end"); DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex)); + lex_end_stage1(lex); + lex_end_stage2(lex); + + DBUG_VOID_RETURN; +} + +void lex_end_stage1(LEX *lex) +{ + DBUG_ENTER("lex_end_stage1"); + /* release used plugins */ if (lex->plugins.elements) /* No function call and no mutex if no plugins. */ { @@ -556,6 +566,19 @@ void lex_end(LEX *lex) delete lex->sphead; lex->sphead= NULL; + DBUG_VOID_RETURN; +} + +/* + MASTER INFO parameters (or state) is normally cleared towards the end + of a statement. But in case of PS, the state needs to be preserved during + its lifetime and should only be cleared on PS close or deallocation. +*/ +void lex_end_stage2(LEX *lex) +{ + DBUG_ENTER("lex_end_stage2"); + + /* Reset LEX_MASTER_INFO */ lex->mi.reset(); DBUG_VOID_RETURN; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aa59d76245b..6454da24af3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2940,6 +2940,8 @@ extern void lex_init(void); extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); +extern void lex_end_stage1(LEX *lex); +extern void lex_end_stage2(LEX *lex); void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex); int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex); extern int MYSQLlex(union YYSTYPE *yylval, THD *thd); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index e948813584d..4fcc007d104 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3416,7 +3416,8 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->mdl_context.release_transactional_locks(); } - lex_end(lex); + /* Preserve CHANGE MASTER attributes */ + lex_end_stage1(lex); cleanup_stmt(); thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; @@ -3997,6 +3998,10 @@ void Prepared_statement::deallocate() { /* We account deallocate in the same manner as mysqld_stmt_close */ status_var_increment(thd->status_var.com_stmt_close); + + /* It should now be safe to reset CHANGE MASTER parameters */ + lex_end_stage2(lex); + /* Statement map calls delete stmt on erase */ thd->stmt_map.erase(this); } From f92dd6ae6fb8922122049957b6ab7e07b6518bc2 Mon Sep 17 00:00:00 2001 From: Mithun C Y Date: Mon, 12 Oct 2015 12:56:36 +0530 Subject: [PATCH 17/66] Bug #20007383: HANDLE_FATAL_SIGNAL (SIG=11) IN UPDATE_REF_AND_KEYS. Issue: ====== The fulltext predicate is inside a subquery and involves an outer reference; it thus cannot be used for FT index look-up, but MySQL does not see it, which causes a illegal access. Solution: ========= Solution is backported from bug#21140088. Outer reference can not be used as argument of the MATCH function. Added check for outer reference. --- mysql-test/r/fulltext.result | 2 +- sql/item_func.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 7788a32ac90..28977b88f32 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -541,7 +541,7 @@ MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) DROP TABLE t1; CREATE TABLE t1(a TEXT); SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); -ERROR HY000: Incorrect arguments to AGAINST +ERROR HY000: Incorrect arguments to MATCH DROP TABLE t1; CREATE TABLE t1(a VARCHAR(64), FULLTEXT(a)); INSERT INTO t1 VALUES('awrd bwrd cwrd'),('awrd bwrd cwrd'),('awrd bwrd cwrd'); diff --git a/sql/item_func.cc b/sql/item_func.cc index 67fe15a7f0d..363745d7fd6 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, 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 @@ -5900,12 +5900,12 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) const_item_cache=0; for (uint i=1 ; i < arg_count ; i++) { - item=args[i]; - if (item->type() == Item::REF_ITEM) - args[i]= item= *((Item_ref *)item)->ref; - if (item->type() != Item::FIELD_ITEM) + item= args[i]= args[i]->real_item(); + if (item->type() != Item::FIELD_ITEM || + /* Cannot use FTS index with outer table field */ + (item->used_tables() & OUTER_REF_TABLE_BIT)) { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "MATCH"); return TRUE; } } From 3846b085521bce8e4600d4860dc3f2ea5f2ceb2d Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Wed, 14 Oct 2015 11:08:49 +0530 Subject: [PATCH 18/66] Bug #21602056 : CONCURRENT FLUSH PRIVILEGES + REVOKE/GRANT CRASHES IN WILD_CASE_COMPARE! Description:- Executing FLUSH PRIVILEGES and REVOKE/ GRANT concurrently crashes the server. Analysis:- Concurrent FLUSH PRIVILEGES and REVOKE/GRANT might trigger a small time frame in which REVOKE/GRANT fetches the "acl_proxy_user" information as a part of "acl_check_proxy_grant_access()". Meanwhile FLUSH PRIVILEGES deletes the old acl structures as a part of "acl_reload()". After which REVOKE/GRANT tries to access the hostname in "wild_case_compare()" which leads to a crash because of the invalid memory access. Fix:- Mutex lock on "acl_cache" is acquired before fetching "acl_proxy_user" information in "acl_check_proxy_grant_access()". --- sql/sql_acl.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fea1a209c20..a939ae72ecb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -50,6 +50,7 @@ #include "hostname.h" #include "sql_db.h" #include "sql_array.h" +#include "debug_sync.h" bool mysql_user_table_is_in_short_password_format= false; @@ -1194,6 +1195,8 @@ my_bool acl_reload(THD *thd) mysql_mutex_unlock(&acl_cache->lock); end: close_mysql_tables(thd); + + DEBUG_SYNC(thd, "after_acl_reload"); DBUG_RETURN(return_val); } @@ -7346,11 +7349,14 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, DBUG_RETURN(FALSE); } + mysql_mutex_lock(&acl_cache->lock); + /* check for matching WITH PROXY rights */ for (uint i=0; i < acl_proxy_users.elements; i++) { ACL_PROXY_USER *proxy= dynamic_element(&acl_proxy_users, i, ACL_PROXY_USER *); + DEBUG_SYNC(thd, "before_proxy_matches"); if (proxy->matches(thd->security_ctx->get_host()->ptr(), thd->security_ctx->user, thd->security_ctx->get_ip()->ptr(), @@ -7358,10 +7364,12 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, proxy->get_with_grant()) { DBUG_PRINT("info", ("found")); + mysql_mutex_unlock(&acl_cache->lock); DBUG_RETURN(FALSE); } } + mysql_mutex_unlock(&acl_cache->lock); my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0), thd->security_ctx->user, thd->security_ctx->host_or_ip); From a86191c69c95240ba3dcd9858341a30898c34285 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Wed, 14 Oct 2015 12:00:39 +0530 Subject: [PATCH 19/66] Bug #21235226 : THE --ENABLE-CLEARTEXT-PLUGIN IS NOT IMPLEMENTED IN ALL CLIENT PROGRAMS Description: Option "enable-cleartext-plugin" is not available for the following client utilities:- mysqldump mysqlimport mysqlshow mysqlcheck Analysis: The unavailability of this option limits the features like PAM authentication from using the above mentioned utilities. Fix: Option "enable-cleartext-plugin" is implemented in the above mentioned client utilities. --- client/mysqlcheck.c | 15 ++++- client/mysqldump.c | 15 ++++- client/mysqlimport.c | 13 ++++ client/mysqlshow.c | 15 ++++- mysql-test/r/enable_cleartext_plugin.result | 35 ++++++++++ .../t/enable_cleartext_plugin-master.opt | 2 + mysql-test/t/enable_cleartext_plugin.test | 65 +++++++++++++++++++ 7 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/enable_cleartext_plugin.result create mode 100644 mysql-test/t/enable_cleartext_plugin-master.opt create mode 100644 mysql-test/t/enable_cleartext_plugin.test diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ca06a85bec0..0d5570434e4 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2015, 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 @@ -42,6 +42,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, opt_write_binlog= 1; static uint verbose = 0, opt_mysql_port=0; +static uint opt_enable_cleartext_plugin= 0; +static my_bool using_opt_enable_cleartext_plugin= 0; static int my_end_arg; static char * opt_mysql_unix_port = 0; static char *opt_password = 0, *current_user = 0, @@ -110,6 +112,10 @@ static struct my_option my_long_options[] = "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN, + "Enable/disable the clear text authentication plugin.", + &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"fast",'F', "Check only tables that haven't been closed properly.", &opt_fast, &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -326,6 +332,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), verbose++; break; case 'V': print_version(); exit(0); + case OPT_ENABLE_CLEARTEXT_PLUGIN: + using_opt_enable_cleartext_plugin= TRUE; + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); @@ -880,6 +889,10 @@ static int dbConnect(char *host, char *user, char *passwd) if (opt_default_auth && *opt_default_auth) mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (using_opt_enable_cleartext_plugin) + mysql_options(&mysql_connection, MYSQL_ENABLE_CLEARTEXT_PLUGIN, + (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))) diff --git a/client/mysqldump.c b/client/mysqldump.c index 2a873903d60..6bb249134e8 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, 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 @@ -129,6 +129,8 @@ static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2 +static uint opt_enable_cleartext_plugin= 0; +static my_bool using_opt_enable_cleartext_plugin= 0; static uint opt_mysql_port= 0, opt_master_data; static uint opt_slave_data; static uint my_end_arg; @@ -513,6 +515,10 @@ static struct my_option my_long_options[] = "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN, + "Enable/disable the clear text authentication plugin.", + &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -883,6 +889,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; break; } + case (int) OPT_ENABLE_CLEARTEXT_PLUGIN: + using_opt_enable_cleartext_plugin= TRUE; + break; case (int) OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); @@ -1485,6 +1494,10 @@ static int connect_to_db(char *host, char *user,char *passwd) if (opt_default_auth && *opt_default_auth) mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (using_opt_enable_cleartext_plugin) + 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))) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 813c1baf793..f71111f7e9e 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -49,6 +49,8 @@ static char *opt_password=0, *current_user=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, *opt_columns=0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; +static uint opt_enable_cleartext_plugin= 0; +static my_bool using_opt_enable_cleartext_plugin= 0; static uint opt_mysql_port= 0, opt_protocol= 0; static char * opt_mysql_unix_port=0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; @@ -88,6 +90,10 @@ static struct my_option my_long_options[] = GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"delete", 'd', "First delete all rows from table.", &opt_delete, &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN, + "Enable/disable the clear text authentication plugin.", + &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"fields-terminated-by", OPT_FTB, "Fields in the input file are terminated by the given string.", &fields_terminated, &fields_terminated, 0, @@ -234,6 +240,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_local_file=1; break; #endif + case OPT_ENABLE_CLEARTEXT_PLUGIN: + using_opt_enable_cleartext_plugin= TRUE; + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); @@ -435,6 +444,10 @@ static MYSQL *db_connect(char *host, char *database, if (opt_default_auth && *opt_default_auth) mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (using_opt_enable_cleartext_plugin) + mysql_options(mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, + (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, diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 5677681541b..a6705548bcb 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, 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 @@ -37,6 +37,8 @@ static uint my_end_arg= 0; static uint opt_verbose=0; static char *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; static char *opt_plugin_dir= 0, *opt_default_auth= 0; +static uint opt_enable_cleartext_plugin= 0; +static my_bool using_opt_enable_cleartext_plugin= 0; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; @@ -133,6 +135,10 @@ int main(int argc, char **argv) if (opt_default_auth && *opt_default_auth) mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (using_opt_enable_cleartext_plugin) + 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, @@ -195,6 +201,10 @@ static struct my_option my_long_options[] = "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN, + "Enable/disable the clear text authentication plugin.", + &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", &host, &host, 0, GET_STR, @@ -309,6 +319,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_protocol = MYSQL_PROTOCOL_PIPE; #endif break; + case (int) OPT_ENABLE_CLEARTEXT_PLUGIN: + using_opt_enable_cleartext_plugin= TRUE; + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); diff --git a/mysql-test/r/enable_cleartext_plugin.result b/mysql-test/r/enable_cleartext_plugin.result new file mode 100644 index 00000000000..b57a6fc0e16 --- /dev/null +++ b/mysql-test/r/enable_cleartext_plugin.result @@ -0,0 +1,35 @@ +# +# Bug #21235226 : THE --ENABLE-CLEARTEXT-PLUGIN IS NOT IMPLEMENTED +# IN ALL CLIENT PROGRAMS +# +CREATE DATABASE db21235226; +USE db21235226; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM t1; +a +1 +2 +CREATE USER uplain@localhost IDENTIFIED WITH 'cleartext_plugin_server' + AS 'cleartext_test'; +GRANT ALL PRIVILEGES ON *.* TO uplain@localhost; +mysqldump: Got error: 2059: Authentication plugin 'mysql_clear_password' cannot be loaded: plugin not enabled when trying to connect +SELECT * FROM t1; +a +mysqlimport: Error: 2059 Authentication plugin 'mysql_clear_password' cannot be loaded: plugin not enabled +SELECT * FROM t1; +a +1 +2 +mysqlshow: Authentication plugin 'mysql_clear_password' cannot be loaded: plugin not enabled +Database: db21235226 ++--------+ +| Tables | ++--------+ +| t1 | ++--------+ +mysqlcheck: Got error: 2059: Authentication plugin 'mysql_clear_password' cannot be loaded: plugin not enabled when trying to connect +db21235226.t1 OK +DROP TABLE t1; +DROP DATABASE db21235226; +DROP USER uplain@localhost; diff --git a/mysql-test/t/enable_cleartext_plugin-master.opt b/mysql-test/t/enable_cleartext_plugin-master.opt new file mode 100644 index 00000000000..3536d102387 --- /dev/null +++ b/mysql-test/t/enable_cleartext_plugin-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_LOAD diff --git a/mysql-test/t/enable_cleartext_plugin.test b/mysql-test/t/enable_cleartext_plugin.test new file mode 100644 index 00000000000..e2ae35c8e73 --- /dev/null +++ b/mysql-test/t/enable_cleartext_plugin.test @@ -0,0 +1,65 @@ +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +--echo # +--echo # Bug #21235226 : THE --ENABLE-CLEARTEXT-PLUGIN IS NOT IMPLEMENTED +--echo # IN ALL CLIENT PROGRAMS +--echo # + +CREATE DATABASE db21235226; +USE db21235226; + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM t1; + +CREATE USER uplain@localhost IDENTIFIED WITH 'cleartext_plugin_server' + AS 'cleartext_test'; + +GRANT ALL PRIVILEGES ON *.* TO uplain@localhost; + +#Reset the LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN variable. +let LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=N; + +#Scenario 1 : MYSQL_DUMP without --enable_cleartext_plugin +# Should get CR_AUTH_PLUGIN_CANNOT_LOAD error +--error 2 +--exec $MYSQL_DUMP --user=uplain --password=cleartext_test --tab=$MYSQLTEST_VARDIR/tmp/ db21235226 2>&1 + +#Scenario 2 : MYSQL_DUMP with --enable_cleartext_plugin +--exec $MYSQL_DUMP --enable_cleartext_plugin --user=uplain --password=cleartext_test --tab=$MYSQLTEST_VARDIR/tmp/ db21235226 +--exec $MYSQL --enable_cleartext_plugin --user=uplain --password=cleartext_test db21235226 < $MYSQLTEST_VARDIR/tmp/t1.sql +SELECT * FROM t1; + +#Scenario 3 : MYSQL_IMPORT without --enable_cleartext_plugin +# Should get CR_AUTH_PLUGIN_CANNOT_LOAD error +--replace_regex /.*mysqlimport(\.exe)*/mysqlimport/ +--error 1 +--exec $MYSQL_IMPORT --user=uplain --password=cleartext_test --silent db21235226 $MYSQLTEST_VARDIR/tmp/t1.txt 2>&1 + +#Scenario 4 : MYSQL_IMPORT with --enable_cleartext_plugin +--exec $MYSQL_IMPORT --enable_cleartext_plugin --user=uplain --password=cleartext_test --silent db21235226 $MYSQLTEST_VARDIR/tmp/t1.txt +SELECT * FROM t1; + +#Scenario 5 : MYSQL_SHOW without --enable_cleartext_plugin +# Should get CR_AUTH_PLUGIN_CANNOT_LOAD error +--replace_regex /.*mysqlshow(\.exe)*/mysqlshow/ +--error 1 +--exec $MYSQL_SHOW --user=uplain --password=cleartext_test db21235226 2>&1 + +#Scenario 6 : MYSQL_SHOW with --enable_cleartext_plugin +--exec $MYSQL_SHOW --enable_cleartext_plugin --user=uplain --password=cleartext_test db21235226 + +#Scenario 7 : MYSQL_CHECK without --enable_cleartext_plugin +# Should get CR_AUTH_PLUGIN_CANNOT_LOAD error +--replace_regex /.*mysqlcheck(\.exe)*/mysqlcheck/ +--error 2 +--exec $MYSQL_CHECK --user=uplain --password=cleartext_test db21235226 t1 2>&1 + +#Scenario 8 : MYSQL_CHECK with --enable_cleartext_plugin +--exec $MYSQL_CHECK --enable_cleartext_plugin --user=uplain --password=cleartext_test db21235226 t1 + +#Cleanup +DROP TABLE t1; +DROP DATABASE db21235226; +DROP USER uplain@localhost; From 74a503b4ceecf0e813666fc8cdbcb92e580442bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Fri, 16 Oct 2015 09:56:09 +0200 Subject: [PATCH 20/66] BUG#22024764 MAIN.EVENTS_1 FAILS BECAUSE IT USES ENDDATE OF 20151010 Move date 10 years forward to let test pass for some more years. --- mysql-test/r/events_1.result | 2 +- mysql-test/t/events_1.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/events_1.result b/mysql-test/r/events_1.result index 29e81975c87..05223b0afcf 100644 --- a/mysql-test/r/events_1.result +++ b/mysql-test/r/events_1.result @@ -114,7 +114,7 @@ create table t_event3 (a int, b float); drop event if exists event3; Warnings: Note 1305 Event event3 does not exist -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); select count(*) from t_event3; count(*) 0 diff --git a/mysql-test/t/events_1.test b/mysql-test/t/events_1.test index 7f31e3fc881..bb71b334219 100644 --- a/mysql-test/t/events_1.test +++ b/mysql-test/t/events_1.test @@ -125,7 +125,7 @@ drop event existant; create table t_event3 (a int, b float); drop event if exists event3; -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); let $wait_condition=SELECT count(*)=0 from t_event3; --source include/wait_condition.inc select count(*) from t_event3; From df804208657dfae10e24d656d9228f05e57b14a5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 21 Oct 2015 14:42:56 +0200 Subject: [PATCH 21/66] fix events_1 test for October 2015 cherry-picked 7454f1c5 from 10.1 --- mysql-test/r/events_1.result | 3 ++- mysql-test/t/events_1.test | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/events_1.result b/mysql-test/r/events_1.result index 5a64cf14ef5..475a190d73d 100644 --- a/mysql-test/r/events_1.result +++ b/mysql-test/r/events_1.result @@ -114,7 +114,8 @@ create table t_event3 (a int, b float); drop event if exists event3; Warnings: Note 1305 Event event3 does not exist -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) +comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); select count(*) from t_event3; count(*) 0 diff --git a/mysql-test/t/events_1.test b/mysql-test/t/events_1.test index 7f31e3fc881..7b0012c7079 100644 --- a/mysql-test/t/events_1.test +++ b/mysql-test/t/events_1.test @@ -125,7 +125,8 @@ drop event existant; create table t_event3 (a int, b float); drop event if exists event3; -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) + comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); let $wait_condition=SELECT count(*)=0 from t_event3; --source include/wait_condition.inc select count(*) from t_event3; From dea23408660130f04af7e954811122d86656900f Mon Sep 17 00:00:00 2001 From: Mithun C Y Date: Thu, 22 Oct 2015 17:02:12 +0530 Subject: [PATCH 22/66] Bug #20447262: REPEATED EXECUTION OF PREPARED STATEMENTS FAILS, IF DEFAULT DATABASE IS CHANGED. Issue: ====== While re-preparing the statement in Prepared_statement::swap_prepared_statement for swapping the database of PS we only swapped the db string but not its length. This resulted in mismatch between the actual string and its length. In one particular case where db of PS was dropped, we have db as null pointer and length as non-zero. strdup which used above values resulted in invalid memory access. Solution: ========= In Prepared_statement::swap_prepared_statement also swap db_length along with db variable. Also, remove DBUG_ASSERT(db_length == copy->db_length) as this have no meaning if they are 2 different entities. --- sql/sql_prepare.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 48d23cd5d21..f2f74c68085 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2015, 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 @@ -3668,8 +3668,8 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy) swap_variables(LEX_STRING, name, copy->name); /* Ditto */ swap_variables(char *, db, copy->db); + swap_variables(size_t, db_length, copy->db_length); - DBUG_ASSERT(db_length == copy->db_length); DBUG_ASSERT(param_count == copy->param_count); DBUG_ASSERT(thd == copy->thd); last_error[0]= '\0'; From a60740607c9581ed2bf92bdd087139ea8d872484 Mon Sep 17 00:00:00 2001 From: Srikanth B R Date: Mon, 26 Oct 2015 16:19:11 +0530 Subject: [PATCH 23/66] BUG#22084221 : TEST IMPROVEMENT FOR MAIN.EVENTS_1 Issue: main.events_1 will fail after 10-10-2015 due to hardcoded dates specified with events. Fix: Replace harcoded dates with current dates and offset. --- mysql-test/r/events_1.result | 2 +- mysql-test/t/events_1.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/events_1.result b/mysql-test/r/events_1.result index 05223b0afcf..679eb63be35 100644 --- a/mysql-test/r/events_1.result +++ b/mysql-test/r/events_1.result @@ -114,7 +114,7 @@ create table t_event3 (a int, b float); drop event if exists event3; Warnings: Note 1305 Event event3 does not exist -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add(curdate(), interval 5 minute) ends date_add(curdate(), interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); select count(*) from t_event3; count(*) 0 diff --git a/mysql-test/t/events_1.test b/mysql-test/t/events_1.test index bb71b334219..032d5ecd380 100644 --- a/mysql-test/t/events_1.test +++ b/mysql-test/t/events_1.test @@ -125,7 +125,7 @@ drop event existant; create table t_event3 (a int, b float); drop event if exists event3; -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add(curdate(), interval 5 minute) ends date_add(curdate(), interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); let $wait_condition=SELECT count(*)=0 from t_event3; --source include/wait_condition.inc select count(*) from t_event3; From 1942506b82897e498493cc3ec274a2b402c4d105 Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Thu, 29 Oct 2015 13:35:32 +0530 Subject: [PATCH 24/66] DESCRIPTION =========== When doing an upgrade, you execute mysql_upgrade. If mysql_upgrade fails to connect or it connects with a user without the proper privileges, it will return the error: FATAL ERROR: Upgrade failed which is not very informative. ANALYSIS ======== In main() and check_version_match(), the condition for errors are clubbed together and throw the same error msg. The functions need to be splitted up and the corresponding error msgs have to be displayed. FIX === Splitted the functions and added the specific error msg. --- client/mysql_upgrade.c | 36 ++++++++++++++++++++----------- mysql-test/r/mysql_upgrade.result | 8 ++++++- mysql-test/t/mysql_upgrade.test | 9 ++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 33f9f030c1e..fcbde2653e8 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2006, 2015, 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 @@ -862,10 +862,17 @@ static int check_version_match(void) if (init_dynamic_string(&ds_version, NULL, NAME_CHAR_LEN, NAME_CHAR_LEN)) die("Out of memory"); - if (run_query("show variables like 'version'", - &ds_version, FALSE) || - extract_variable_from_show(&ds_version, version_str)) + + if (run_query("show variables like 'version'", &ds_version, FALSE)) { + fprintf(stderr, "Error: Failed while fetching Server version! Could be" + " due to unauthorized access.\n"); + dynstr_free(&ds_version); + return 1; /* Query failed */ + } + if (extract_variable_from_show(&ds_version, version_str)) + { + fprintf(stderr, "Error: Failed while extracting Server version!\n"); dynstr_free(&ds_version); return 1; /* Query failed */ } @@ -955,15 +962,20 @@ int main(int argc, char **argv) /* Run "mysqlcheck" and "mysql_fix_privilege_tables.sql" */ - if ((!opt_systables_only && - (run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) || - run_sql_fix_privilege_tables()) + if (!opt_systables_only) { - /* - The upgrade failed to complete in some way or another, - significant error message should have been printed to the screen - */ - die("Upgrade failed" ); + if (run_mysqlcheck_fixnames()) + die("Error during call to mysql_check for fixing the db/tables names."); + + if (run_mysqlcheck_upgrade()) + die("Error during call to mysql_check for upgrading the tables names."); + } + + if (run_sql_fix_privilege_tables()) + { + /* Specific error msg (if present) would be printed in the function call + * above */ + die("Upgrade failed"); } verbose("OK"); diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 8ce3f426375..6ba874f327a 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -86,7 +86,7 @@ mysql.user OK DROP USER mysqltest1@'%'; Run mysql_upgrade with a non existing server socket mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errno) when trying to connect -FATAL ERROR: Upgrade failed +FATAL ERROR: Error during call to mysql_check for fixing the db/tables names. set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE'; mtr.global_suppressions OK mtr.test_suppressions OK @@ -226,4 +226,10 @@ mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK +# +# Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR +# +Run mysql_upgrade with unauthorized access +Error: Failed while fetching Server version! Could be due to unauthorized access. +FATAL ERROR: Upgrade failed End of tests diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index c52a328c28b..faf7ed21a28 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -124,4 +124,13 @@ let $MYSQLD_DATADIR= `select @@datadir`; # so the following command should never fail. --remove_file $MYSQLD_DATADIR/mysql_upgrade_info + +--echo # +--echo # Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR +--echo # + +--echo Run mysql_upgrade with unauthorized access +--error 1 +--exec $MYSQL_UPGRADE --skip-verbose --user=root --password=wrong_password 2>&1 + --echo End of tests From 9b6ac73419256cf3c9554d8a782c4eaee6c6cf79 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Mon, 2 Nov 2015 16:30:57 +0530 Subject: [PATCH 25/66] Bug#20755389 SERVER CRASHES IN ITEM_FUNC_GROUP_CONCAT::FIX_FIELDS ON 2ND EXECUTION OF PS Description: ------------ When MySQL calls 'EXECUTE stmt' firstly to deal with ORDER BY clause which is similar with 'ORDER BY 1,(t2a.f2+1)' in find_order_in_list(), it believes the first expression is a position, the function replaces the pointer of the first expression with Item_field object associated with a temporary table field, then releases it after the end of the execution, that behavior destroys the pointer of first expression. After that, when MySQL calls 'EXECUTE stmt' once more, the first expression points to an invalid pointer, so it crashed. Fix: ---- If an item of ORDER clause is a location, reset 'args' with a original value. --- sql/item_sum.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index f491795c449..b63cbbd3c26 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3184,7 +3184,9 @@ void Item_func_group_concat::cleanup() ORDER **order_ptr= order; for (uint i= 0; i < arg_count_order; i++) { - (*order_ptr)->item= &args[arg_count_field + i]; + + if ((*order_ptr)->counter_used) + args[arg_count_field + i]= (*order_ptr)->item_ptr; order_ptr++; } DBUG_VOID_RETURN; From 5e9a50efc37c233f1e2a3616f8bcb36315aba4c2 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 3 Nov 2015 07:43:54 +0530 Subject: [PATCH 26/66] Bug #22023218: MYSQL 5.5: MAIN.FULLTEXT HAS VALGRIND ISSUES. Issue ----- This problem occurs when varchar columns are used in a internal temporary table. The type of the field is set incorrectly to the generic FIELD_NORMAL type. This in turn results in an inaccurate calculation of the record length. Valgrind issues will occur since initialization has not happend for some bytes. Fix ---- While creating the temporary table, the type of the field needs to be to set FIELD_VARCHAR. This will allow myisam to calculate the record length accurately. This fix is a backport of BUG#13350136. --- sql/sql_select.cc | 36 ++++++++++++++++++++++++++---------- storage/myisam/mi_create.c | 5 ++--- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 956551a0786..96f60d46651 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10313,8 +10313,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, uint temp_pool_slot=MY_BIT_NONE; uint fieldnr= 0; ulong reclength, string_total_length; - bool using_unique_constraint= 0; - bool use_packed_rows= 0; + bool using_unique_constraint= false; + bool use_packed_rows= false; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); char *tmpname,path[FN_REFLEN]; uchar *pos, *group_buff, *bitmaps; @@ -10370,10 +10370,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, { (*tmp->item)->marker=4; // Store null in key if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB) - using_unique_constraint=1; + using_unique_constraint= true; } if (param->group_length >= MAX_BLOB_WIDTH) - using_unique_constraint=1; + using_unique_constraint= true; if (group) distinct=0; // Can't use distinct } @@ -10588,6 +10588,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, *blob_field++= fieldnr; blob_count++; } + + if (new_field->real_type() == MYSQL_TYPE_STRING || + new_field->real_type() == MYSQL_TYPE_VARCHAR) + { + string_count++; + string_total_length+= new_field->pack_length(); + } + if (item->marker == 4 && item->maybe_null) { group_null_items++; @@ -10638,7 +10646,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, if (group && (param->group_parts > table->file->max_key_parts() || param->group_length > table->file->max_key_length())) - using_unique_constraint=1; + using_unique_constraint= true; } else { @@ -10791,6 +10799,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, field->real_type() == MYSQL_TYPE_STRING && length >= MIN_STRING_LENGTH_TO_PACK_ROWS) recinfo->type=FIELD_SKIP_ENDSPACE; + else if (use_packed_rows && + field->real_type() == MYSQL_TYPE_VARCHAR && + length >= MIN_STRING_LENGTH_TO_PACK_ROWS) + recinfo->type= FIELD_VARCHAR; else recinfo->type=FIELD_NORMAL; if (!--hidden_field_count) @@ -11229,11 +11241,15 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, create_info.data_file_length= ~(ulonglong) 0; if ((error=mi_create(share->table_name.str, share->keys, &keydef, - (uint) (param->recinfo-param->start_recinfo), - param->start_recinfo, - share->uniques, &uniquedef, - &create_info, - HA_CREATE_TMP_TABLE))) + (uint) (param->recinfo-param->start_recinfo), + param->start_recinfo, + share->uniques, &uniquedef, + &create_info, + HA_CREATE_TMP_TABLE | + ((share->db_create_options & HA_OPTION_PACK_RECORD) ? + HA_PACK_RECORD : 0) + ))) + { table->file->print_error(error,MYF(0)); /* purecov: inspected */ /* diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 8873b8f71fb..02fa88cbab9 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, 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 @@ -462,7 +462,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_del[i]=HA_OFFSET_ERROR; unique_key_parts=0; - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++) { uniquedef->key=keys+i; @@ -727,7 +726,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, #endif } /* Create extra keys for unique definitions */ - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; + offset=real_reclength - uniques * MI_UNIQUE_HASH_LENGTH; bzero((char*) &tmp_keydef,sizeof(tmp_keydef)); bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg)); for (i=0; i < uniques ; i++) From 75bfdea40f9c2954d8eadccbadc795231e310ab7 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 3 Nov 2015 07:59:57 +0530 Subject: [PATCH 27/66] Bug #22123583: MYSQL 5.5: MAIN.SP HAS VALGRIND ISSUES Issue: ----- When a varchar column is used to fill the record in an internal temporary table, the length of the string stored in the column is not taken into account. Instead the default length of packed data is used to copy with memmove. This will cause valgrind issues since some bytes are uninitialized. SOLUTION: --------- The solution is to take into account the length of the string stored in the column while filling the record. This fix is a backport of BUG#13389854. --- sql/field.h | 20 +++--- sql/field_conv.cc | 163 ++++++++++++++++++++++++++-------------------- 2 files changed, 104 insertions(+), 79 deletions(-) diff --git a/sql/field.h b/sql/field.h index 73922460037..cc4b79a9e4a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -209,7 +209,7 @@ public: DBUG_ENTER("Field::pack_length_from_metadata"); DBUG_RETURN(field_metadata); } - virtual uint row_pack_length() { return 0; } + virtual uint row_pack_length() const { return 0; } virtual int save_field_metadata(uchar *first_byte) { return do_save_field_metadata(first_byte); } @@ -733,7 +733,7 @@ public: int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); uint is_equal(Create_field *new_field); - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } uint32 pack_length_from_metadata(uint field_metadata) { uint32 length= pack_length(); DBUG_PRINT("result", ("pack_length_from_metadata(%d): %u", @@ -923,7 +923,7 @@ public: uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } uint pack_length_from_metadata(uint field_metadata); - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } bool compatible_field_size(uint field_metadata, Relay_log_info *rli, uint16 mflags, int *order_var); uint is_equal(Create_field *new_field); @@ -1195,7 +1195,7 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(float); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } void sql_type(String &str) const; private: int do_save_field_metadata(uchar *first_byte); @@ -1235,7 +1235,7 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(double); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } void sql_type(String &str) const; private: int do_save_field_metadata(uchar *first_byte); @@ -1621,7 +1621,7 @@ public: } bool compatible_field_size(uint field_metadata, Relay_log_info *rli, uint16 mflags, int *order_var); - uint row_pack_length() { return field_length; } + uint row_pack_length() const { return field_length; } int pack_cmp(const uchar *a,const uchar *b,uint key_length, my_bool insert_or_update); int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update); @@ -1671,7 +1671,7 @@ public: enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } bool match_collation_to_optimize_range() const { return TRUE; } enum ha_base_keytype key_type() const; - uint row_pack_length() { return field_length; } + uint row_pack_length() const { return field_length; } bool zero_pack() const { return 0; } int reset(void) { bzero(ptr,field_length+length_bytes); return 0; } uint32 pack_length() const { return (uint32) field_length+length_bytes; } @@ -1797,7 +1797,7 @@ public: */ uint32 pack_length_no_ptr() const { return (uint32) (packlength); } - uint row_pack_length() { return pack_length_no_ptr(); } + uint row_pack_length() const { return pack_length_no_ptr(); } uint32 sort_length() const; virtual uint32 max_data_length() const { @@ -1960,7 +1960,7 @@ public: enum_field_types real_type() const { return MYSQL_TYPE_ENUM; } uint pack_length_from_metadata(uint field_metadata) { return (field_metadata & 0x00ff); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } bool eq_def(Field *field); @@ -2081,7 +2081,7 @@ public: uint32 pack_length() const { return (uint32) (field_length + 7) / 8; } uint32 pack_length_in_rec() const { return bytes_in_rec; } uint pack_length_from_metadata(uint field_metadata); - uint row_pack_length() + uint row_pack_length() const { return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); } bool compatible_field_size(uint metadata, Relay_log_info *rli, uint16 mflags, int *order_var); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 14c4fd257fe..7eb49b9dd92 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -447,79 +447,99 @@ static void do_expand_string(Copy_field *copy) copy->to_length-copy->from_length, ' '); } +/** + Find how many bytes should be copied between Field_varstring fields + so that only the bytes in use in the 'from' field are copied. + Handles single and multi-byte charsets. Adds warning if not all + bytes in 'from' will fit into 'to'. -static void do_varstring1(Copy_field *copy) + @param to Variable length field we're copying to + @param from Variable length field we're copying from + + @return Number of bytes that should be copied from 'from' to 'to'. +*/ +static uint get_varstring_copy_length(Field_varstring *to, + const Field_varstring *from) { - uint length= (uint) *(uchar*) copy->from_ptr; - if (length > copy->to_length- 1) + CHARSET_INFO * const cs= from->charset(); + const bool is_multibyte_charset= (cs->mbmaxlen != 1); + const uint to_byte_length= to->row_pack_length(); + + uint bytes_to_copy; + if (from->length_bytes == 1) + bytes_to_copy= *from->ptr; + else + bytes_to_copy= uint2korr(from->ptr); + + if (is_multibyte_charset) { - length=copy->to_length - 1; - if (copy->from_field->table->in_use->count_cuted_fields) - copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1); + int well_formed_error; + const char *from_beg= reinterpret_cast(from->ptr + from->length_bytes); + const uint to_char_length= (to_byte_length) / cs->mbmaxlen; + const uint from_byte_length= bytes_to_copy; + bytes_to_copy= + cs->cset->well_formed_len(cs, from_beg, + from_beg + from_byte_length, + to_char_length, + &well_formed_error); + if (bytes_to_copy < from_byte_length) + { + if (from->table->in_use->count_cuted_fields) + to->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1); + } } - *(uchar*) copy->to_ptr= (uchar) length; - memcpy(copy->to_ptr+1, copy->from_ptr + 1, length); -} - - -static void do_varstring1_mb(Copy_field *copy) -{ - int well_formed_error; - CHARSET_INFO *cs= copy->from_field->charset(); - uint from_length= (uint) *(uchar*) copy->from_ptr; - const uchar *from_ptr= copy->from_ptr + 1; - uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen; - uint length= cs->cset->well_formed_len(cs, (char*) from_ptr, - (char*) from_ptr + from_length, - to_char_length, &well_formed_error); - if (length < from_length) + else { - if (current_thd->count_cuted_fields) - copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1); + if (bytes_to_copy > (to_byte_length)) + { + bytes_to_copy= to_byte_length; + if (from->table->in_use->count_cuted_fields) + to->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1); + } } - *copy->to_ptr= (uchar) length; - memcpy(copy->to_ptr + 1, from_ptr, length); + return bytes_to_copy; } +/** + A variable length string field consists of: + (a) 1 or 2 length bytes, depending on the VARCHAR column definition + (b) as many relevant character bytes, as defined in the length byte(s) + (c) unused padding up to the full length of the column -static void do_varstring2(Copy_field *copy) + This function only copies (a) and (b) + + Condition for using this function: to and from must use the same + number of bytes for length, i.e: to->length_bytes==from->length_bytes + + @param to Variable length field we're copying to + @param from Variable length field we're copying from +*/ +static void copy_field_varstring(Field_varstring * const to, + const Field_varstring * const from) { - uint length=uint2korr(copy->from_ptr); - if (length > copy->to_length- HA_KEY_BLOB_LENGTH) - { - length=copy->to_length-HA_KEY_BLOB_LENGTH; - if (copy->from_field->table->in_use->count_cuted_fields) - copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1); - } - int2store(copy->to_ptr,length); - memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH, - length); + const uint length_bytes= from->length_bytes; + DBUG_ASSERT(length_bytes == to->length_bytes); + DBUG_ASSERT(length_bytes == 1 || length_bytes == 2); + + const uint bytes_to_copy= get_varstring_copy_length(to, from); + if (length_bytes == 1) + *to->ptr= static_cast(bytes_to_copy); + else + int2store(to->ptr, bytes_to_copy); + + // memcpy should not be used for overlaping memory blocks + DBUG_ASSERT(to->ptr != from->ptr); + memcpy(to->ptr + length_bytes, from->ptr + length_bytes, bytes_to_copy); } - -static void do_varstring2_mb(Copy_field *copy) +static void do_varstring(Copy_field *copy) { - int well_formed_error; - CHARSET_INFO *cs= copy->from_field->charset(); - uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen; - uint from_length= uint2korr(copy->from_ptr); - const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; - uint length= cs->cset->well_formed_len(cs, (char*) from_beg, - (char*) from_beg + from_length, - char_length, &well_formed_error); - if (length < from_length) - { - if (current_thd->count_cuted_fields) - copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1); - } - int2store(copy->to_ptr, length); - memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length); + copy_field_varstring(static_cast(copy->to_field), + static_cast(copy->from_field)); } - + /*************************************************************************** ** The different functions that fills in a Copy_field class @@ -711,11 +731,7 @@ Copy_field::get_copy_func(Field *to,Field *from) ((Field_varstring*) from)->length_bytes) return do_field_string; else - return (((Field_varstring*) to)->length_bytes == 1 ? - (from->charset()->mbmaxlen == 1 ? do_varstring1 : - do_varstring1_mb) : - (from->charset()->mbmaxlen == 1 ? do_varstring2 : - do_varstring2_mb)); + return do_varstring; } else if (to_length < from_length) return (from->charset()->mbmaxlen == 1 ? @@ -771,8 +787,20 @@ Copy_field::get_copy_func(Field *to,Field *from) int field_conv(Field *to,Field *from) { if (to->real_type() == from->real_type() && - !(to->type() == MYSQL_TYPE_BLOB && to->table->copy_blobs)) + !(to->type() == MYSQL_TYPE_BLOB && to->table->copy_blobs) && + to->charset() == from->charset()) { + if (to->real_type() == MYSQL_TYPE_VARCHAR && + from->real_type() == MYSQL_TYPE_VARCHAR) + { + Field_varstring *to_vc= static_cast(to); + const Field_varstring *from_vc= static_cast(from); + if (to_vc->length_bytes == from_vc->length_bytes) + { + copy_field_varstring(to_vc, from_vc); + return 0; + } + } if (to->pack_length() == from->pack_length() && !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && to->real_type() != MYSQL_TYPE_ENUM && @@ -781,15 +809,12 @@ int field_conv(Field *to,Field *from) (to->real_type() != MYSQL_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) && - from->charset() == to->charset() && to->table->s->db_low_byte_first == from->table->s->db_low_byte_first && (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != MYSQL_TYPE_DATE && to->type() != MYSQL_TYPE_DATETIME)) && - (from->real_type() != MYSQL_TYPE_VARCHAR || - ((Field_varstring*)from)->length_bytes == - ((Field_varstring*)to)->length_bytes)) + (from->real_type() != MYSQL_TYPE_VARCHAR)) { // Identical fields // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x' memmove(to->ptr, from->ptr, to->pack_length()); From 5f2d3479ffed18e28435c9ad130d400e7290e0bb Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 4 Nov 2015 16:12:27 +0530 Subject: [PATCH 28/66] BUG 22005375 - DEVEL PACKAGES INSTALL FAILS IF MYSQL-CONNECTOR-C-DEVEL-6.1.6 IS INSTALLED As MySQL Connector C 6.1 is end of life, added conflict with mysql-connector-c-devel dependencies --- packaging/rpm-oel/mysql.spec.in | 2 +- packaging/rpm-sles/mysql.spec.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index 2d91975f56c..3136e47230b 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -301,7 +301,7 @@ Obsoletes: mysql-devel < %{version}-%{release} Obsoletes: mariadb-devel Provides: mysql-devel = %{version}-%{release} Provides: mysql-devel%{?_isa} = %{version}-%{release} -Conflicts: mysql-connector-c-shared-devel < 6.2 +Conflicts: mysql-connector-c-devel < 6.2 %description devel This package contains the development header files and libraries necessary diff --git a/packaging/rpm-sles/mysql.spec.in b/packaging/rpm-sles/mysql.spec.in index b5fb5b77642..cb42dfacf71 100644 --- a/packaging/rpm-sles/mysql.spec.in +++ b/packaging/rpm-sles/mysql.spec.in @@ -268,7 +268,7 @@ Obsoletes: mariadb-devel Obsoletes: libmysqlclient-devel Provides: mysql-devel = %{version}-%{release} Provides: libmysqlclient-devel = %{version}-%{release} -Conflicts: mysql-connector-c-shared-devel < 6.2 +Conflicts: mysql-connector-c-devel < 6.2 %description devel This package contains the development header files and libraries necessary From fd9831410dfc878420fcd95dc576b955e94d2c76 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Thu, 5 Nov 2015 16:33:47 +0530 Subject: [PATCH 29/66] BUG#21950975 - MYSQL RPM INSTALLER(NEW STYLE) FAILS TO CREATE 'MYSQL' USER FOR EL5 - Remove -N option in useradd for EL5 platforms --- packaging/rpm-oel/mysql.spec.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index 3136e47230b..a76eaa114f8 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -622,7 +622,7 @@ rm -r $(readlink var) var %pre server /usr/sbin/groupadd -g 27 -o -r mysql >/dev/null 2>&1 || : -/usr/sbin/useradd -M -N -g mysql -o -r -d /var/lib/mysql -s /bin/bash \ +/usr/sbin/useradd -M %{!?el5:-N} -g mysql -o -r -d /var/lib/mysql -s /bin/bash \ -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || : %post server From 0dbd5a8797ed4bd18e8b883988fb62177eb0f73f Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Fri, 6 Nov 2015 16:41:55 +0530 Subject: [PATCH 30/66] Bug#21973610: BUFFER OVERFLOW ISSUES Description : Incorrect usage of sprintf/strcpy caused possible buffer overflow issues at various places. Solution : - Fixed mysql_plugin and mysqlshow - Fixed regex library issues Reviewed-By : Georgi Kodinov Reviewed-By : Venkata S Murthy Sidagam --- client/mysql_plugin.c | 10 ++++++++-- client/mysqlshow.c | 35 +++++++++++++++++++++-------------- libmysql/conf_to_src.c | 4 ++-- regex/main.c | 17 +++++++++++------ 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index cf212b16f24..293bd6727cf 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2015, 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 @@ -406,7 +406,7 @@ exit: static void usage(void) { PRINT_VERSION; - puts("Copyright (c) 2011, Oracle and/or its affiliates. " + puts("Copyright (c) 2011, 2015, Oracle and/or its affiliates. " "All rights reserved.\n"); puts("Enable or disable plugins."); printf("\nUsage: %s [options] ENABLE|DISABLE\n\nOptions:\n", @@ -757,6 +757,11 @@ static int check_options(int argc, char **argv, char *operation) /* read the plugin config file and check for match against argument */ else { + if (strlen(argv[i]) + 4 + 1 > FN_REFLEN) + { + fprintf(stderr, "ERROR: argument is too long.\n"); + return 1; + } strcpy(plugin_name, argv[i]); strcpy(config_file, argv[i]); strcat(config_file, ".ini"); @@ -848,6 +853,7 @@ static int process_options(int argc, char *argv[], char *operation) if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2) { char buff[FN_REFLEN]; + memset(buff, 0, sizeof(buff)); strncpy(buff, opt_basedir, sizeof(buff) - 1); #ifdef __WIN__ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index a6705548bcb..6cbbc5e2463 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -377,7 +377,7 @@ list_dbs(MYSQL *mysql,const char *wild) uint length, counter = 0; ulong rowcount = 0L; char tables[NAME_LEN+1], rows[NAME_LEN+1]; - char query[255]; + char query[NAME_LEN + 100]; MYSQL_FIELD *field; MYSQL_RES *result; MYSQL_ROW row= NULL, rrow; @@ -444,7 +444,8 @@ list_dbs(MYSQL *mysql,const char *wild) MYSQL_ROW trow; while ((trow = mysql_fetch_row(tresult))) { - sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]); + my_snprintf(query, sizeof(query), + "SELECT COUNT(*) FROM `%s`", trow[0]); if (!(mysql_query(mysql,query))) { MYSQL_RES *rresult; @@ -500,7 +501,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table) { const char *header; uint head_length, counter = 0; - char query[255], rows[NAME_LEN], fields[16]; + char query[NAME_LEN + 100], rows[NAME_LEN], fields[16]; MYSQL_FIELD *field; MYSQL_RES *result; MYSQL_ROW row, rrow; @@ -585,7 +586,8 @@ list_tables(MYSQL *mysql,const char *db,const char *table) if (opt_verbose > 1) { /* Print the count of rows for each table */ - sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]); + my_snprintf(query, sizeof(query), "SELECT COUNT(*) FROM `%s`", + row[0]); if (!(mysql_query(mysql,query))) { if ((rresult = mysql_store_result(mysql))) @@ -645,13 +647,15 @@ list_tables(MYSQL *mysql,const char *db,const char *table) static int list_table_status(MYSQL *mysql,const char *db,const char *wild) { - char query[1024],*end; + char query[NAME_LEN + 100]; + int len; MYSQL_RES *result; MYSQL_ROW row; - end=strxmov(query,"show table status from `",db,"`",NullS); - if (wild && wild[0]) - strxmov(end," like '",wild,"'",NullS); + len= sizeof(query); + len-= my_snprintf(query, len, "show table status from `%s`", db); + if (wild && wild[0] && len) + strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n", @@ -683,7 +687,8 @@ static int list_fields(MYSQL *mysql,const char *db,const char *table, const char *wild) { - char query[1024],*end; + char query[NAME_LEN + 100]; + int len; MYSQL_RES *result; MYSQL_ROW row; ulong UNINIT_VAR(rows); @@ -697,7 +702,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, if (opt_count) { - sprintf(query,"select count(*) from `%s`", table); + my_snprintf(query, sizeof(query), "select count(*) from `%s`", table); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot get record count for db: %s, table: %s: %s\n", @@ -709,9 +714,11 @@ list_fields(MYSQL *mysql,const char *db,const char *table, mysql_free_result(result); } - end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`"); - if (wild && wild[0]) - strxmov(end," like '",wild,"'",NullS); + len= sizeof(query); + len-= my_snprintf(query, len, "show /*!32332 FULL */ columns from `%s`", + table); + if (wild && wild[0] && len) + strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n", @@ -732,7 +739,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, print_res_top(result); if (opt_show_keys) { - end=strmov(strmov(strmov(query,"show keys from `"),table),"`"); + my_snprintf(query, sizeof(query), "show keys from `%s`", table); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot list keys in db: %s, table: %s: %s\n", diff --git a/libmysql/conf_to_src.c b/libmysql/conf_to_src.c index a5a7d23db0b..0e92388c93c 100644 --- a/libmysql/conf_to_src.c +++ b/libmysql/conf_to_src.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, 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 @@ -118,7 +118,7 @@ print_arrays_for(char *set) { FILE *f; - sprintf(buf, "%s.conf", set); + snprintf(buf, sizeof(buf), "%s.conf", set); if ((f = fopen(buf, "r")) == NULL) { fprintf(stderr, "%s: can't read conf file for charset %s\n", prog, set); diff --git a/regex/main.c b/regex/main.c index f5b591907cf..d35d5a93734 100644 --- a/regex/main.c +++ b/regex/main.c @@ -425,7 +425,8 @@ char *should; (sub.rm_so != -1 && sub.rm_eo == -1) || (sub.rm_so != -1 && sub.rm_so < 0) || (sub.rm_eo != -1 && sub.rm_eo < 0) ) { - sprintf(grump, "start %ld end %ld", (long)sub.rm_so, + snprintf(grump, sizeof(grump), + "start %ld end %ld", (long)sub.rm_so, (long)sub.rm_eo); return(grump); } @@ -438,7 +439,8 @@ char *should; /* check for in range */ if ((int) sub.rm_eo > (int) strlen(str)) { - sprintf(grump, "start %ld end %ld, past end of string", + snprintf(grump, sizeof(grump), + "start %ld end %ld, past end of string", (long)sub.rm_so, (long)sub.rm_eo); return(grump); } @@ -449,13 +451,15 @@ char *should; /* check for not supposed to match */ if (should == NULL) { - sprintf(grump, "matched `%.*s'", len, p); + snprintf(grump, sizeof(grump), + "matched `%.*s'", len, p); return(grump); } /* check for wrong match */ if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { - sprintf(grump, "matched `%.*s' instead", len, p); + snprintf(grump, sizeof(grump), + "matched `%.*s' instead", len, p); return(grump); } if (shlen > 0) @@ -468,7 +472,8 @@ char *should; if (shlen == 0) shlen = 1; /* force check for end-of-string */ if (strncmp(p, at, shlen) != 0) { - sprintf(grump, "matched null at `%.20s'", p); + snprintf(grump, sizeof(grump), + "matched null at `%.20s'", p); return(grump); } return(NULL); @@ -501,7 +506,7 @@ char *name; static char efbuf[100]; my_regex_t re; - sprintf(efbuf, "REG_%s", name); + snprintf(efbuf, sizeof(efbuf), "REG_%s", name); assert(strlen(efbuf) < sizeof(efbuf)); re.re_endp = efbuf; (void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); From c88ca2c22739dc2327c7b1082df79a93370662ba Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 6 Nov 2015 17:56:56 +0100 Subject: [PATCH 31/66] MDEV-8701 Crash on derived query MDEV-8938 Server Crash on Update with joins Make unique table check after setup_fields of update because unique table can materialize table and we do not need field resolving after materialization. --- mysql-test/r/update.result | 59 ++++++++++++++++++++++++++++++ mysql-test/t/update.test | 73 ++++++++++++++++++++++++++++++++++++++ sql/sql_prepare.cc | 3 +- sql/sql_update.cc | 32 ++++++++++++----- sql/sql_update.h | 1 + 5 files changed, 158 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 3ea58553653..0b036ca0a2e 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -618,3 +618,62 @@ Variable_name Value Handler_update 5 ROLLBACK; DROP TABLE t1, t2; +# +# MDEV-8938: Server Crash on Update with joins +# +CREATE TABLE `t1` ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +UPDATE `t1` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `t1` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain"; +drop table t1; +CREATE TABLE `t1` ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +create table t2 ( +`name` varchar(255) NOT NULL, +`value` varchar(4095) DEFAULT NULL, +PRIMARY KEY (`name`) +); +UPDATE t1 +SET value = (SELECT value FROM t2 WHERE `name`= t1.name) +WHERE value is null ; +drop table t1,t2; +# +#MDEV-8701: Crash on derived query +# +CREATE TABLE t1 ( +data_exit_entry_id int(11) NOT NULL, +data_entry_id int(11) NOT NULL, +data_entry_exit_id int(11) NOT NULL, +data_exit_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +data_entry_id int(11) NOT NULL, +data_entry_cost double NOT NULL, +data_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; +create algorithm=temptable view v1 as SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost +FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id; +UPDATE t2 +SET data_entry_cost += ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) +FROM +v1 AS query +WHERE data_entry_exit_id = t2.data_entry_id +) +); +UPDATE t2 +SET data_entry_cost += ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) +FROM +( SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost +FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id) AS query +WHERE data_entry_exit_id = t2.data_entry_id +) +); +drop view v1; +drop table t1, t2; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index be97dd02dc7..e9d7ff243dd 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -559,3 +559,76 @@ SHOW STATUS LIKE 'HANDLER_UPDATE'; ROLLBACK; DROP TABLE t1, t2; +--echo # +--echo # MDEV-8938: Server Crash on Update with joins +--echo # + +CREATE TABLE `t1` ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +UPDATE `t1` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `t1` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain"; + +drop table t1; + +CREATE TABLE `t1` ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +create table t2 ( + `name` varchar(255) NOT NULL, + `value` varchar(4095) DEFAULT NULL, + PRIMARY KEY (`name`) +); + +UPDATE t1 +SET value = (SELECT value FROM t2 WHERE `name`= t1.name) +WHERE value is null ; + +drop table t1,t2; + +--echo # +--echo #MDEV-8701: Crash on derived query +--echo # + +CREATE TABLE t1 ( + data_exit_entry_id int(11) NOT NULL, + data_entry_id int(11) NOT NULL, + data_entry_exit_id int(11) NOT NULL, + data_exit_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; + +CREATE TABLE t2 ( + data_entry_id int(11) NOT NULL, + data_entry_cost double NOT NULL, + data_entry_quantity double NOT NULL +) DEFAULT CHARSET=utf8; + +create algorithm=temptable view v1 as SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost + FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id; + +UPDATE t2 +SET data_entry_cost + = ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) + FROM + v1 AS query + WHERE data_entry_exit_id = t2.data_entry_id + ) + ); + +UPDATE t2 +SET data_entry_cost + = ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost) + FROM + ( SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost + FROM t1 INNER JOIN t2 as dt ON dt.data_entry_id = t1.data_entry_id) AS query + WHERE data_entry_exit_id = t2.data_entry_id + ) + ); + +drop view v1; +drop table t1, t2; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4fcc007d104..c61c9101a36 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1408,7 +1408,8 @@ static int mysql_test_update(Prepared_statement *stmt, (SELECT_ACL & ~table_list->table->grant.privilege); table_list->register_want_access(SELECT_ACL); #endif - if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0)) + if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) || + check_unique_table(thd, table_list)) goto error; /* TODO: here we should send types of placeholders to the client. */ DBUG_RETURN(0); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 23e17b0a3bb..c8a7990c23e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -367,6 +367,9 @@ int mysql_update(THD *thd, DBUG_RETURN(1); /* purecov: inspected */ } + if (check_unique_table(thd, table_list)) + DBUG_RETURN(TRUE); + /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */ if (select_lex->optimize_unflattened_subqueries(false)) DBUG_RETURN(TRUE); @@ -1036,19 +1039,30 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); - /* Check that we are not using table that we are updating in a sub select */ - { - TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) - { - update_non_unique_table_error(table_list, "UPDATE", duplicate); - DBUG_RETURN(TRUE); - } - } select_lex->fix_prepare_information(thd, conds, &fake_conds); DBUG_RETURN(FALSE); } +/** + Check that we are not using table that we are updating in a sub select + + @param thd Thread handle + @param table_list List of table with first to check + + @retval TRUE Error + @retval FALSE OK +*/ +bool check_unique_table(THD *thd, TABLE_LIST *table_list) +{ + TABLE_LIST *duplicate; + DBUG_ENTER("check_unique_table"); + if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) + { + update_non_unique_table_error(table_list, "UPDATE", duplicate); + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} /*************************************************************************** Update multiple tables from join diff --git a/sql/sql_update.h b/sql/sql_update.h index 64029c5d634..4c6f89d8468 100644 --- a/sql/sql_update.h +++ b/sql/sql_update.h @@ -27,6 +27,7 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT; bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order); +bool check_unique_table(THD *thd, TABLE_LIST *table_list); int mysql_update(THD *thd,TABLE_LIST *tables,List &fields, List &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, From 40ae1b9b618fbbc3b494a896a9d074b74e414337 Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Sat, 7 Nov 2015 22:03:47 +0530 Subject: [PATCH 32/66] Bug#21973610: BUFFER OVERFLOW ISSUES post push fix : Fixing test failures --- mysql-test/r/mysql_plugin.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/mysql_plugin.result b/mysql-test/r/mysql_plugin.result index 636b039047e..0bcb47e4a10 100644 --- a/mysql-test/r/mysql_plugin.result +++ b/mysql-test/r/mysql_plugin.result @@ -102,7 +102,7 @@ ERROR: Missing --plugin_dir option. # Show the help. # mysql_plugin Ver V.V.VV Distrib XX.XX.XX -Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. Enable or disable plugins. From 5d754fce95fa378027d1b575d049ab6b78823bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 9 Nov 2015 09:23:32 +0200 Subject: [PATCH 33/66] MDEV-8854: New warning messages are unreadable Improved warning messages by quote marks. --- .../suite/innodb/r/innodb-fk-warnings.result | 24 ++-- mysql-test/suite/innodb/r/innodb-fk.result | 6 +- storage/innobase/dict/dict0dict.c | 122 +++++++++--------- storage/xtradb/dict/dict0dict.c | 122 +++++++++--------- 4 files changed, 136 insertions(+), 138 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index 542fc972880..b3360d038df 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -24,7 +24,7 @@ create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=i ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(a)) engine=innodb. +Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(a)) engine=innodb'. Error 1005 Can't create table 'test.t2' (errno: 150) drop table t1; create table t1(a int not null primary key, b int) engine=innodb; @@ -33,14 +33,14 @@ constraint a foreign key a (a) references t1(b)) engine=innodb; ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(b)) engine=innodb. +Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(b)) engine=innodb'. Error 1005 Can't create table 'test.t2' (errno: 150) create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb; alter table t2 add constraint b foreign key (b) references t2(b); ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key (b) references t2(b). +Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'. Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t2, t1; create table t1 (f1 integer primary key) engine=innodb; @@ -48,7 +48,7 @@ alter table t1 add constraint c1 foreign key (f1) references t11(f1); ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary close to foreign key (f1) references t11(f1). +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary near ' foreign key (f1) references t11(f1)'. Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t1; create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb; @@ -56,13 +56,13 @@ create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb; ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(a) references t1(a)) engine=innodb. +Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(a) references t1(a)) engine=innodb'. Error 1005 Can't create table 'test.t2' (errno: 150) alter table t1 add foreign key(b) references t1(a); ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a). +Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(b) references t1(a)'. Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t1; create table t1(a int not null primary key, b int, key(b)) engine=innodb; @@ -70,7 +70,8 @@ alter table t1 add foreign key(a,b) references t1(a); ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Foreign key constraint parse error in foreign key(a,b) references t1(a) close to ). Too few referenced columns, you have 1 when you should have 2. +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Parse error in 'foreign key(a,b) references t1(a)' near ')'. Referencing column count 1 does not match referenced column count 2. + Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t1; create table t1(a int not null primary key, b int, key(b)) engine=innodb; @@ -78,7 +79,8 @@ alter table t1 add foreign key(a) references t1(a,b); ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Foreign key constraint parse error in foreign key(a) references t1(a,b) close to ). Too few referenced columns, you have 2 when you should have 1. +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Parse error in 'foreign key(a) references t1(a,b)' near ')'. Referencing column count 2 does not match referenced column count 1. + Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t1; create table t1 (f1 integer not null primary key) engine=innodb; @@ -86,13 +88,13 @@ alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update se ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column f1 is defined as NOT NULL in foreign key (f1) references t1(f1) on update set null close to on update set null. +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column 'f1' is defined as NOT NULL in ' foreign key (f1) references t1(f1) on update set null' near ' on update set null'. Error 1005 Can't create table '#sql-temporary' (errno: 150) create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb; ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column a is defined as NOT NULL in foreign key(a) references t1(f1) on delete set null) engine=innodb close to on delete set null) engine=innodb. +Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column 'a' is defined as NOT NULL in 'foreign key(a) references t1(f1) on delete set null) engine=innodb' near ' on delete set null) engine=innodb'. Error 1005 Can't create table 'test.t2' (errno: 150) drop table t1; create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb; @@ -100,6 +102,6 @@ create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=inn ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column a does not mach referenced column f1 close to foreign key(a) references t1(f1)) engine=innodb +Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column 'a' does not mach referenced column 'f1' near 'foreign key(a) references t1(f1)) engine=innodb'. Error 1005 Can't create table 'test.t2' (errno: 150) drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result index 2b53bc21b31..6c3306f5c15 100644 --- a/mysql-test/suite/innodb/r/innodb-fk.result +++ b/mysql-test/suite/innodb/r/innodb-fk.result @@ -50,8 +50,8 @@ CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE ERROR HY000: Can't create table 'test.t2' (errno: 150) show warnings; Level Code Message -Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE -) ENGINE=InnoDB. +Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE +) ENGINE=InnoDB'. Error 1005 Can't create table 'test.t2' (errno: 150) CREATE TABLE t2 ( id int(11) NOT NULL AUTO_INCREMENT, @@ -64,7 +64,7 @@ ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE ERROR HY000: Can't create table '#sql-temporary' (errno: 150) show warnings; Level Code Message -Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE. +Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE'. Error 1005 Can't create table '#sql-temporary' (errno: 150) drop table t2; drop table t1; diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index ad900385325..17e9eb122df 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -3628,13 +3628,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -3643,13 +3643,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -3657,12 +3657,12 @@ dict_foreign_push_index_error( fprintf(ef, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s\n", + "column '%s' on index is defined as NOT NULL near '%s'.\n", operation, create_name, columns[err_col], latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s", + "column '%s' on index is defined as NOT NULL near '%s'.", operation, create_name, columns[err_col], latest_foreign); break; } @@ -3675,13 +3675,13 @@ dict_foreign_push_index_error( table, dict_col_get_no(field->col)); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s\n", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.\n", operation, create_name, columns[err_col], col_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.", operation, create_name, columns[err_col], col_name, latest_foreign); break; } @@ -3973,14 +3973,14 @@ loop: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4009,16 +4009,16 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4038,14 +4038,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4081,14 +4081,14 @@ col_loop1: if (!success || !my_isspace(cs, *ptr)) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4148,7 +4148,7 @@ col_loop1: ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.", + "near '%s'.", operation, create_name, buf, start_of_latest_foreign); dict_foreign_free(foreign); @@ -4157,7 +4157,7 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.\n", + "near '%s'.\n", operation, create_name, buf, start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -4172,14 +4172,14 @@ col_loop1: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4201,16 +4201,16 @@ col_loop2: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4228,14 +4228,12 @@ col_loop2: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns.\n", + " failed. Parse error in '%s' near '%s'. Referencing column count does not match referenced column count.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns, you have %d when you should have %d.", + " failed. Parse error in '%s' near '%s'. Referencing column count %d does not match referenced column count %d.\n", operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields); dict_foreign_free(foreign); @@ -4268,14 +4266,14 @@ scan_on_conditions: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4316,14 +4314,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4345,14 +4343,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4365,14 +4363,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4392,16 +4390,16 @@ scan_on_conditions: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.\n", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.\n", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); @@ -4427,14 +4425,14 @@ try_find_index: fprintf(ef, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.\n", + " in '%s' near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.", + " in '%s' near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index cd8e4159033..7351de5de2b 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -3762,13 +3762,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -3777,13 +3777,13 @@ dict_foreign_push_index_error( "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.\n", + " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table '%s' with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" - " as the first columns. Error close to %s.", + " as the first columns near '%s'.", operation, create_name, latest_foreign); break; } @@ -3791,12 +3791,12 @@ dict_foreign_push_index_error( fprintf(ef, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s\n", + "column '%s' on index is defined as NOT NULL near '%s'.\n", operation, create_name, columns[err_col], latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " - "field %s on index is defined as NOT NULL close to %s", + "column '%s' on index is defined as NOT NULL near '%s'.", operation, create_name, columns[err_col], latest_foreign); break; } @@ -3809,13 +3809,13 @@ dict_foreign_push_index_error( table, dict_col_get_no(field->col)); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s\n", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.\n", operation, create_name, columns[err_col], col_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Field type or character set for column %s " - "does not mach referenced column %s close to %s", + " failed. Field type or character set for column '%s' " + "does not mach referenced column '%s' near '%s'.", operation, create_name, columns[err_col], col_name, latest_foreign); break; } @@ -4107,14 +4107,14 @@ loop: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4143,16 +4143,16 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4172,14 +4172,14 @@ col_loop1: if (!success) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4215,14 +4215,14 @@ col_loop1: if (!success || !my_isspace(cs, *ptr)) { dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4282,7 +4282,7 @@ col_loop1: ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.", + "near '%s'.", operation, create_name, buf, start_of_latest_foreign); dict_foreign_free(foreign); @@ -4291,7 +4291,7 @@ col_loop1: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary " - "close to %s.\n", + "near '%s'.\n", operation, create_name, buf, start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -4306,14 +4306,14 @@ col_loop1: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4335,16 +4335,16 @@ col_loop2: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, orig); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, orig); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4362,14 +4362,12 @@ col_loop2: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns\n", + " failed. Parse error in '%s' near '%s'. Referencing column count does not match referenced column count.\n", operation, create_name, start_of_latest_foreign, orig); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s. Too few referenced columns, you have %d when you should have %d.", + " failed. Parse error in '%s' near '%s'. Referencing column count %d does not match referenced column count %d.\n", operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields); dict_foreign_free(foreign); @@ -4402,14 +4400,14 @@ scan_on_conditions: dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4450,14 +4448,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4479,14 +4477,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); @@ -4499,14 +4497,14 @@ scan_on_conditions: dict_foreign_free(foreign); dict_foreign_report_syntax_err( "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.\n", + " failed. Parse error in '%s'" + " near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. Foreign key constraint parse error in %s" - " close to %s.", + " failed. Parse error in '%s'" + " near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); return(DB_CANNOT_ADD_CONSTRAINT); } @@ -4526,16 +4524,16 @@ scan_on_conditions: dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.\n", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.\n", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" - " failed. You have defined a SET NULL condition but column %s is defined as NOT NULL" - " in %s close to %s.", + " failed. You have defined a SET NULL condition but column '%s' is defined as NOT NULL" + " in '%s' near '%s'.", operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); @@ -4561,14 +4559,14 @@ try_find_index: fprintf(ef, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.\n", + " in '%s' near '%s'.\n", operation, create_name, start_of_latest_foreign, start_of_latest_set); mutex_exit(&dict_foreign_err_mutex); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, "%s table %s with foreign key constraint" " failed. You have more than one on delete or on update clause" - " in %s close to %s.", + " in '%s' near '%s'.", operation, create_name, start_of_latest_foreign, start_of_latest_set); dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); From 7e4da9b370d032db9015adb47ad2ff585aeaea5d Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 6 Nov 2015 16:36:41 +0100 Subject: [PATCH 34/66] DEV-8632 Segmentation fault on INSERT View/derived fields should be taken into account when we build ref_pointer_array constructed. DBUG_ASSERTs added to avoid memory overrun. --- mysql-test/r/view.result | 33 +++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 35 +++++++++++++++++++++++++++++++++++ sql/item.cc | 3 +++ sql/sql_select.cc | 6 ++++++ sql/sql_view.cc | 5 +++++ sql/sql_yacc.yy | 9 +++++++++ 6 files changed, 91 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 57065d74274..b008e623b5d 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5479,6 +5479,39 @@ UPDATE t1, t2 SET a = 1 WHERE a IN ( SELECT 0 FROM v3 ); EXECUTE stmt; DROP TABLE t1, t2, t3; DROP VIEW v3; +# +# MDEV-8632: Segmentation fault on INSERT +# +CREATE TABLE `t1` ( +`id` int(10) unsigned NOT NULL, +`r` float NOT NULL, +PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +create view v1 as select id, if(r=r,1,2) as d from t1; +create view v2 as +select id, +d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p +from v1; +insert into t1 (id, r) +select id,p from +( +select id, +d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p +from ( +select id, if(r=r,1,2) as d +from t1 +) a +) b +on duplicate key update r=p; +insert into t1 (id, r) +select id,p from v2 +on duplicate key update r=p; +prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p"; +execute stmt; +execute stmt; +deallocate prepare stmt; +drop view v1,v2; +drop table `t1`; # ----------------------------------------------------------------- # -- End of 5.5 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index fe04cdfecec..815be87b04e 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5445,6 +5445,41 @@ EXECUTE stmt; DROP TABLE t1, t2, t3; DROP VIEW v3; +--echo # +--echo # MDEV-8632: Segmentation fault on INSERT +--echo # +CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL, + `r` float NOT NULL, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +create view v1 as select id, if(r=r,1,2) as d from t1; +create view v2 as + select id, + d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p + from v1; +insert into t1 (id, r) +select id,p from +( + select id, + d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p + from ( + select id, if(r=r,1,2) as d + from t1 + ) a +) b +on duplicate key update r=p; +insert into t1 (id, r) +select id,p from v2 +on duplicate key update r=p; + +prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop view v1,v2; +drop table `t1`; --echo # ----------------------------------------------------------------- --echo # -- End of 5.5 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/item.cc b/sql/item.cc index 878c9604ca2..840272c57a4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1891,6 +1891,8 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, */ Item_aggregate_ref *item_ref; uint el= fields.elements; + DBUG_ASSERT(fields.elements <= + thd->lex->current_select->ref_pointer_array_size); /* If this is an item_ref, get the original item This is a safety measure if this is called for things that is @@ -6719,6 +6721,7 @@ Item *Item_field::update_value_transformer(uchar *select_arg) { List *all_fields= &select->join->all_fields; Item **ref_pointer_array= select->ref_pointer_array; + DBUG_ASSERT(all_fields->elements <= select->ref_pointer_array_size); int el= all_fields->elements; Item_ref *ref; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e960a3d7c45..ef1b5b0014e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -427,6 +427,7 @@ fix_inner_refs(THD *thd, List &all_fields, SELECT_LEX *select, if (ref_pointer_array && !ref->found_in_select_list) { int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= select->ref_pointer_array_size); ref_pointer_array[el]= item; /* Add the field item to the select list of the current select. */ all_fields.push_front(item); @@ -832,6 +833,7 @@ JOIN::prepare(Item ***rref_pointer_array, { Item_field *field= new Item_field(thd, *(Item_field**)ord->item); int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= select_lex->ref_pointer_array_size); ref_pointer_array[el]= field; all_fields.push_front(field); ord->item= ref_pointer_array + el; @@ -20596,6 +20598,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, return TRUE; /* Wrong field. */ uint el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= + thd->lex->current_select->ref_pointer_array_size); all_fields.push_front(order_item); /* Add new field to field list. */ ref_pointer_array[el]= order_item; /* @@ -20855,6 +20859,8 @@ create_distinct_group(THD *thd, Item **ref_pointer_array, */ Item_field *new_item= new Item_field(thd, (Item_field*)item); int el= all_fields.elements; + DBUG_ASSERT(all_fields.elements <= + thd->lex->current_select->ref_pointer_array_size); orig_ref_pointer_array[el]= new_item; all_fields.push_front(new_item); ord->item= orig_ref_pointer_array + el; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 255f876e02a..e6c5ffddfcf 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1520,6 +1520,11 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, */ lex->sql_command= old_lex->sql_command; lex->duplicates= old_lex->duplicates; + + /* Fields in this view can be used in upper select in case of merge. */ + if (table->select_lex) + table->select_lex->select_n_where_fields+= + lex->select_lex.select_n_where_fields; } /* This method has a dependency on the proper lock type being set, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a49dea6380e..11d7efdbadf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -9872,6 +9872,15 @@ table_factor: sel->add_joined_table($$); lex->pop_context(); lex->nest_level--; + /* + Fields in derived table can be used in upper select in + case of merge. We do not add HAVING fields because we do + not merge such derived. We do not add union because + also do not merge them + */ + if (!sel->next_select()) + $2->select_n_where_fields+= + sel->select_n_where_fields; } /*else if (($3->select_lex && $3->select_lex->master_unit()->is_union() && From e669a5fd87b28158cbb4454b4bcce7fe4a4ef8b8 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 17 Nov 2015 18:33:08 +0100 Subject: [PATCH 35/66] MDEV-7588 Add thd_wait_begin/end to notify threadpool of binlog waits --- sql/log.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/log.cc b/sql/log.cc index 0940cb9b56c..a87ec7225d1 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -6296,11 +6296,13 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd, int ret= 0; DBUG_ENTER("wait_for_update_bin_log"); + thd_wait_begin(thd, THD_WAIT_BINLOG); if (!timeout) mysql_cond_wait(&update_cond, &LOCK_log); else ret= mysql_cond_timedwait(&update_cond, &LOCK_log, const_cast(timeout)); + thd_wait_end(thd); DBUG_RETURN(ret); } From 726162989bdffca6af4a83c018a7d8eafeb82e6f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 18 Nov 2015 10:58:51 +0100 Subject: [PATCH 36/66] feedback plugin debug make it possible to change feedback plugin wait intervals * only in debug builds * and force the feedback report to be ignored update the test to use this feature --- mysql-test/include/default_mysqld.cnf | 3 ++ .../plugins/r/feedback_plugin_install.result | 3 +- .../plugins/r/feedback_plugin_load.result | 3 +- .../plugins/r/feedback_plugin_send.result | 9 +++-- .../plugins/t/feedback_plugin_install.test | 4 ++- .../suite/plugins/t/feedback_plugin_load.test | 3 +- .../suite/plugins/t/feedback_plugin_send.test | 15 +++------ plugin/feedback/feedback.cc | 33 +++++++++++++++++++ plugin/feedback/feedback.h | 4 +++ plugin/feedback/sender_thread.cc | 6 ++-- 10 files changed, 61 insertions(+), 22 deletions(-) diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index 96848c39f11..40d699ce759 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -38,6 +38,9 @@ max_heap_table_size= 1M loose-aria-pagecache-buffer-size=8M loose-feedback-user-info= mysql-test +loose-feedback-debug-startup-interval=20 +loose-feedback-debug-first-interval=60 +loose-feedback-debug-interval=60 loose-innodb_data_file_path= ibdata1:10M:autoextend loose-innodb_buffer_pool_size= 8M diff --git a/mysql-test/suite/plugins/r/feedback_plugin_install.result b/mysql-test/suite/plugins/r/feedback_plugin_install.result index 37d26b48501..c52fdb8f85b 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_install.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_install.result @@ -3,7 +3,8 @@ select plugin_status from information_schema.plugins where plugin_name='feedback plugin_status ACTIVE select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid'; + and variable_name not like '%_uid' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK used 1 FEEDBACK version 1.1 diff --git a/mysql-test/suite/plugins/r/feedback_plugin_load.result b/mysql-test/suite/plugins/r/feedback_plugin_load.result index ea6eae98601..e2cf3247022 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_load.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_load.result @@ -6,7 +6,8 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher variable_value = @feedback_used + 1 1 select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK version 1.1 FEEDBACK_SEND_RETRY_WAIT 60 diff --git a/mysql-test/suite/plugins/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result index 90a37f7ffbc..56a4e37981c 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -6,14 +6,13 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher variable_value = @feedback_used + 1 1 select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; VARIABLE_NAME VARIABLE_VALUE FEEDBACK version 1.1 FEEDBACK_SEND_RETRY_WAIT 60 FEEDBACK_SEND_TIMEOUT 60 FEEDBACK_URL http://mariadb.org/feedback_plugin/post FEEDBACK_USER_INFO mysql-test -feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -feedback plugin: server replied 'ok' -feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -feedback plugin: server replied 'ok' +6: feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent +6: feedback plugin: server replied 'ok' diff --git a/mysql-test/suite/plugins/t/feedback_plugin_install.test b/mysql-test/suite/plugins/t/feedback_plugin_install.test index 81343c436c3..559dcebfc05 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_install.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_install.test @@ -10,6 +10,8 @@ select plugin_status from information_schema.plugins where plugin_name='feedback --replace_result https http --sorted_result select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid'; + and variable_name not like '%_uid' + and variable_name not like '%debug%'; + uninstall plugin feedback; diff --git a/mysql-test/suite/plugins/t/feedback_plugin_load.test b/mysql-test/suite/plugins/t/feedback_plugin_load.test index f7c62b96b49..f626f1b0125 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_load.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_load.test @@ -24,4 +24,5 @@ SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback wher --replace_result https http --sorted_result select * from information_schema.feedback where variable_name like 'feed%' - and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'; + and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used' + and variable_name not like '%debug%'; diff --git a/mysql-test/suite/plugins/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index 31542c33482..31ab213831e 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -25,20 +25,15 @@ sleep 310; --let $shutdown_timeout= 60 source include/restart_mysqld.inc; -replace_result https http; +replace_result https http 2 6; perl; $log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err'; open(LOG, '<', $log_error) or die "open(< $log_error): $!"; - # Get the first few rows (as there may be different number rows in the log) - $i= 0; - while ($_=) - { - if (/feedback plugin:.*/) - { - print "$&\n"; - break if ($i++ >= 3); - } + %logg=(); + while ($_=) { + $logg{$&}++ if /feedback plugin:.*/; } + print "$logg{$_}: $_\n" for sort keys %logg; close LOG; EOF diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index 9bf2fcb99bc..f87caa54cbc 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -22,6 +22,10 @@ extern ST_SCHEMA_TABLE schema_tables[]; namespace feedback { +#ifndef DBUG_OFF +ulong debug_startup_interval, debug_first_interval, debug_interval; +#endif + char server_uid_buf[SERVER_UID_SIZE+1]; ///< server uid will be written here /* backing store for system variables */ @@ -249,6 +253,18 @@ static int init(void *p) prepare_linux_info(); +#ifndef DBUG_OFF + if (startup_interval != debug_startup_interval || + first_interval != debug_first_interval || + interval != debug_interval) + { + startup_interval= debug_startup_interval; + first_interval= debug_first_interval; + interval= debug_interval; + user_info= "mysql-test"; + } +#endif + url_count= 0; if (*url) { @@ -347,12 +363,29 @@ static MYSQL_SYSVAR_ULONG(send_retry_wait, send_retry_wait, PLUGIN_VAR_RQCMDARG, "Wait this many seconds before retrying a failed send.", NULL, NULL, 60, 1, 60*60*24, 1); +#ifndef DBUG_OFF +static MYSQL_SYSVAR_ULONG(debug_startup_interval, debug_startup_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, startup_interval, 1, INT_MAX32, 1); +static MYSQL_SYSVAR_ULONG(debug_first_interval, debug_first_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, first_interval, 1, INT_MAX32, 1); +static MYSQL_SYSVAR_ULONG(debug_interval, debug_interval, + PLUGIN_VAR_RQCMDARG, "for debugging only", + NULL, NULL, interval, 1, INT_MAX32, 1); +#endif + static struct st_mysql_sys_var* settings[] = { MYSQL_SYSVAR(server_uid), MYSQL_SYSVAR(user_info), MYSQL_SYSVAR(url), MYSQL_SYSVAR(send_timeout), MYSQL_SYSVAR(send_retry_wait), +#ifndef DBUG_OFF + MYSQL_SYSVAR(debug_startup_interval), + MYSQL_SYSVAR(debug_first_interval), + MYSQL_SYSVAR(debug_interval), +#endif NULL }; diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h index c5acbb5ef72..63aa4f8db8a 100644 --- a/plugin/feedback/feedback.h +++ b/plugin/feedback/feedback.h @@ -58,6 +58,10 @@ class Url { extern Url **urls; extern uint url_count; +extern time_t startup_interval; +extern time_t first_interval; +extern time_t interval; + /* these are used to communicate with the background thread */ extern mysql_mutex_t sleep_mutex; extern mysql_cond_t sleep_condition; diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 4ab45998484..abc3d0a18e6 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -25,9 +25,9 @@ static my_thread_id thd_thread_id; ///< its thread_id static size_t needed_size= 20480; -static const time_t startup_interval= 60*5; ///< in seconds (5 minutes) -static const time_t first_interval= 60*60*24; ///< in seconds (one day) -static const time_t interval= 60*60*24*7; ///< in seconds (one week) +time_t startup_interval= 60*5; ///< in seconds (5 minutes) +time_t first_interval= 60*60*24; ///< in seconds (one day) +time_t interval= 60*60*24*7; ///< in seconds (one week) /** reads the rows from a table and puts them, concatenated, in a String From 43a5090980ac0ab9695587979b9068b6bf849d64 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 18 Nov 2015 11:20:59 +0100 Subject: [PATCH 37/66] MDEV-9051 mysqld got signal 11, after upgrade to 10.1.8 feedback plugin needs to set tables->select_lex properly --- mysql-test/suite/plugins/r/feedback_plugin_send.result | 1 + mysql-test/suite/plugins/t/feedback_plugin_send.test | 6 +++++- plugin/feedback/sender_thread.cc | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/plugins/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result index 56a4e37981c..10378673829 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -14,5 +14,6 @@ FEEDBACK_SEND_RETRY_WAIT 60 FEEDBACK_SEND_TIMEOUT 60 FEEDBACK_URL http://mariadb.org/feedback_plugin/post FEEDBACK_USER_INFO mysql-test +set global sql_mode=ONLY_FULL_GROUP_BY; 6: feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent 6: feedback plugin: server replied 'ok' diff --git a/mysql-test/suite/plugins/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index 31ab213831e..b28f9d4cb38 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -13,7 +13,11 @@ if (!$MTR_FEEDBACK_PLUGIN) { # Let's wait, and hope that mtr is started with --parallel and # is doing some work in other workers. # -sleep 310; + +sleep 100; +set global sql_mode=ONLY_FULL_GROUP_BY; +sleep 210; + # The test expects that the plugin will send a report at least 2 times, # now (5 min after loading) and on server shutdown which happens below. diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index abc3d0a18e6..f32bf36a634 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -124,6 +124,7 @@ static int prepare_for_fill(TABLE_LIST *tables) if (!tables->table) return 1; + tables->select_lex= thd->lex->current_select; tables->table->pos_in_table_list= tables; return 0; From 13ad179c96ee8c8c4043806b8575c851e3676f0d Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 20 Nov 2015 14:50:18 +0100 Subject: [PATCH 38/66] MDEV-8756 MariaDB 10.0.21 crashes during PREPARE Non-select-like queries has no correct JOIN structure connected to top-most SELECT_LEX (and should not). --- mysql-test/r/ps.result | 21 +++++++++++++++++++++ mysql-test/t/ps.test | 22 ++++++++++++++++++++++ sql/item.cc | 20 ++++++++++++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 1438595aa3b..04a19d3840f 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4052,3 +4052,24 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)' drop table t1; # End of 5.3 tests +# +# MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +# +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +id value +1 1 +2 1 +3 NULL +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; +# End of 10.0 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9775a8dc28e..2ed5bb11bac 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3633,3 +3633,25 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; drop table t1; --echo # End of 5.3 tests + +--echo # +--echo # MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +--echo # + +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; + +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; + + +--echo # End of 10.0 tests diff --git a/sql/item.cc b/sql/item.cc index 840272c57a4..6d2983f249d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4889,8 +4889,24 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) As this is an outer field it should be added to the list of non aggregated fields of the outer select. */ - marker= select->cur_pos_in_select_list; - select->join->non_agg_fields.push_back(this); + if (select->join) + { + marker= select->cur_pos_in_select_list; + select->join->non_agg_fields.push_back(this); + } + else + { + /* + join is absent if it is upper SELECT_LEX of non-select + command + */ + DBUG_ASSERT(select->master_unit()->outer_select() == NULL && + (thd->lex->sql_command != SQLCOM_SELECT && + thd->lex->sql_command != SQLCOM_UPDATE_MULTI && + thd->lex->sql_command != SQLCOM_DELETE_MULTI && + thd->lex->sql_command != SQLCOM_INSERT_SELECT && + thd->lex->sql_command != SQLCOM_REPLACE_SELECT)); + } } if (*from_field != view_ref_found) { From 33589b25efe3283b748e43a54c42db2ed176c3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 3 Dec 2015 13:18:10 +0200 Subject: [PATCH 39/66] MDEV-7762 InnoDB: Failing assertion: block->page.buf_fix_count > 0 in buf0buf.ic line 730 Analysis: debug only assertion I_S function (IS is XtraDB feature) is calling buf_block_get_frame on any page it reads, which debug-asserts that the page is buffer-fixed, which is not the case in I_S query. Fixed by holding the buffer page mutex while the fields are read directly. --- .../r/innodb_information_schema_tables.result | 2 + .../t/innodb_information_schema_tables.opt | 29 +++++++++ .../t/innodb_information_schema_tables.test | 64 +++++++++++++++++++ storage/xtradb/handler/i_s.cc | 15 +++-- 4 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_information_schema_tables.result create mode 100644 mysql-test/suite/innodb/t/innodb_information_schema_tables.opt create mode 100644 mysql-test/suite/innodb/t/innodb_information_schema_tables.test diff --git a/mysql-test/suite/innodb/r/innodb_information_schema_tables.result b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result new file mode 100644 index 00000000000..ea713ea6f6a --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result @@ -0,0 +1,2 @@ +CREATE TABLE t1 ENGINE=InnoDB AS SELECT * FROM mysql.help_topic; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt new file mode 100644 index 00000000000..9f30d81ef9c --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt @@ -0,0 +1,29 @@ +--loose-innodb_trx +--loose-innodb_locks +--loose-innodb_lock_waits +--loose-innodb_cmp +--loose-innodb_cmp_reset +--loose-innodb_cmp_per_index +--loose-innodb_cmp_per_index_reset +--loose-innodb_cmpmem +--loose-innodb_cmpmem_reset +--loose-innodb_buffer_page +--loose-innodb_buffer_page_lru +--loose-innodb_buffer_stats +--loose-innodb_sys_tables +--loose-innodb_sys_tablestats +--loose-innodb_sys_indexes +--loose-innodb_sys_columns +--loose-innodb_sys_fields +--loose-innodb_sys_foreign +--loose-innodb_sys_foreign_cols +--loose-innodb_changed_pages +--loose-innodb_rseg +--loose-innodb_undo_logs +--loose-innodb_sys_stats +--loose-innodb_table_stats +--loose-innodb_index_stats +--loose-innodb_admin_command +--loose-innodb_buffer_pool_pages +--loose-innodb_buffer_pool_pages_index +--loose-innodb_buffer_pool_pages_blob diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test new file mode 100644 index 00000000000..15b3bf4f561 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test @@ -0,0 +1,64 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +# +# MDEV-7762 InnoDB: Failing assertion: block->page.buf_fix_count > 0 in buf0buf.ic line 730 +# +# Make sure that all supported information_schema tables are readable +# (actual result sets are not important). +# +CREATE TABLE t1 ENGINE=InnoDB AS SELECT * FROM mysql.help_topic; + +--disable_query_log +--disable_result_log +BEGIN; +SELECT * FROM t1 FOR UPDATE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; +SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; +SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; +SELECT * FROM INFORMATION_SCHEMA.INNODB_CMP; +SELECT * FROM INFORMATION_SCHEMA.INNODB_CMP_RESET; +SELECT * FROM INFORMATION_SCHEMA.INNODB_CMPMEM; +SELECT * FROM INFORMATION_SCHEMA.INNODB_CMPMEM_RESET; +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_STATS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_RSEG; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_UNDO_LOGS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_STATS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_INDEX_STATS; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_ADMIN_COMMAND; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES_INDEX; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES_BLOB; +--error 0,1109 +SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES; +COMMIT; +--enable_query_log +--enable_result_log +DROP TABLE t1; diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index bba0dade830..c868fbbedea 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -6664,9 +6664,10 @@ i_s_innodb_buffer_pool_pages_blob_fill( buf_pool = buf_pool_from_array(i); buf_pool_mutex_enter(buf_pool); - + for (n_block = 0; n_block < buf_pool->curr_size; n_block++) { buf_block_t* block = buf_page_from_array(buf_pool, n_block); + mutex_t* block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); page_zip_des_t* block_page_zip = buf_block_get_page_zip(block); const buf_frame_t* frame = block->frame; @@ -6676,16 +6677,16 @@ i_s_innodb_buffer_pool_pages_blob_fill( part_len = 0; /* hmm, can't figure it out */ next_page_no = mach_read_from_4( - buf_block_get_frame(block) - + FIL_PAGE_NEXT); + frame + + FIL_PAGE_NEXT); } else { part_len = mach_read_from_4( - buf_block_get_frame(block) + frame + FIL_PAGE_DATA + 0 /*BTR_BLOB_HDR_PART_LEN*/); next_page_no = mach_read_from_4( - buf_block_get_frame(block) + frame + FIL_PAGE_DATA + 4 /*BTR_BLOB_HDR_NEXT_PAGE_NO*/); } @@ -6712,7 +6713,9 @@ i_s_innodb_buffer_pool_pages_blob_fill( } } - } + + mutex_exit(block_mutex); + } buf_pool_mutex_exit(buf_pool); } From 9f07c6b383d776d430510de1256b3e4e8680bc60 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Dec 2015 16:08:54 +0400 Subject: [PATCH 40/66] MDEV-9001 - [PATCH] Fix DB name quoting in mysqldump --routine mysqldump --routine fails to dump databases containing backslash ("\") character. This happened because escaped database name was being used as an identifier while changing current database. Such identifers are not supposed to be escaped, they must be properly quoted instead. --- client/mysqldump.c | 17 ++++++++--------- mysql-test/r/mysqldump.result | 26 ++++++++++++++++++++++++++ mysql-test/t/mysqldump.test | 10 ++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index b649e638bc3..cfd38e019ba 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1119,13 +1119,12 @@ static int fetch_db_collation(const char *db_name, char query[QUERY_LENGTH]; MYSQL_RES *db_cl_res; MYSQL_ROW db_cl_row; - char quoted_database_buf[NAME_LEN*2+3]; - char *qdatabase= quote_name(db_name, quoted_database_buf, 1); - my_snprintf(query, sizeof (query), "use %s", qdatabase); - - if (mysql_query_with_error_report(mysql, NULL, query)) - return 1; + if (mysql_select_db(mysql, db_name)) + { + DB_error(mysql, "when selecting the database"); + return 1; /* If --force */ + } if (mysql_query_with_error_report(mysql, &db_cl_res, "select @@collation_database")) @@ -2319,7 +2318,7 @@ static uint dump_routines_for_db(char *db) /* Get database collation. */ - if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name))) + if (fetch_db_collation(db, db_cl_name, sizeof (db_cl_name))) DBUG_RETURN(1); if (switch_character_set_results(mysql, "binary")) @@ -2388,7 +2387,7 @@ static uint dump_routines_for_db(char *db) if (mysql_num_fields(routine_res) >= 6) { - if (switch_db_collation(sql_file, db_name_buff, ";", + if (switch_db_collation(sql_file, db, ";", db_cl_name, row[5], &db_cl_altered)) { DBUG_RETURN(1); @@ -2435,7 +2434,7 @@ static uint dump_routines_for_db(char *db) if (db_cl_altered) { - if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name)) + if (restore_db_collation(sql_file, db, ";", db_cl_name)) DBUG_RETURN(1); } } diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 43601f4a7c6..b205b81880e 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -5312,3 +5312,29 @@ Usage: mysqldump [OPTIONS] database [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all-databases [OPTIONS] For more options, use mysqldump --help +# +# MDEV-9001 - [PATCH] Fix DB name quoting in mysqldump --routine +# +CREATE DATABASE `a\"'``b`; +USE `a\"'``b`; +CREATE PROCEDURE p1() BEGIN END; +ALTER DATABASE `a\"'``b` COLLATE utf8_general_ci; +ALTER DATABASE `a\"'``b` CHARACTER SET latin1 COLLATE latin1_swedish_ci ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +BEGIN END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +ALTER DATABASE `a\"'``b` CHARACTER SET utf8 COLLATE utf8_general_ci ; +DROP DATABASE `a\"'``b`; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index e0c0ce346ed..b0285747e4e 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2494,3 +2494,13 @@ DROP DATABASE db_20772273; --exec $MYSQL_DUMP --user=foo 2>&1 > $MYSQLTEST_VARDIR/tmp/bug6056.out --exec $MYSQL_DUMP --help > $MYSQLTEST_VARDIR/tmp/bug6056.out + +--echo # +--echo # MDEV-9001 - [PATCH] Fix DB name quoting in mysqldump --routine +--echo # +CREATE DATABASE `a\"'``b`; +USE `a\"'``b`; +CREATE PROCEDURE p1() BEGIN END; +ALTER DATABASE `a\"'``b` COLLATE utf8_general_ci; +--exec $MYSQL_DUMP --routines --compact a\\\"\'\`b 2>&1 +DROP DATABASE `a\"'``b`; From d87bc55b05046d6484659286fa831ff10dbd3af9 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 3 Dec 2015 20:43:54 +0400 Subject: [PATCH 41/66] MDEV-8630 Datetime value dropped in "INSERT ... SELECT ... ON DUPLICATE KEY" Item_func_coalesce::fix_length_and_dec() calls Item_func::count_string_result_length()) which called agg_arg_charsets() with wrong flags, so the collation derivation of the COALESCE result was not properly set to DERIVATION_COERCIBLE. It erroneously stayed DERIVATION_NUMERIC. So GREATEST() misinterpreted the argument as a number rather that a string and did not calculate its own length properly. --- mysql-test/r/ctype_utf8.result | 27 +++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 16 ++++++++++++++++ sql/item_func.cc | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index a964384336a..91dbe853a38 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -5777,5 +5777,32 @@ SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2); ERROR 21000: Subquery returns more than 1 row DROP TABLE t1, t2; # +# MDEV-8630 Datetime value dropped in "INSERT ... SELECT ... ON DUPLICATE KEY" +# +SET NAMES utf8; +CREATE TABLE t1 (id2 int, ts timestamp); +INSERT INTO t1 VALUES (1,'2012-06-11 15:17:34'),(2,'2012-06-11 15:18:24'); +CREATE TABLE t2 AS SELECT +COALESCE(ts, 0) AS c0, +GREATEST(COALESCE(ts, 0), COALESCE(ts, 0)) AS c1, +GREATEST(CASE WHEN 1 THEN ts ELSE 0 END, CASE WHEN 1 THEN ts ELSE 0 END) AS c2, +GREATEST(IFNULL(ts,0), IFNULL(ts,0)) AS c3, +GREATEST(IF(1,ts,0), IF(1,ts,0)) AS c4 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c0` varchar(19) CHARACTER SET utf8 NOT NULL DEFAULT '', + `c1` varchar(19) CHARACTER SET utf8 NOT NULL DEFAULT '', + `c2` varchar(19) CHARACTER SET utf8 NOT NULL DEFAULT '', + `c3` varchar(19) CHARACTER SET utf8 NOT NULL DEFAULT '', + `c4` varchar(19) CHARACTER SET utf8 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT * FROM t2; +c0 c1 c2 c3 c4 +2012-06-11 15:17:34 2012-06-11 15:17:34 2012-06-11 15:17:34 2012-06-11 15:17:34 2012-06-11 15:17:34 +2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 +DROP TABLE t2, t1; +# # End of 5.5 tests # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index bed026ac8ce..8cd70e9261a 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1631,6 +1631,22 @@ INSERT INTO t2 VALUES ('aaa'); SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2); DROP TABLE t1, t2; +--echo # +--echo # MDEV-8630 Datetime value dropped in "INSERT ... SELECT ... ON DUPLICATE KEY" +--echo # +SET NAMES utf8; +CREATE TABLE t1 (id2 int, ts timestamp); +INSERT INTO t1 VALUES (1,'2012-06-11 15:17:34'),(2,'2012-06-11 15:18:24'); +CREATE TABLE t2 AS SELECT + COALESCE(ts, 0) AS c0, + GREATEST(COALESCE(ts, 0), COALESCE(ts, 0)) AS c1, + GREATEST(CASE WHEN 1 THEN ts ELSE 0 END, CASE WHEN 1 THEN ts ELSE 0 END) AS c2, + GREATEST(IFNULL(ts,0), IFNULL(ts,0)) AS c3, + GREATEST(IF(1,ts,0), IF(1,ts,0)) AS c4 +FROM t1; +SHOW CREATE TABLE t2; +SELECT * FROM t2; +DROP TABLE t2, t1; --echo # --echo # End of 5.5 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index eb5b63f549e..9a38fc60b0d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -719,7 +719,7 @@ void Item_func::count_real_length() bool Item_func::count_string_result_length(enum_field_types field_type, Item **items, uint nitems) { - if (agg_arg_charsets(collation, items, nitems, MY_COLL_ALLOW_CONV, 1)) + if (agg_arg_charsets_for_string_result(collation, items, nitems, 1)) return true; if (is_temporal_type(field_type)) count_datetime_length(items, nitems); From 082b859d0d8afbe49be770c2f18cf39bbd939aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 4 Dec 2015 14:24:03 +0200 Subject: [PATCH 42/66] MDEV-9233: Copying MySQL 5.5 data directory to 10.0 with partition tables crashes on insert Analysis: There were two problems. (1) if partition table was created using lower_case_tables = 1 on windows we did find the correct table but we did not set share->ib_table correctly. (2) we did open table on dictionary but did not increase mysql_open_tables. Fix: In xtradb allow access to tables with incorrect lower case names (warning is printed to error log). If table is opened increase mysql_open_tables count to avoid crash on flush tables. --- storage/innobase/handler/ha_innodb.cc | 8 +-- storage/xtradb/handler/ha_innodb.cc | 80 ++++++++++++++++----------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2bdbdf7a19f..17cf15e6b84 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4053,7 +4053,7 @@ ha_innobase::open( } ib_table = dict_table_get( - par_case_name, FALSE, ignore_err); + par_case_name, TRUE, ignore_err); } if (ib_table) { #ifndef __WIN__ @@ -5214,9 +5214,9 @@ ha_innobase::write_row( DBUG_ENTER("ha_innobase::write_row"); if (prebuilt->trx != trx) { - sql_print_error("The transaction object for the table handle is at " - "%p, but for the current thread it is at %p", - (const void*) prebuilt->trx, (const void*) trx); + sql_print_error("The transaction object for the table handle is at " + "%p, but for the current thread it is at %p", + (const void*) prebuilt->trx, (const void*) trx); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 37a029dd210..b56cd4d5013 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -4692,8 +4692,9 @@ ha_innobase::open( DBUG_RETURN(1); } - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1)) { free_share(share); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); @@ -4721,8 +4722,9 @@ ha_innobase::open( /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE, ignore_err); - if (UNIV_UNLIKELY(ib_table && ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(ib_table && + ib_table->is_corrupt && + srv_pass_corrupt_table <= 1)) { free_share(share); my_free(upd_buf); upd_buf = NULL; @@ -4775,8 +4777,9 @@ ha_innobase::open( } ib_table = dict_table_get( - par_case_name, FALSE, ignore_err); + par_case_name, TRUE, ignore_err); } + if (ib_table) { #ifndef __WIN__ sql_print_warning("Partition table %s opened " @@ -4798,6 +4801,10 @@ ha_innobase::open( "current file system\n", norm_name); #endif + /* We allow use of table if it is found. + this is consistent to current behavior + to innodb_plugin */ + share->ib_table = ib_table; goto table_opened; } } @@ -6174,9 +6181,9 @@ ha_innobase::write_row( DBUG_ENTER("ha_innobase::write_row"); if (prebuilt->trx != trx) { - sql_print_error("The transaction object for the table handle is at " - "%p, but for the current thread it is at %p", - (const void*) prebuilt->trx, (const void*) trx); + sql_print_error("The transaction object for the table handle is at " + "%p, but for the current thread it is at %p", + (const void*) prebuilt->trx, (const void*) trx); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); @@ -6190,7 +6197,7 @@ ha_innobase::write_row( ha_statistic_increment(&SSV::ha_write_count); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -6416,7 +6423,7 @@ report_error: func_exit: innobase_active_small(); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -6618,7 +6625,7 @@ ha_innobase::update_row( ha_statistic_increment(&SSV::ha_update_count); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -6711,7 +6718,7 @@ ha_innobase::update_row( innobase_active_small(); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -6736,7 +6743,7 @@ ha_innobase::delete_row( ha_statistic_increment(&SSV::ha_delete_count); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -6768,7 +6775,7 @@ ha_innobase::delete_row( innobase_active_small(); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -7017,8 +7024,10 @@ ha_innobase::index_read( ha_statistic_increment(&SSV::ha_read_key_count); - if (UNIV_UNLIKELY(share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(!share->ib_table || + (share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1))) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -7089,8 +7098,10 @@ ha_innobase::index_read( ret = DB_UNSUPPORTED; } - if (UNIV_UNLIKELY(share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(!share->ib_table || + (share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1))) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -7208,8 +7219,10 @@ ha_innobase::change_active_index( { DBUG_ENTER("change_active_index"); - if (UNIV_UNLIKELY(share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(!share->ib_table || + (share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1))) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -7332,8 +7345,10 @@ ha_innobase::general_fetch( DBUG_RETURN(HA_ERR_END_OF_FILE); } - if (UNIV_UNLIKELY(share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(!share->ib_table || + (share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1))) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -7346,8 +7361,10 @@ ha_innobase::general_fetch( innodb_srv_conc_exit_innodb(prebuilt->trx); - if (UNIV_UNLIKELY(share->ib_table->is_corrupt && - srv_pass_corrupt_table <= 1)) { + if (UNIV_UNLIKELY(!share->ib_table || + (share->ib_table && + share->ib_table->is_corrupt && + srv_pass_corrupt_table <= 1))) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -8628,7 +8645,7 @@ ha_innobase::truncate(void) update_thd(ha_thd()); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -8640,7 +8657,7 @@ ha_innobase::truncate(void) error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } @@ -9365,7 +9382,8 @@ ha_innobase::info_low( ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { - if ((called_from_analyze || innobase_stats_on_metadata) && !share->ib_table->is_corrupt) { + if ((called_from_analyze || innobase_stats_on_metadata) && + share->ib_table && !share->ib_table->is_corrupt) { /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -9719,7 +9737,7 @@ ha_innobase::analyze( THD* thd, /*!< in: connection thread handle */ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */ { - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { return(HA_ADMIN_CORRUPT); } @@ -9727,7 +9745,7 @@ ha_innobase::analyze( info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, true /* called from analyze */); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { return(HA_ADMIN_CORRUPT); } @@ -9980,7 +9998,7 @@ ha_innobase::check( my_error(ER_QUERY_INTERRUPTED, MYF(0)); } - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { return(HA_ADMIN_CORRUPT); } @@ -10783,7 +10801,7 @@ ha_innobase::transactional_table_lock( update_thd(thd); - if (share->ib_table->is_corrupt) { + if (!share->ib_table || share->ib_table->is_corrupt) { DBUG_RETURN(HA_ERR_CRASHED); } From e528fe79b8479000e1e4ed20de1682bc385ad82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 5 Dec 2015 12:21:33 +0200 Subject: [PATCH 43/66] Fix gcc v5.compiler errors. --- storage/innobase/dict/dict0crea.c | 2 +- storage/innobase/log/log0recv.c | 2 +- storage/xtradb/dict/dict0crea.c | 2 +- storage/xtradb/log/log0recv.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index dcbca492b08..dcce3c1dca1 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -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(err == DB_SUCCESS ? node->index != NULL : node->index == NULL); if (err != DB_SUCCESS) { diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 46157687071..c4f23da85aa 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1763,7 +1763,7 @@ loop: goto loop; } - ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); + ut_ad(allow_ibuf == FALSE ? mutex_own(&log_sys->mutex) : !mutex_own(&log_sys->mutex)); if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index f7663b999b7..4419287ad8b 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1255,7 +1255,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(err == DB_SUCCESS ? node->index != NULL : node->index == NULL); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index cae36421c52..5ab5e4be29e 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -1840,7 +1840,7 @@ loop: goto loop; } - ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); + ut_ad(allow_ibuf == FALSE ? mutex_own(&log_sys->mutex) : !mutex_own(&log_sys->mutex)); if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; From d85168e40d12de12c119b98ea92c35f3c2fe1f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 7 Dec 2015 09:20:31 +0200 Subject: [PATCH 44/66] Correct length check in my_wc_mb_filename() --- mysql-test/r/ctype_filename.result | 3 +++ mysql-test/t/ctype_filename.test | 3 +++ strings/ctype-utf8.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_filename.result b/mysql-test/r/ctype_filename.result index acc32c7dedf..ac8df476137 100644 --- a/mysql-test/r/ctype_filename.result +++ b/mysql-test/r/ctype_filename.result @@ -11,3 +11,6 @@ create table com1 (a int); drop table com1; create table `clock$` (a int); drop table `clock$`; +select convert(convert(',' using filename) using binary); +convert(convert(',' using filename) using binary) +@002c diff --git a/mysql-test/t/ctype_filename.test b/mysql-test/t/ctype_filename.test index 436ccfc4f2e..4c501a8b826 100644 --- a/mysql-test/t/ctype_filename.test +++ b/mysql-test/t/ctype_filename.test @@ -19,3 +19,6 @@ drop table com1; create table `clock$` (a int); drop table `clock$`; + +select convert(convert(',' using filename) using binary); + diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index edcac2774f8..2dd7f5e6b92 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -4585,7 +4585,7 @@ my_wc_mb_filename(CHARSET_INFO *cs __attribute__((unused)), } /* Non letter */ - if (s + 5 > e) + if (s + 4 > e) return MY_CS_TOOSMALL5; *s++= hex[(wc >> 12) & 15]; From 0df22a539e046a9090a99f10260cf6d80f0c4e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 7 Dec 2015 09:34:41 +0200 Subject: [PATCH 45/66] MDEV-7050: MySQL#74603 - Assertion `comma_length > 0' failed in mysql_prepare_create_table Incorrect array lenght for comma buffer. --- mysql-test/r/create.result | 6 ++++++ mysql-test/t/create.test | 8 ++++++++ sql/sql_table.cc | 5 +++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 8dd3cc8f643..327b53ce6cd 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -2477,3 +2477,9 @@ t1 CREATE TABLE `t1` ( `c` char(32) AS (convert(cast(n as char), char)) PERSISTENT ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +set @@session.collation_server=filename; +create table t1(a enum('','')); +Warnings: +Note 1291 Column 'a' has duplicated value '' in ENUM +drop table t1; +set @@session.collation_server=default; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 6de2c50ab36..e066dc6277d 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -2053,3 +2053,11 @@ select * from t1; show create table t1; drop table t1; + +# +# MDEV-7050: MySQL#74603 - Assertion `comma_length > 0' failed in mysql_prepare_create_table +# +set @@session.collation_server=filename; +create table t1(a enum('','')); +drop table t1; +set @@session.collation_server=default; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6e589e2b8d4..a771f64e767 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2986,9 +2986,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->interval_list); List_iterator int_it(sql_field->interval_list); String conv, *tmp; - char comma_buf[4]; /* 4 bytes for utf32 */ + char comma_buf[5]; /* 5 bytes for 'filename' charset */ + DBUG_ASSERT(sizeof(comma_buf) >= cs->mbmaxlen); int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf, - (uchar*) comma_buf + + (uchar*) comma_buf + sizeof(comma_buf)); DBUG_ASSERT(comma_length > 0); for (uint i= 0; (tmp= int_it++); i++) From ee2fce5e88b3ea4a3193422105c83dc1582de29f Mon Sep 17 00:00:00 2001 From: Christian Loos Date: Tue, 20 Oct 2015 09:41:44 +0200 Subject: [PATCH 46/66] fix debian logrotate slow log filename debian/additions/my.cnf sets slow_query_log_file to /var/log/mysql/mariadb-slow.log. Update the filename to rotate the slow log file. --- debian/mariadb-server-5.5.mysql-server.logrotate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/mariadb-server-5.5.mysql-server.logrotate b/debian/mariadb-server-5.5.mysql-server.logrotate index 0f0de516b13..789ad353e43 100644 --- a/debian/mariadb-server-5.5.mysql-server.logrotate +++ b/debian/mariadb-server-5.5.mysql-server.logrotate @@ -2,7 +2,7 @@ # flush-logs'd only once. # Else the binary logs would automatically increase by n times every day. # - The error log is obsolete, messages go to syslog now. -/var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log { +/var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mariadb-slow.log { daily rotate 7 missingok From c8652eefe50fd1894f2e2360e8bd631a7b9c67f5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 11:22:25 +0100 Subject: [PATCH 47/66] one more test --- mysql-test/suite/innodb/r/innodb-autoinc.result | 12 ++++++++++++ mysql-test/suite/innodb/t/innodb-autoinc.test | 1 + 2 files changed, 13 insertions(+) diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index 6a232cf434e..d6f7a930340 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -641,6 +641,18 @@ PRIMARY KEY (m)) ENGINE = InnoDB; INSERT INTO t2 (n,o) VALUES (1 , 'true'), (1 , 'false'), (2 , 'true'), (2 , 'false'), (3 , 'true'), (3 , 'false'), (4 , 'true'), (4 , 'false'), (5 , 'true'), (5 , 'false'); +SELECT * FROM t2; +m n o +1 1 TRUE +2 1 FALSE +3 2 TRUE +4 2 FALSE +5 3 TRUE +6 3 FALSE +7 4 TRUE +8 4 FALSE +9 5 TRUE +10 5 FALSE SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index a8dda12cadd..5e5a2b49a7d 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -401,6 +401,7 @@ CREATE TABLE t2 ( INSERT INTO t2 (n,o) VALUES (1 , 'true'), (1 , 'false'), (2 , 'true'), (2 , 'false'), (3 , 'true'), (3 , 'false'), (4 , 'true'), (4 , 'false'), (5 , 'true'), (5 , 'false'); +SELECT * FROM t2; SHOW CREATE TABLE t2; INSERT INTO t1 (b,c) SELECT n,o FROM t2 ; SHOW CREATE TABLE t1; From ef47b62551b0f37770e5d174ea028150c5b71fd8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 11:29:00 +0100 Subject: [PATCH 48/66] MDEV-8827 Duplicate key with auto increment fix innodb auto-increment handling three bugs: 1. innobase_next_autoinc treated the case of current offset) { + if (current >= offset) { next = (current - offset) / step; } else { - next = (offset - current) / step; + next = 0; + block -= step; } ut_a(max_value > next); @@ -10445,15 +10446,12 @@ ha_innobase::get_auto_increment( current = *first_value; - /* If the increment step of the auto increment column - decreases then it is not affecting the immediate - next value in the series. */ - if (prebuilt->autoinc_increment > increment) { + if (prebuilt->autoinc_increment != increment) { current = autoinc - prebuilt->autoinc_increment; current = innobase_next_autoinc( - current, 1, increment, 1, col_max_value); + current, 1, increment, offset, col_max_value); dict_table_autoinc_initialize(prebuilt->table, current); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b56cd4d5013..19aec80dbbd 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1748,10 +1748,11 @@ innobase_next_autoinc( if (next_value == 0) { ulonglong next; - if (current > offset) { + if (current >= offset) { next = (current - offset) / step; } else { - next = (offset - current) / step; + next = 0; + block -= step; } ut_a(max_value > next); @@ -11604,15 +11605,12 @@ ha_innobase::get_auto_increment( current = *first_value; - /* If the increment step of the auto increment column - decreases then it is not affecting the immediate - next value in the series. */ - if (prebuilt->autoinc_increment > increment) { + if (prebuilt->autoinc_increment != increment) { current = autoinc - prebuilt->autoinc_increment; current = innobase_next_autoinc( - current, 1, increment, 1, col_max_value); + current, 1, increment, offset, col_max_value); dict_table_autoinc_initialize(prebuilt->table, current); From e05883bf305ff6f9b85288e11d1e9b7458bb924e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 15:25:15 +0100 Subject: [PATCH 49/66] MDEV-7341 mysqld_multi doesn't recognize include directive (not following includes) --- scripts/mysqld_multi.sh | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index cd1b6fc18b7..2f67ff424b9 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -486,6 +486,7 @@ sub get_mysqladmin_options # Return a list of option files which can be opened. Similar, but not # identical, to behavior of my_search_option_files() +# TODO implement and use my_print_defaults --list-groups instead sub list_defaults_files { my %opt; @@ -497,9 +498,7 @@ sub list_defaults_files return ($opt{file}) if exists $opt{file}; - my %seen; # Don't list the same file more than once - return grep { defined $_ and not $seen{$_}++ and -f $_ and -r $_ } - ('/etc/my.cnf', + return ('/etc/my.cnf', '/etc/mysql/my.cnf', '@sysconfdir@/my.cnf', ($ENV{MYSQL_HOME} ? "$ENV{MYSQL_HOME}/my.cnf" : undef), @@ -539,11 +538,12 @@ sub find_groups } } + my %seen; my @defaults_files = list_defaults_files(); - #warn "@{[sort keys %gids]} -> @defaults_files\n"; - foreach my $file (@defaults_files) + while (@defaults_files) { - next unless open CONF, "< $file"; + my $file = shift @defaults_files; + next unless defined $file and not $seen{$file}++ and open CONF, '<', $file; while () { @@ -556,6 +556,14 @@ sub find_groups push @groups, "$1$2"; } } + elsif (/^\s*!include\s+(\S.*?)\s*$/) + { + push @defaults_files, $1; + } + elsif (/^\s*!includedir\s+(\S.*?)\s*$/) + { + push @defaults_files, <$1/*.cnf>; + } } close CONF; From 354e567c2384f95126ffa1e36382c4e0c206521c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 01:40:51 +0100 Subject: [PATCH 50/66] federatedx small cleanup * reduce code duplication * change int->void for the function that doesn't return an error * use ha_thd() --- storage/federatedx/ha_federatedx.cc | 52 +++++++++++------------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 62199515ca9..05a11fe31a7 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1639,6 +1639,7 @@ error: } +static federatedx_txn zero_txn; static int free_server(federatedx_txn *txn, FEDERATEDX_SERVER *server) { bool destroy; @@ -1654,12 +1655,9 @@ static int free_server(federatedx_txn *txn, FEDERATEDX_SERVER *server) MEM_ROOT mem_root; if (!txn) - { - federatedx_txn tmp_txn; - tmp_txn.close(server); - } - else - txn->close(server); + txn= &zero_txn; + + txn->close(server); DBUG_ASSERT(server->io_count == 0); @@ -1678,7 +1676,7 @@ static int free_server(federatedx_txn *txn, FEDERATEDX_SERVER *server) free memory associated with it. */ -static int free_share(federatedx_txn *txn, FEDERATEDX_SHARE *share) +static void free_share(federatedx_txn *txn, FEDERATEDX_SHARE *share) { bool destroy; DBUG_ENTER("free_share"); @@ -1701,7 +1699,7 @@ static int free_share(federatedx_txn *txn, FEDERATEDX_SHARE *share) free_server(txn, server); } - DBUG_RETURN(0); + DBUG_VOID_RETURN; } @@ -1767,7 +1765,7 @@ int ha_federatedx::disconnect(handlerton *hton, MYSQL_THD thd) int ha_federatedx::open(const char *name, int mode, uint test_if_locked) { int error; - THD *thd= current_thd; + THD *thd= ha_thd(); DBUG_ENTER("ha_federatedx::open"); if (!(share= get_share(name, table))) @@ -1811,8 +1809,8 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked) int ha_federatedx::close(void) { - int retval= 0, error; - THD *thd= current_thd; + int retval= 0; + THD *thd= ha_thd(); DBUG_ENTER("ha_federatedx::close"); /* free the result set */ @@ -1822,24 +1820,13 @@ int ha_federatedx::close(void) /* Disconnect from mysql */ if (!thd || !(txn= get_txn(thd, true))) - { - federatedx_txn tmp_txn; + txn= &zero_txn; - tmp_txn.release(&io); + txn->release(&io); + DBUG_ASSERT(io == NULL); - DBUG_ASSERT(io == NULL); + free_share(txn, share); - if ((error= free_share(&tmp_txn, share))) - retval= error; - } - else - { - txn->release(&io); - DBUG_ASSERT(io == NULL); - - if ((error= free_share(txn, share))) - retval= error; - } DBUG_RETURN(retval); } @@ -1862,9 +1849,8 @@ int ha_federatedx::close(void) 0 otherwise */ -static inline uint field_in_record_is_null(TABLE *table, - Field *field, - char *record) +static inline uint field_in_record_is_null(TABLE *table, Field *field, + char *record) { int null_offset; DBUG_ENTER("ha_federatedx::field_in_record_is_null"); @@ -2203,7 +2189,7 @@ int ha_federatedx::end_bulk_insert() */ void ha_federatedx::update_auto_increment(void) { - THD *thd= current_thd; + THD *thd= ha_thd(); DBUG_ENTER("ha_federatedx::update_auto_increment"); ha_federatedx::info(HA_STATUS_AUTO); @@ -3058,7 +3044,7 @@ error: int ha_federatedx::info(uint flag) { uint error_code; - THD *thd= current_thd; + THD *thd= ha_thd(); federatedx_txn *tmp_txn; federatedx_io *tmp_io= 0, **iop= 0; DBUG_ENTER("ha_federatedx::info"); @@ -3189,7 +3175,7 @@ int ha_federatedx::reset(void) federatedx_io *tmp_io= 0, **iop; // external_lock may not have been called so txn may not be set - tmp_txn= get_txn(current_thd); + tmp_txn= get_txn(ha_thd()); if (!*(iop= &io) && (error= tmp_txn->acquire(share, TRUE, (iop= &tmp_io)))) { @@ -3364,7 +3350,7 @@ int ha_federatedx::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { int retval; - THD *thd= current_thd; + THD *thd= ha_thd(); FEDERATEDX_SHARE tmp_share; // Only a temporary share, to test the url federatedx_txn *tmp_txn; federatedx_io *tmp_io= NULL; From 18954ff25d27252f3ce9865e636c91e0783572af Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 01:48:07 +0100 Subject: [PATCH 51/66] MDEV-8313 Got an error writing communication packets Don't let network errors from mysql_close() leak into THD. * remove incorrect upstream fix ** table->in_use can be NULL, must use ha_thd() ** clear_error() may remove earlier errors, don't use it * fix the bug properly in federated and federatedx --- .../federated/error_on_close-8313.result | 27 +++++++++++++ .../suite/federated/error_on_close-8313.test | 38 +++++++++++++++++++ storage/federated/ha_federated.cc | 31 ++++++++++----- storage/federatedx/ha_federatedx.cc | 19 ++++++++++ 4 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/federated/error_on_close-8313.result create mode 100644 mysql-test/suite/federated/error_on_close-8313.test diff --git a/mysql-test/suite/federated/error_on_close-8313.result b/mysql-test/suite/federated/error_on_close-8313.result new file mode 100644 index 00000000000..93b0edb4e49 --- /dev/null +++ b/mysql-test/suite/federated/error_on_close-8313.result @@ -0,0 +1,27 @@ +CREATE DATABASE federated; +CREATE DATABASE federated; +connection slave; +create table t1 (foo int, bar int); +connection master; +create server 's1' foreign data wrapper 'mysql' options +(HOST 'localhost', +DATABASE 'test', +USER 'root', +PASSWORD '', +SOCKET 'SLAVE_MYSOCK'); +create table t1 (foo integer, bar integer) engine=federated +connection='s1'; +select * from t1; +foo bar +connection slave; +connection master; +drop table t1; +drop server s1; +connection slave; +drop table t1; +connection master; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +connection slave; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/error_on_close-8313.test b/mysql-test/suite/federated/error_on_close-8313.test new file mode 100644 index 00000000000..b0b12861a66 --- /dev/null +++ b/mysql-test/suite/federated/error_on_close-8313.test @@ -0,0 +1,38 @@ +# +# MDEV-8313 Got an error writing communication packets +# +source include/federated.inc; + +enable_connect_log; + +connection slave; +create table t1 (foo int, bar int); + +connection master; + +--replace_result $SLAVE_MYSOCK SLAVE_MYSOCK +eval create server 's1' foreign data wrapper 'mysql' options + (HOST 'localhost', + DATABASE 'test', + USER 'root', + PASSWORD '', + SOCKET '$SLAVE_MYSOCK'); + + +eval create table t1 (foo integer, bar integer) engine=federated + connection='s1'; + +select * from t1; + +connection slave; +source include/restart_mysqld.inc; + +connection master; +drop table t1; +drop server s1; + +connection slave; +drop table t1; + +source include/federated_cleanup.inc; + diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index c720213bb4f..adf4f0f4db2 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1662,6 +1662,20 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(0); } +class Net_error_handler : public Internal_error_handler +{ +public: + Net_error_handler() {} + +public: + bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, MYSQL_ERROR ** cond_hdl) + { + return sql_errno >= ER_ABORTING_CONNECTION && + sql_errno <= ER_NET_WRITE_INTERRUPTED; + } +}; /* Closes a table. We call the free_share() function to free any resources @@ -1683,18 +1697,15 @@ int ha_federated::close(void) delete_dynamic(&results); /* Disconnect from mysql */ + THD *thd= ha_thd(); + Net_error_handler err_handler; + if (thd) + thd->push_internal_handler(&err_handler); mysql_close(mysql); - mysql= NULL; + if (thd) + thd->pop_internal_handler(); - /* - mysql_close() might return an error if a remote server's gone - for some reason. If that happens while removing a table from - the table cache, the error will be propagated to a client even - if the original query was not issued against the FEDERATED table. - So, don't propagate errors from mysql_close(). - */ - if (table->in_use) - table->in_use->clear_error(); + mysql= NULL; DBUG_RETURN(free_share(share)); } diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 05a11fe31a7..c9b07a8f3c3 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1795,6 +1795,20 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(0); } +class Net_error_handler : public Internal_error_handler +{ +public: + Net_error_handler() {} + +public: + bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, MYSQL_ERROR ** cond_hdl) + { + return sql_errno >= ER_ABORTING_CONNECTION && + sql_errno <= ER_NET_WRITE_INTERRUPTED; + } +}; /* Closes a table. We call the free_share() function to free any resources @@ -1825,7 +1839,12 @@ int ha_federatedx::close(void) txn->release(&io); DBUG_ASSERT(io == NULL); + Net_error_handler err_handler; + if (thd) + thd->push_internal_handler(&err_handler); free_share(txn, share); + if (thd) + thd->pop_internal_handler(); DBUG_RETURN(retval); } From d1fe928c4f128cc5440c30511b3900d7c5da65d7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 12:01:12 +0100 Subject: [PATCH 52/66] MDEV-8607 Init script doesn't check all applicable configuration groups use --mysqld instead of naming all groups explicitly https://github.com/MariaDB/server/pull/92 --- support-files/mysql.server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index e23b8373ec4..63cef2ade96 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -210,7 +210,7 @@ else fi fi -parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server` +parse_server_arguments `$print_defaults $extra_args --mysqld mysql.server` # wait for the pid file to disappear wait_for_gone () { From f18599a129cb64a65187a6c12a9b2505f39f85f5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 20:22:33 +0100 Subject: [PATCH 53/66] tokudb compilation warnings 5.5 patch only --- storage/tokudb/hatoku_cmp.cc | 186 ----------------------------------- storage/tokudb/hatoku_cmp.h | 19 ---- storage/tokudb/hatoku_hton.h | 8 -- 3 files changed, 213 deletions(-) diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc index 45bd44eec3c..42c0db81c8d 100644 --- a/storage/tokudb/hatoku_cmp.cc +++ b/storage/tokudb/hatoku_cmp.cc @@ -3140,189 +3140,3 @@ static uint32_t pack_key_from_desc( return (uint32_t)(packed_key_pos - buf); // } -static bool fields_have_same_name(Field* a, Field* b) { - return strcmp(a->field_name, b->field_name) == 0; -} - -static bool fields_are_same_type(Field* a, Field* b) { - bool retval = true; - enum_field_types a_mysql_type = a->real_type(); - enum_field_types b_mysql_type = b->real_type(); - TOKU_TYPE a_toku_type = mysql_to_toku_type(a); - TOKU_TYPE b_toku_type = mysql_to_toku_type(b); - // make sure have same names - // make sure have same types - if (a_mysql_type != b_mysql_type) { - retval = false; - goto cleanup; - } - // Thanks to MariaDB 5.5, we can have two fields - // be the same MySQL type but not the same toku type, - // This is an issue introduced with MariaDB's fractional time - // implementation - if (a_toku_type != b_toku_type) { - retval = false; - goto cleanup; - } - // make sure that either both are nullable, or both not nullable - if ((a->null_bit && !b->null_bit) || (!a->null_bit && b->null_bit)) { - retval = false; - goto cleanup; - } - switch (a_mysql_type) { - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - // length, unsigned, auto increment - if (a->pack_length() != b->pack_length() || - (a->flags & UNSIGNED_FLAG) != (b->flags & UNSIGNED_FLAG) || - (a->flags & AUTO_INCREMENT_FLAG) != (b->flags & AUTO_INCREMENT_FLAG)) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_FLOAT: - // length, unsigned, auto increment - if (a->pack_length() != b->pack_length() || - (a->flags & UNSIGNED_FLAG) != (b->flags & UNSIGNED_FLAG) || - (a->flags & AUTO_INCREMENT_FLAG) != (b->flags & AUTO_INCREMENT_FLAG)) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_NEWDECIMAL: - // length, unsigned - if (a->pack_length() != b->pack_length() || - (a->flags & UNSIGNED_FLAG) != (b->flags & UNSIGNED_FLAG)) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_ENUM: { - Field_enum *a_enum = static_cast(a); - if (!a_enum->eq_def(b)) { - retval = false; - goto cleanup; - } - break; - } - case MYSQL_TYPE_SET: { - Field_set *a_set = static_cast(a); - if (!a_set->eq_def(b)) { - retval = false; - goto cleanup; - } - break; - } - case MYSQL_TYPE_BIT: - // length - if (a->pack_length() != b->pack_length()) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_TIMESTAMP: -#if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ - (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099) - case MYSQL_TYPE_DATETIME2: - case MYSQL_TYPE_TIMESTAMP2: - case MYSQL_TYPE_TIME2: -#endif - // length - if (a->pack_length() != b->pack_length()) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_LONG_BLOB: - // test the charset - if (a->charset()->number != b->charset()->number) { - retval = false; - goto cleanup; - } - if (a->row_pack_length() != b->row_pack_length()) { - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_STRING: - if (a->pack_length() != b->pack_length()) { - retval = false; - goto cleanup; - } - // if both are binary, we know have same pack lengths, - // so we can goto end - if (a->binary() && b->binary()) { - // nothing to do, we are good - } - else if (!a->binary() && !b->binary()) { - // test the charset - if (a->charset()->number != b->charset()->number) { - retval = false; - goto cleanup; - } - } - else { - // one is binary and the other is not, so not the same - retval = false; - goto cleanup; - } - break; - case MYSQL_TYPE_VARCHAR: - if (a->field_length != b->field_length) { - retval = false; - goto cleanup; - } - // if both are binary, we know have same pack lengths, - // so we can goto end - if (a->binary() && b->binary()) { - // nothing to do, we are good - } - else if (!a->binary() && !b->binary()) { - // test the charset - if (a->charset()->number != b->charset()->number) { - retval = false; - goto cleanup; - } - } - else { - // one is binary and the other is not, so not the same - retval = false; - goto cleanup; - } - break; - // - // I believe these are old types that are no longer - // in any 5.1 tables, so tokudb does not need - // to worry about them - // Putting in this assert in case I am wrong. - // Do not support geometry yet. - // - case MYSQL_TYPE_GEOMETRY: - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_NULL: - assert(false); - } - -cleanup: - return retval; -} - -static bool are_two_fields_same(Field* a, Field* b) { - return fields_have_same_name(a, b) && fields_are_same_type(a, b); -} - - diff --git a/storage/tokudb/hatoku_cmp.h b/storage/tokudb/hatoku_cmp.h index 6ecd0968db7..af77d4da7e0 100644 --- a/storage/tokudb/hatoku_cmp.h +++ b/storage/tokudb/hatoku_cmp.h @@ -208,10 +208,6 @@ static bool is_variable_field(KEY_AND_COL_INFO *kcinfo, uint field_num) { return kcinfo->field_types[field_num] == KEY_AND_COL_INFO::TOKUDB_VARIABLE_FIELD; } -static bool is_blob_field(KEY_AND_COL_INFO *kcinfo, uint field_num) { - return kcinfo->field_types[field_num] == KEY_AND_COL_INFO::TOKUDB_BLOB_FIELD; -} - static bool field_valid_for_tokudb_table(Field* field); static void get_var_field_info( @@ -472,20 +468,5 @@ static uint32_t pack_key_from_desc( const DBT* pk_val ); -static bool fields_have_same_name( - Field* a, - Field* b - ); - -static bool fields_are_same_type( - Field* a, - Field* b - ); - -static bool are_two_fields_same( - Field* a, - Field* b - ); - #endif diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h index 71d78e57d63..b74e997841d 100644 --- a/storage/tokudb/hatoku_hton.h +++ b/storage/tokudb/hatoku_hton.h @@ -193,10 +193,6 @@ static MYSQL_THDVAR_BOOL(disable_slow_alter, false ); -static bool get_disable_slow_alter(THD* thd) { - return (THDVAR(thd, disable_slow_alter) != 0); -} - static MYSQL_THDVAR_BOOL(disable_hot_alter, 0, "if on, hot alter table is disabled", @@ -205,10 +201,6 @@ static MYSQL_THDVAR_BOOL(disable_hot_alter, false ); -static bool get_disable_hot_alter(THD* thd) { - return THDVAR(thd, disable_hot_alter) != 0; -} - static MYSQL_THDVAR_BOOL(create_index_online, 0, "if on, create index done online", From 8fd24b418d1a0935ff37d164a6548c9f956bf600 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:25:27 +0100 Subject: [PATCH 54/66] MDEV-9226 SHOW COLUMNS returns wrong column order for tables with large ENUMs set keep_row_order=true for temporary tables that hold results of the SHOW command --- mysql-test/r/show_row_order-9226.result | 80 +++++++++++++++++++++++++ mysql-test/t/show_row_order-9226.test | 73 ++++++++++++++++++++++ sql/sql_show.cc | 5 +- 3 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/show_row_order-9226.result create mode 100644 mysql-test/t/show_row_order-9226.test diff --git a/mysql-test/r/show_row_order-9226.result b/mysql-test/r/show_row_order-9226.result new file mode 100644 index 00000000000..b8c8de647ef --- /dev/null +++ b/mysql-test/r/show_row_order-9226.result @@ -0,0 +1,80 @@ +create table test_table ( +column_number_1 enum('1','2') not null, +column_number_2 enum('1','2','3','4','5','6','7','8','9','10','11','12') not null, +column_number_3 varchar(10) not null, +column_number_4 varchar(10) not null, +column_number_5 enum( +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa02', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa03', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa04', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa05', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa06', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa07', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa08', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa09', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52' + ) not null, +column_number_6 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','96','97','98','99','100','101','102','103','104','105','106','107','108','109','110','111','112','113','114','115','116','117','118','119','120','121','122','123','124','125','126','127','128','129','130','131') not null, +column_number_7 enum('1','2','3','4','5','6','7') not null, +column_number_8 enum('8') not null, +column_number_9 enum('9') not null, +column_number_10 varchar(10) not null, +column_number_11 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49') not null +) default charset=utf8mb4; +show columns from test_table; +Field Type Null Key Default Extra +column_number_1 enum('1','2') NO NULL +column_number_2 enum('1','2','3','4','5','6','7','8','9','10','11','12') NO NULL +column_number_3 varchar(10) NO NULL +column_number_4 varchar(10) NO NULL +column_number_5 enum('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa02','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa03','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa04','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa05','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa06','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa07','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa08','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa09','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52') NO NULL +column_number_6 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','96','97','98','99','100','101','102','103','104','105','106','107','108','109','110','111','112','113','114','115','116','117','118','119','120','121','122','123','124','125','126','127','128','129','130','131') NO NULL +column_number_7 enum('1','2','3','4','5','6','7') NO NULL +column_number_8 enum('8') NO NULL +column_number_9 enum('9') NO NULL +column_number_10 varchar(10) NO NULL +column_number_11 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49') NO NULL +drop table test_table; diff --git a/mysql-test/t/show_row_order-9226.test b/mysql-test/t/show_row_order-9226.test new file mode 100644 index 00000000000..06df24061ec --- /dev/null +++ b/mysql-test/t/show_row_order-9226.test @@ -0,0 +1,73 @@ +# +# MDEV-9226 SHOW COLUMNS returns wrong column order for tables with large ENUMs +# +create table test_table ( + column_number_1 enum('1','2') not null, + column_number_2 enum('1','2','3','4','5','6','7','8','9','10','11','12') not null, + column_number_3 varchar(10) not null, + column_number_4 varchar(10) not null, + column_number_5 enum( +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa02', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa03', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa04', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa05', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa06', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa07', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa08', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa09', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51', +'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52' + ) not null, + column_number_6 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','96','97','98','99','100','101','102','103','104','105','106','107','108','109','110','111','112','113','114','115','116','117','118','119','120','121','122','123','124','125','126','127','128','129','130','131') not null, + column_number_7 enum('1','2','3','4','5','6','7') not null, + column_number_8 enum('8') not null, + column_number_9 enum('9') not null, + column_number_10 varchar(10) not null, + column_number_11 enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49') not null +) default charset=utf8mb4; +# SHOW command must list columns in the table order +# (SELECT isn't required to do it, though) +show columns from test_table; +drop table test_table; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 86fc11ca236..45bddc24820 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7371,11 +7371,12 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) tmp_table_param->field_count= field_count; tmp_table_param->schema_table= 1; SELECT_LEX *select_lex= thd->lex->current_select; + bool keep_row_order= sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND; if (!(table= create_tmp_table(thd, tmp_table_param, field_list, (ORDER*) 0, 0, 0, (select_lex->options | thd->variables.option_bits | - TMP_TABLE_ALL_COLUMNS), - HA_POS_ERROR, table_list->alias))) + TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, + table_list->alias, false, keep_row_order))) DBUG_RETURN(0); my_bitmap_map* bitmaps= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); From 99774f150186d1624efe41a6600c437e556f6299 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 11:51:57 +0100 Subject: [PATCH 55/66] feedback plugin compilation warnings --- plugin/feedback/feedback.cc | 2 +- plugin/feedback/feedback.h | 6 +++--- plugin/feedback/sender_thread.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index f87caa54cbc..a06c0e6c496 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -261,7 +261,7 @@ static int init(void *p) startup_interval= debug_startup_interval; first_interval= debug_first_interval; interval= debug_interval; - user_info= "mysql-test"; + user_info= const_cast("mysql-test"); } #endif diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h index 63aa4f8db8a..98939c29d34 100644 --- a/plugin/feedback/feedback.h +++ b/plugin/feedback/feedback.h @@ -58,9 +58,9 @@ class Url { extern Url **urls; extern uint url_count; -extern time_t startup_interval; -extern time_t first_interval; -extern time_t interval; +extern ulong startup_interval; +extern ulong first_interval; +extern ulong interval; /* these are used to communicate with the background thread */ extern mysql_mutex_t sleep_mutex; diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index f32bf36a634..e6be8e3b9c2 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -25,9 +25,9 @@ static my_thread_id thd_thread_id; ///< its thread_id static size_t needed_size= 20480; -time_t startup_interval= 60*5; ///< in seconds (5 minutes) -time_t first_interval= 60*60*24; ///< in seconds (one day) -time_t interval= 60*60*24*7; ///< in seconds (one week) +ulong startup_interval= 60*5; ///< in seconds (5 minutes) +ulong first_interval= 60*60*24; ///< in seconds (one day) +ulong interval= 60*60*24*7; ///< in seconds (one week) /** reads the rows from a table and puts them, concatenated, in a String From 859a7369c1977baf6e204f4ed8f54b774790a179 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 14:07:36 +0100 Subject: [PATCH 56/66] MDEV-9161 feedback_plugin_send in debug builds thd->cleanup_after_query() is needed to destroy all Items created for this query (and Item destructors free allocated Strings). --- plugin/feedback/sender_thread.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index e6be8e3b9c2..da7628ef895 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -254,6 +254,7 @@ ret: { if (tables.table) free_tmp_table(thd, tables.table); + thd->cleanup_after_query(); /* clean up, free the thd. reset all thread local status variables to minimize From 79d08e682ff70469abe7146f06b3b4103679e072 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 15:15:43 +0100 Subject: [PATCH 57/66] small cleanup: udf_init()/udf_free() calls --- sql/mysqld.cc | 14 ++------------ sql/sql_udf.cc | 4 +++- sql/sql_udf.h | 3 +++ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3ad7b84829d..6c72954e9c2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1813,12 +1813,7 @@ void clean_up(bool print_message) item_user_lock_free(); lex_free(); /* Free some memory */ item_create_cleanup(); - if (!opt_noacl) - { -#ifdef HAVE_DLOPEN - udf_free(); -#endif - } + udf_free(); table_def_start_shutdown(); plugin_shutdown(); ha_end(); @@ -5005,12 +5000,7 @@ int mysqld_main(int argc, char **argv) if (!opt_bootstrap) servers_init(0); - if (!opt_noacl) - { -#ifdef HAVE_DLOPEN - udf_init(); -#endif - } + udf_init(); init_status_vars(); if (opt_bootstrap) /* If running with bootstrap, do not start replication. */ diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index e5fac48a750..626e5569ccc 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -142,7 +142,7 @@ void udf_init() DBUG_ENTER("ufd_init"); char db[]= "mysql"; /* A subject to casednstr, can't be constant */ - if (initialized) + if (initialized || opt_noacl) DBUG_VOID_RETURN; #ifdef HAVE_PSI_INTERFACE @@ -267,6 +267,8 @@ void udf_free() { /* close all shared libraries */ DBUG_ENTER("udf_free"); + if (opt_noacl) + DBUG_VOID_RETURN; for (uint idx=0 ; idx < udf_hash.records ; idx++) { udf_func *udf=(udf_func*) my_hash_element(&udf_hash,idx); diff --git a/sql/sql_udf.h b/sql/sql_udf.h index cdb15b9e0f5..68c01964687 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -143,5 +143,8 @@ udf_func *find_udf(const char *name, uint len=0,bool mark_used=0); void free_udf(udf_func *udf); int mysql_create_function(THD *thd,udf_func *udf); int mysql_drop_function(THD *thd,const LEX_STRING *name); +#else +static inline void udf_init(void) { } +static inline void udf_free(void) { } #endif #endif /* SQL_UDF_INCLUDED */ From 544eeda30d740bf8eaa99e8a1f47fbbbc3ef2086 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:27:58 +0100 Subject: [PATCH 58/66] MDEV-8644 Using a UDF in a virtual column causes a crash when stopping the server first close all tables, then unload UDFs --- mysql-test/r/udf_notembedded.result | 6 ++++++ mysql-test/t/udf_notembedded.test | 14 ++++++++++++++ sql/mysqld.cc | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/udf_notembedded.result create mode 100644 mysql-test/t/udf_notembedded.test diff --git a/mysql-test/r/udf_notembedded.result b/mysql-test/r/udf_notembedded.result new file mode 100644 index 00000000000..3fdcdbbe9d3 --- /dev/null +++ b/mysql-test/r/udf_notembedded.result @@ -0,0 +1,6 @@ +create function sequence returns integer soname "UDF_EXAMPLE_LIB"; +create table t1 (n int key not null auto_increment, msg int as (sequence()) virtual); +select * from t1; +n msg +drop table t1; +drop function sequence; diff --git a/mysql-test/t/udf_notembedded.test b/mysql-test/t/udf_notembedded.test new file mode 100644 index 00000000000..bf54af7256c --- /dev/null +++ b/mysql-test/t/udf_notembedded.test @@ -0,0 +1,14 @@ +--source include/not_embedded.inc +--source include/have_udf.inc + +# +# MDEV-8644 Using a UDF in a virtual column causes a crash when stopping the server +# +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval create function sequence returns integer soname "$UDF_EXAMPLE_SO"; +create table t1 (n int key not null auto_increment, msg int as (sequence()) virtual); +select * from t1; +source include/restart_mysqld.inc; +drop table t1; +drop function sequence; + diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6c72954e9c2..6a14b5c2e7e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1813,9 +1813,9 @@ void clean_up(bool print_message) item_user_lock_free(); lex_free(); /* Free some memory */ item_create_cleanup(); - udf_free(); table_def_start_shutdown(); plugin_shutdown(); + udf_free(); ha_end(); if (tc_log) tc_log->close(); From f0d774d48416bb06063184380b684380ca005a41 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:06:54 +0100 Subject: [PATCH 59/66] MDEV-9212 ssl-validate-cert incorrect hostname check Reimplement ssl_verify_server_cert() using the logic from https://wiki.openssl.org/index.php/Hostname_validation The bug was discovered by Alex Gaynor. --- sql-common/client.c | 55 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 01f73974f61..1bb4a250c69 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1885,8 +1885,11 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c { SSL *ssl; X509 *server_cert; - char *cp1, *cp2; - char *buf; + X509_NAME *x509sn; + int cn_pos; + X509_NAME_ENTRY *cn_entry; + ASN1_STRING *cn_asn1; + const char *cn_str; DBUG_ENTER("ssl_verify_server_cert"); DBUG_PRINT("enter", ("server_hostname: %s", server_hostname)); @@ -1920,34 +1923,32 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c are what we expect. */ - buf= X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0); + x509sn= X509_get_subject_name(server_cert); + + if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0) + goto err; + + if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos))) + goto err; + + if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry))) + goto err; + + cn_str = (char *)ASN1_STRING_data(cn_asn1); + + /* Make sure there is no embedded \0 in the CN */ + if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str)) + goto err; + + if (strcmp(cn_str, server_hostname)) + goto err; + X509_free (server_cert); + DBUG_RETURN(0); - if (!buf) - { - *errptr= "Out of memory"; - DBUG_RETURN(1); - } - - DBUG_PRINT("info", ("hostname in cert: %s", buf)); - cp1= strstr(buf, "/CN="); - if (cp1) - { - cp1+= 4; /* Skip the "/CN=" that we found */ - /* Search for next / which might be the delimiter for email */ - cp2= strchr(cp1, '/'); - if (cp2) - *cp2= '\0'; - DBUG_PRINT("info", ("Server hostname in cert: %s", cp1)); - if (!strcmp(cp1, server_hostname)) - { - free(buf); - /* Success */ - DBUG_RETURN(0); - } - } +err: + X509_free(server_cert); *errptr= "SSL certificate validation failure"; - free(buf); DBUG_RETURN(1); } From c21b927145e2da7fe835bc84b2b2b57e9dc2c60a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 8 Dec 2015 10:13:13 +0100 Subject: [PATCH 60/66] mysql_upgrade cleanup --- client/mysql_upgrade.c | 45 ++++++++++++------------------- mysql-test/r/mysql_upgrade.result | 2 +- mysql-test/t/mysql_upgrade.test | 2 +- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index ee6845def68..916af8755a0 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -109,6 +109,7 @@ static struct my_option my_long_options[]= &opt_force, &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#define PASSWORD_OPT 12 {"password", 'p', "Password to use when connecting to server. If password is not given," " it's solicited on the tty.", &opt_password,&opt_password, @@ -146,6 +147,7 @@ static struct my_option my_long_options[]= "do not try to upgrade the data.", &opt_systables_only, &opt_systables_only, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#define USER_OPT (array_elements(my_long_options) - 6) {"user", 'u', "User for login if not current user.", &opt_user, &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Display more output about the process.", @@ -235,26 +237,15 @@ static void verbose(const char *fmt, ...) static void add_one_option(DYNAMIC_STRING* ds, const struct my_option *opt, - const char* argument) - + const char* arg) { - const char* eq= NullS; - const char* arg= NullS; - if (opt->arg_type != NO_ARG) + dynstr_append(ds, "--"); + dynstr_append(ds, opt->name); + if (arg) { - eq= "="; - switch (opt->var_type & GET_TYPE_MASK) { - case GET_STR: - arg= argument; - break; - case GET_BOOL: - arg= (*(my_bool *)opt->value) ? "1" : "0"; - break; - default: - die("internal error at %s: %d",__FILE__, __LINE__); - } + dynstr_append(ds, "="); + dynstr_append_os_quoted(ds, arg, NullS); } - dynstr_append_os_quoted(ds, "--", opt->name, eq, arg, NullS); dynstr_append(ds, " "); } @@ -288,7 +279,6 @@ get_one_option(int optid, const struct my_option *opt, case 'p': if (argument == disabled_my_option) argument= (char*) ""; /* Don't require password */ - tty_password= 1; add_option= FALSE; if (argument) { @@ -298,6 +288,8 @@ get_one_option(int optid, const struct my_option *opt, *argument++= 'x'; /* Destroy argument */ tty_password= 0; } + else + tty_password= 1; break; case 't': @@ -351,7 +343,7 @@ get_one_option(int optid, const struct my_option *opt, if (add_option) { /* - This is an option that is accpted by mysql_upgrade just so + This is an option that is accepted by mysql_upgrade just so it can be passed on to "mysql" and "mysqlcheck" Save it in the ds_args string */ @@ -415,11 +407,8 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...) while ((arg= va_arg(args, char *))) { - /* Options should be os quoted */ - if (strncmp(arg, "--", 2) == 0) - dynstr_append_os_quoted(&ds_cmdline, arg, NullS); - else - dynstr_append(&ds_cmdline, arg); + /* Options should already be os quoted */ + dynstr_append(&ds_cmdline, arg); dynstr_append(&ds_cmdline, " "); } @@ -1031,12 +1020,12 @@ int main(int argc, char **argv) { opt_password= get_tty_password(NullS); /* add password to defaults file */ - dynstr_append_os_quoted(&ds_args, "--password=", opt_password, NullS); - dynstr_append(&ds_args, " "); + add_one_option(&ds_args, &my_long_options[PASSWORD_OPT], opt_password); + DBUG_ASSERT(strcmp(my_long_options[PASSWORD_OPT].name, "password") == 0); } /* add user to defaults file */ - dynstr_append_os_quoted(&ds_args, "--user=", opt_user, NullS); - dynstr_append(&ds_args, " "); + add_one_option(&ds_args, &my_long_options[USER_OPT], opt_user); + DBUG_ASSERT(strcmp(my_long_options[USER_OPT].name, "user") == 0); /* Find mysql */ find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name); diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 8b8fea2909d..805ee82a3ac 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -36,7 +36,7 @@ Phase 4/4: Running 'mysql_fix_privilege_tables' OK Run it again - should say already completed This installation of MySQL is already upgraded to VERSION, use --force if you still need to run mysql_upgrade -Force should run it regardless of wether it's been run before +Force should run it regardless of whether it has been run before Phase 1/4: Fixing views Phase 2/4: Fixing table and database names Phase 3/4: Checking and upgrading tables diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 13be03aa9bb..0b9e1433c39 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -19,7 +19,7 @@ file_exists $MYSQLD_DATADIR/mysql_upgrade_info; # It should have created a file in the MySQL Servers datadir file_exists $MYSQLD_DATADIR/mysql_upgrade_info; ---echo Force should run it regardless of wether it's been run before +--echo Force should run it regardless of whether it has been run before --exec $MYSQL_UPGRADE --force 2>&1 # It should have created a file in the MySQL Servers datadir From 50a796dcba2abe5f25c1e4cd8a69d7ea43343a8d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 8 Dec 2015 10:16:41 +0100 Subject: [PATCH 61/66] MDEV-8825 mysql_upgrade leaks the admin password when it spawns a shell process to execute mysqlcheck don't put common arguments on the command-line, use a config file instead --- client/mysql_upgrade.c | 51 +++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 916af8755a0..d8ee8f0d911 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -53,6 +53,8 @@ static DYNAMIC_STRING conn_args; static char *opt_password= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; +static char *cnf_file_path= 0, defaults_file[FN_REFLEN + 32]; + static my_bool tty_password= 0; static char opt_tmpdir[FN_REFLEN] = ""; @@ -184,6 +186,8 @@ static void free_used_memory(void) dynstr_free(&ds_args); dynstr_free(&conn_args); + if (cnf_file_path) + my_delete(cnf_file_path, MYF(MY_WME)); } @@ -235,8 +239,8 @@ static void verbose(const char *fmt, ...) this way we pass the same arguments on to mysql and mysql_check */ -static void add_one_option(DYNAMIC_STRING* ds, - const struct my_option *opt, +static void add_one_option_cmd_line(DYNAMIC_STRING *ds, + const struct my_option *opt, const char* arg) { dynstr_append(ds, "--"); @@ -249,6 +253,18 @@ static void add_one_option(DYNAMIC_STRING* ds, dynstr_append(ds, " "); } +static void add_one_option_cnf_file(DYNAMIC_STRING *ds, + const struct my_option *opt, + const char* arg) +{ + dynstr_append(ds, opt->name); + if (arg) + { + dynstr_append(ds, "="); + dynstr_append_os_quoted(ds, arg, NullS); + } + dynstr_append(ds, "\n"); +} static my_bool get_one_option(int optid, const struct my_option *opt, @@ -283,7 +299,7 @@ get_one_option(int optid, const struct my_option *opt, if (argument) { /* Add password to ds_args before overwriting the arg with x's */ - add_one_option(&ds_args, opt, argument); + add_one_option_cnf_file(&ds_args, opt, argument); while (*argument) *argument++= 'x'; /* Destroy argument */ tty_password= 0; @@ -336,7 +352,7 @@ get_one_option(int optid, const struct my_option *opt, case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */ case OPT_PLUGIN_DIR: /* --plugin-dir */ case OPT_DEFAULT_AUTH: /* --default-auth */ - add_one_option(&conn_args, opt, argument); + add_one_option_cmd_line(&conn_args, opt, argument); break; } @@ -347,7 +363,7 @@ get_one_option(int optid, const struct my_option *opt, it can be passed on to "mysql" and "mysqlcheck" Save it in the ds_args string */ - add_one_option(&ds_args, opt, argument); + add_one_option_cnf_file(&ds_args, opt, argument); } return 0; } @@ -550,8 +566,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, ret= run_tool(mysql_path, ds_res, - "--no-defaults", - ds_args.str, + defaults_file, "--database=mysql", "--batch", /* Turns off pager etc. */ force ? "--force": "--skip-force", @@ -740,8 +755,7 @@ static int run_mysqlcheck_upgrade(void) print_conn_args("mysqlcheck"); retch= run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ - "--no-defaults", - ds_args.str, + defaults_file, "--check-upgrade", "--all-databases", "--auto-repair", @@ -794,8 +808,7 @@ static int run_mysqlcheck_views(void) print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ - "--no-defaults", - ds_args.str, + defaults_file, "--all-databases", "--repair", upgrade_views, "--skip-process-tables", @@ -819,8 +832,7 @@ static int run_mysqlcheck_fixnames(void) print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ - "--no-defaults", - ds_args.str, + defaults_file, "--all-databases", "--fix-db-names", "--fix-table-names", @@ -1020,13 +1032,22 @@ int main(int argc, char **argv) { opt_password= get_tty_password(NullS); /* add password to defaults file */ - add_one_option(&ds_args, &my_long_options[PASSWORD_OPT], opt_password); + add_one_option_cnf_file(&ds_args, &my_long_options[PASSWORD_OPT], opt_password); DBUG_ASSERT(strcmp(my_long_options[PASSWORD_OPT].name, "password") == 0); } /* add user to defaults file */ - add_one_option(&ds_args, &my_long_options[USER_OPT], opt_user); + add_one_option_cnf_file(&ds_args, &my_long_options[USER_OPT], opt_user); DBUG_ASSERT(strcmp(my_long_options[USER_OPT].name, "user") == 0); + cnf_file_path= strmov(defaults_file, "--defaults-file="); + { + int fd= create_temp_file(cnf_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL, + "mysql_upgrade-", O_CREAT | O_WRONLY, MYF(MY_FAE)); + my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE)); + my_write(fd, (uchar*)ds_args.str, ds_args.length, MYF(MY_FAE)); + my_close(fd, MYF(0)); + } + /* Find mysql */ find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name); From dac3149f3f3cd79c8b2066f1030782eefb62ad15 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 8 Dec 2015 17:20:34 +0400 Subject: [PATCH 62/66] MDEV-9001 - [PATCH] Fix DB name quoting in mysqldump --routine Removed unused variable. --- client/mysqldump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index cfd38e019ba..8e4046510df 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1116,7 +1116,6 @@ static int fetch_db_collation(const char *db_name, int db_cl_size) { my_bool err_status= FALSE; - char query[QUERY_LENGTH]; MYSQL_RES *db_cl_res; MYSQL_ROW db_cl_row; From 9457139e591aa7fb0459788acdbc260db53b0f22 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 12:27:04 +0100 Subject: [PATCH 63/66] 5.5.46-37.6 --- storage/xtradb/CMakeLists.txt | 17 +++- storage/xtradb/btr/btr0cur.c | 49 +++++++++-- storage/xtradb/dict/dict0crea.c | 2 +- storage/xtradb/handler/ha_innodb.cc | 88 ++++++++++++++++++- storage/xtradb/include/ha_prototypes.h | 10 +++ storage/xtradb/include/os0file.h | 11 ++- storage/xtradb/include/os0sync.h | 115 ++++++++++++++++++++++++- storage/xtradb/include/sync0sync.h | 9 +- storage/xtradb/include/sync0sync.ic | 9 +- storage/xtradb/include/univ.i | 2 +- storage/xtradb/lock/lock0lock.c | 10 +-- storage/xtradb/log/log0online.c | 16 +++- storage/xtradb/log/log0recv.c | 2 +- storage/xtradb/os/os0file.c | 17 ++-- storage/xtradb/row/row0ins.c | 5 +- storage/xtradb/trx/trx0trx.c | 6 ++ 16 files changed, 318 insertions(+), 50 deletions(-) diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index a8952614966..b97473849ef 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2015, 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 @@ -110,6 +110,18 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS_64 ) + CHECK_C_SOURCE_RUNS( + "#include + int main() + { + unsigned char c; + + __atomic_test_and_set(&c, __ATOMIC_ACQUIRE); + __atomic_clear(&c, __ATOMIC_RELEASE); + return(0); + }" + HAVE_IB_GCC_ATOMIC_TEST_AND_SET + ) ENDIF() IF(HAVE_IB_GCC_ATOMIC_BUILTINS) @@ -119,6 +131,9 @@ ENDIF() IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=1) ENDIF() +IF(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) + ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_TEST_AND_SET=1) +ENDIF() # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not IF(NOT CMAKE_CROSSCOMPILING) diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index ccecbfd64de..a2f5ad49559 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -287,8 +287,13 @@ btr_cur_latch_leaves( #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); - ut_a(btr_page_get_next(get_block->frame, mtr) - == page_get_page_no(page)); + + /* For fake_change mode we avoid a detailed validation + as it operate in tweaked format where-in validation + may fail. */ + ut_a(sibling_mode == RW_NO_LATCH + || btr_page_get_next(get_block->frame, mtr) + == page_get_page_no(page)); #endif /* UNIV_BTR_DEBUG */ if (sibling_mode == RW_NO_LATCH) { /* btr_block_get() called with RW_NO_LATCH will @@ -2139,6 +2144,7 @@ btr_cur_optimistic_update( ulint max_size; ulint new_rec_size; ulint old_rec_size; + ulint max_ins_size = 0; dtuple_t* new_entry; roll_ptr_t roll_ptr; trx_t* trx; @@ -2250,6 +2256,11 @@ any_extern: : (old_rec_size + page_get_max_insert_size_after_reorganize(page, 1)); + if (!page_zip) { + max_ins_size = page_get_max_insert_size_after_reorganize( + page, 1); + } + if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT) && (max_size >= new_rec_size)) || (page_get_n_recs(page) <= 1))) { @@ -2306,10 +2317,14 @@ any_extern: rec = btr_cur_insert_if_possible(cursor, new_entry, 0/*n_ext*/, mtr); ut_a(rec); /* <- We calculated above the insert would fit */ - if (page_zip && !dict_index_is_clust(index) + if (!dict_index_is_clust(index) && page_is_leaf(page)) { /* Update the free bits in the insert buffer. */ - ibuf_update_free_bits_zip(block, mtr); + if (page_zip) { + ibuf_update_free_bits_zip(block, mtr); + } else { + ibuf_update_free_bits_low(block, max_ins_size, mtr); + } } /* Restore the old explicit lock state on the record */ @@ -2418,6 +2433,7 @@ btr_cur_pessimistic_update( ulint n_reserved; ulint n_ext; ulint* offsets = NULL; + ulint max_ins_size = 0; *big_rec = NULL; @@ -2570,6 +2586,11 @@ make_external: /* skip CHANGE, LOG */ err = DB_SUCCESS; goto return_after_reservations; + } + + if (!page_zip) { + max_ins_size = page_get_max_insert_size_after_reorganize( + page, 1); } /* Store state of explicit locks on rec on the page infimum record, @@ -2617,10 +2638,15 @@ make_external: big_rec_vec != NULL && (flags & BTR_KEEP_POS_FLAG), mtr); - if (page_zip && !dict_index_is_clust(index) + if (!dict_index_is_clust(index) && page_is_leaf(page)) { /* Update the free bits in the insert buffer. */ - ibuf_update_free_bits_zip(block, mtr); + if (page_zip) { + ibuf_update_free_bits_zip(block, mtr); + } else { + ibuf_update_free_bits_low(block, max_ins_size, + mtr); + } } err = DB_SUCCESS; @@ -3882,7 +3908,14 @@ btr_estimate_number_of_different_key_vals( page = btr_cur_get_page(&cursor); - SRV_CORRUPT_TABLE_CHECK(page, goto exit_loop;); + DBUG_EXECUTE_IF("ib_corrupt_page_while_stats_calc", + page = NULL;); + + SRV_CORRUPT_TABLE_CHECK(page, + { + mtr_commit(&mtr); + goto exit_loop; + }); rec = page_rec_get_next(page_get_infimum_rec(page)); diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index 7f148aa1f75..44ebca83373 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1255,7 +1255,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 == 0) == (err != DB_SUCCESS)); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 69d8830d07d..7e97ae6ab8e 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1027,6 +1027,19 @@ thd_supports_xa( return(THDVAR((THD*) thd, support_xa)); } +/******************************************************************//** +Check the status of fake changes mode (innodb_fake_changes) +@return true if fake change mode is enabled. */ +extern "C" UNIV_INTERN +ibool +thd_fake_changes( +/*=============*/ + void* thd) /*!< in: thread handle, or NULL to query + the global innodb_supports_xa */ +{ + return(THDVAR((THD*) thd, fake_changes)); +} + /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ @@ -1795,7 +1808,15 @@ innobase_trx_init( trx->check_unique_secondary = !thd_test_options( thd, OPTION_RELAXED_UNIQUE_CHECKS); - trx->fake_changes = THDVAR(thd, fake_changes); + /* Transaction on start caches the fake_changes state and uses it for + complete transaction lifetime. + There are some APIs that doesn't need an active transaction object + but transaction object are just use as a cache object/data carrier. + Before using transaction object for such APIs refresh the state of + fake_changes. */ + if (trx->state == TRX_NOT_STARTED) { + trx->fake_changes = thd_fake_changes(thd); + } #ifdef EXTENDED_SLOWLOG if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) { @@ -3644,12 +3665,26 @@ innobase_commit( /* No-op in XtraDB */ trx_search_latch_release_if_reserved(trx); + /* If fake-changes mode = ON then allow + SELECT (they are read-only) and + CREATE ... SELECT * from table (Well this doesn't open up DDL for InnoDB + as ha_innobase::create will return appropriate error if fake-change = ON + but if create is trying to use other SE and SELECT is executing on + InnoDB table then we allow SELECT to proceed. + Ideally, statement like this should be marked CREATE_SELECT like + INSERT_SELECT but unfortunately it doesn't). */ if (UNIV_UNLIKELY(trx->fake_changes + && (thd_sql_command(thd) != SQLCOM_SELECT + && thd_sql_command(thd) != SQLCOM_CREATE_TABLE) && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) { - innobase_rollback(hton, thd, all); /* rollback implicitly */ - thd->stmt_da->reset_diagnostics_area(); /* because debug assertion code complains, if something left */ + /* rollback implicitly */ + innobase_rollback(hton, thd, all); + + /* because debug assertion code complains, if something left */ + thd->stmt_da->reset_diagnostics_area(); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); } /* Transaction is deregistered only in a commit or a rollback. If @@ -12476,6 +12511,46 @@ innodb_change_buffering_update( *static_cast(save); } +#ifdef UNIV_DEBUG +/*************************************************************//** +Check if it is a valid value of innodb_track_changed_pages. +Changed pages tracking is not working correctly without initialization +procedure on server startup. The function allows to temporary +disable tracking, but only if the feature was enabled on startup. +This function is registered as a callback with MySQL. +@return 0 for valid innodb_track_changed_pages */ +static +int +innodb_track_changed_pages_validate( + THD* thd, /*!< in: thread handle */ + struct st_mysql_sys_var* var, /*!< in: pointer to system + variable */ + void* save, /*!< out: immediate result + for update function */ + struct st_mysql_value* value) /*!< in: incoming bool */ +{ + static bool enabled_on_startup = false; + long long intbuf = 0; + + if (value->val_int(value, &intbuf)) { + /* The value is NULL. That is invalid. */ + return 1; + } + + if (srv_track_changed_pages || enabled_on_startup) { + enabled_on_startup = true; + *reinterpret_cast(save) + = static_cast(intbuf); + return 0; + } + + if (intbuf == srv_track_changed_pages) + return 0; + + return 1; +} +#endif + #ifndef DBUG_OFF static char* srv_buffer_pool_evict; @@ -13168,7 +13243,12 @@ static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages, #endif , "Track the redo log for changed pages and output a changed page bitmap", - NULL, NULL, FALSE); +#ifdef UNIV_DEBUG + innodb_track_changed_pages_validate, +#else + NULL, +#endif + NULL, FALSE); static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size, PLUGIN_VAR_RQCMDARG, diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index c1a763b365d..670995fb578 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -267,6 +267,16 @@ thd_supports_xa( void* thd); /*!< in: thread handle (THD*), or NULL to query the global innodb_supports_xa */ +/******************************************************************//** +Check the status of fake changes mode (innodb_fake_changes) +@return true if fake change mode is enabled. */ + +ibool +thd_fake_changes( +/*=============*/ + void* thd); /*!< in: thread handle, or NULL to query + the global innodb_supports_xa */ + /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index a7b74c83f39..71da5ea6125 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -119,6 +119,10 @@ log. */ #define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_WRITE 444 #define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */ +#define OS_FILE_READ_WRITE_CACHED 666 /* OS_FILE_READ_WRITE but never + O_DIRECT. Only for + os_file_create_simple_no_error_handling + currently. */ /* Options for file_create */ #define OS_FILE_AIO 61 @@ -505,9 +509,10 @@ os_file_create_simple_no_error_handling_func( OS_FILE_CREATE if a new file is created (if exists, error) */ ulint access_type,/*!< in: OS_FILE_READ_ONLY, - OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is - used by a backup program reading the file */ + OS_FILE_READ_WRITE, OS_FILE_READ_ALLOW_DELETE + (used by a backup program reading the file), or + OS_FILE_READ_WRITE_CACHED (disable O_DIRECT if + it would be enabled otherwise). */ ibool* success);/*!< out: TRUE if succeed, FALSE if error */ /****************************************************************//** Tries to disable OS caching on an opened file descriptor. */ diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index ba8fcb7e87b..83647fe3367 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -37,6 +37,21 @@ Created 9/6/1995 Heikki Tuuri #include "univ.i" #include "ut0lst.h" +#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \ + || defined _M_X64 || defined __WIN__ + +#define IB_STRONG_MEMORY_MODEL +#undef HAVE_IB_GCC_ATOMIC_TEST_AND_SET // Quick-and-dirty fix for bug 1519094 + +#endif /* __i386__ || __x86_64__ || _M_IX86 || M_X64 || __WIN__ */ + +#ifdef HAVE_WINDOWS_ATOMICS +typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates + on LONG variable */ +#else +typedef byte lock_word_t; +#endif + #ifdef __WIN__ /** Native event (slow)*/ typedef HANDLE os_native_event_t; @@ -317,6 +332,62 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ __sync_lock_test_and_set(ptr, (byte) new_val) +# 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) + +/** 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(__sync_lock_test_and_set(ptr, 1)); +} + +/** Do an atomic release. + +In theory __sync_lock_release should be used to release the lock. +Unfortunately, it does not work properly alone. The workaround is +that more conservative __sync_lock_test_and_set is used instead. + +Performance regression was observed at some conditions for Intel +architecture. Disable release barrier on Intel architecture for now. +@param[in,out] ptr Memory location to write to +@return the previous value */ +static inline +lock_word_t +os_atomic_clear(volatile lock_word_t* ptr) +{ + return(__sync_lock_test_and_set(ptr, 0)); +} + +# else + +# error "Unsupported platform" + +# endif /* HAVE_IB_GCC_ATOMIC_TEST_AND_SET */ + #elif defined(HAVE_IB_SOLARIS_ATOMICS) # define HAVE_ATOMIC_BUILTINS @@ -374,6 +445,26 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ atomic_swap_uchar(ptr, new_val) +/** Do an atomic xchg and set to non-zero. +@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_swap_uchar(ptr, 1)); +} + +/** Do an atomic xchg and set to zero. +@param[in,out] ptr Memory location to set to zero +@return the previous value */ +static inline +lock_word_t +os_atomic_clear(volatile lock_word_t* ptr) +{ + return(atomic_swap_uchar(ptr, 0)); +} + #elif defined(HAVE_WINDOWS_ATOMICS) # define HAVE_ATOMIC_BUILTINS @@ -431,6 +522,28 @@ clobbered */ # define os_atomic_test_and_set_byte(ptr, new_val) \ ((byte) InterlockedExchange(ptr, new_val)) +/** Do an atomic test and set. +InterlockedExchange() operates on LONG, and the LONG will be clobbered +@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(InterlockedExchange(ptr, 1)); +} + +/** Do an atomic release. +InterlockedExchange() operates on LONG, and the LONG will be clobbered +@param[in,out] ptr Memory location to set to zero +@return the previous value */ +static inline +lock_word_t +os_atomic_clear(volatile lock_word_t* ptr) +{ + return(InterlockedExchange(ptr, 0)); +} + #else # define IB_ATOMICS_STARTUP_MSG \ "Mutexes and rw_locks use InnoDB's own implementation" diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index 263b7b0494a..8a95b1d58f0 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -45,13 +45,6 @@ Created 9/5/1995 Heikki Tuuri extern my_bool timed_mutexes; #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ -#ifdef HAVE_WINDOWS_ATOMICS -typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates - on LONG variable */ -#else -typedef byte lock_word_t; -#endif - #if defined UNIV_PFS_MUTEX || defined UNIV_PFS_RWLOCK /* There are mutexes/rwlocks that we want to exclude from instrumentation even if their corresponding performance schema diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic index 73e7379cac1..b107eebf416 100644 --- a/storage/xtradb/include/sync0sync.ic +++ b/storage/xtradb/include/sync0sync.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -80,7 +80,7 @@ mutex_test_and_set( mutex_t* mutex) /*!< in: mutex */ { #if defined(HAVE_ATOMIC_BUILTINS) - return(os_atomic_test_and_set_byte(&mutex->lock_word, 1)); + return(os_atomic_test_and_set(&mutex->lock_word)); #else ibool ret; @@ -108,10 +108,7 @@ mutex_reset_lock_word( mutex_t* mutex) /*!< in: mutex */ { #if defined(HAVE_ATOMIC_BUILTINS) - /* In theory __sync_lock_release should be used to release the lock. - Unfortunately, it does not work properly alone. The workaround is - that more conservative __sync_lock_test_and_set is used instead. */ - os_atomic_test_and_set_byte(&mutex->lock_word, 0); + os_atomic_clear(&mutex->lock_word); #else mutex->lock_word = 0; diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 83af32760e2..5e7b29120ba 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.4 +#define PERCONA_INNODB_VERSION 37.6 #endif #define INNODB_VERSION_STR MYSQL_SERVER_VERSION diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c index 9d0151f40f8..4d7587af288 100644 --- a/storage/xtradb/lock/lock0lock.c +++ b/storage/xtradb/lock/lock0lock.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2015, 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 @@ -2467,16 +2467,16 @@ lock_rec_inherit_to_gap( /* If srv_locks_unsafe_for_binlog is TRUE or session is using READ COMMITTED isolation level, we do not want locks set by an UPDATE or a DELETE to be inherited as gap type locks. But we - DO want S-locks set by a consistency constraint to be inherited also - then. */ + DO want S-locks/X-locks (taken for replace) set by a consistency + constraint to be inherited also then. */ while (lock != NULL) { if (!lock_rec_get_insert_intention(lock) && !((srv_locks_unsafe_for_binlog || lock->trx->isolation_level <= TRX_ISO_READ_COMMITTED) - && lock_get_mode(lock) == LOCK_X)) { - + && lock_get_mode(lock) == + (lock->trx->duplicates ? LOCK_S : LOCK_X))) { lock_rec_add_to_queue(LOCK_REC | LOCK_GAP | lock_get_mode(lock), heir_block, heir_heap_no, diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c index acb3bd58714..a8444199ea9 100644 --- a/storage/xtradb/log/log0online.c +++ b/storage/xtradb/log/log0online.c @@ -544,7 +544,7 @@ log_online_start_bitmap_file(void) innodb_file_bmp_key, log_bmp_sys->out.name, OS_FILE_CREATE, - OS_FILE_READ_WRITE, + OS_FILE_READ_WRITE_CACHED, &success); } if (UNIV_UNLIKELY(!success)) { @@ -704,7 +704,7 @@ log_online_read_init(void) log_bmp_sys->out.file = os_file_create_simple_no_error_handling (innodb_file_bmp_key, log_bmp_sys->out.name, OS_FILE_OPEN, - OS_FILE_READ_WRITE, &success); + OS_FILE_READ_WRITE_CACHED, &success); if (!success) { @@ -1494,10 +1494,20 @@ log_online_open_bitmap_file_read_only( ibool success = FALSE; ulint size_low; ulint size_high; + size_t srv_data_home_len; ut_ad(name[0] != '\0'); - ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name); + srv_data_home_len = strlen(srv_data_home); + if (srv_data_home_len + && srv_data_home[srv_data_home_len-1] + != SRV_PATH_SEPARATOR) { + ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%c%s", + srv_data_home, SRV_PATH_SEPARATOR, name); + } else { + ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", + srv_data_home, name); + } bitmap_file->file = os_file_create_simple_no_error_handling(innodb_file_bmp_key, bitmap_file->name, diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index 55d951d8ff6..1a991695926 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -1833,7 +1833,7 @@ loop: goto loop; } - ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); + ut_ad((allow_ibuf == 0) == (mutex_own(&log_sys->mutex) != 0)); if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c index ebcacc5c94f..6e1b59aba12 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -1231,9 +1231,10 @@ os_file_create_simple_no_error_handling_func( OS_FILE_CREATE if a new file is created (if exists, error) */ ulint access_type,/*!< in: OS_FILE_READ_ONLY, - OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is - used by a backup program reading the file */ + OS_FILE_READ_WRITE, OS_FILE_READ_ALLOW_DELETE + (used by a backup program reading the file), or + OS_FILE_READ_WRITE_CACHED (disable O_DIRECT if + it would be enabled otherwise). */ ibool* success)/*!< out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ @@ -1256,7 +1257,8 @@ os_file_create_simple_no_error_handling_func( if (access_type == OS_FILE_READ_ONLY) { access = GENERIC_READ; - } else if (access_type == OS_FILE_READ_WRITE) { + } else if (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) { access = GENERIC_READ | GENERIC_WRITE; } else if (access_type == OS_FILE_READ_ALLOW_DELETE) { access = GENERIC_READ; @@ -1317,7 +1319,8 @@ os_file_create_simple_no_error_handling_func( if (file == -1) { *success = FALSE; #ifdef USE_FILE_LOCK - } else if (access_type == OS_FILE_READ_WRITE + } else if ((access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) && os_file_lock(file, name)) { *success = FALSE; close(file); @@ -1330,7 +1333,9 @@ os_file_create_simple_no_error_handling_func( disable OS caching (O_DIRECT) here as we do in os_file_create_func(), so we open the same file in the same mode, see man page of open(2). */ - if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) { + if ((srv_unix_file_flush_method == SRV_UNIX_O_DIRECT + || srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) + && access_type != OS_FILE_READ_WRITE_CACHED) { os_file_set_nocache(file, name, mode_str); } } diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 97a4fb0767f..6de9a95a694 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -247,8 +247,9 @@ row_ins_sec_index_entry_by_modify( rec = btr_cur_get_rec(cursor); ut_ad(!dict_index_is_clust(cursor->index)); - ut_ad(rec_get_deleted_flag(rec, - dict_table_is_comp(cursor->index->table))); + ut_ad(UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes) + || rec_get_deleted_flag(rec, + dict_table_is_comp(cursor->index->table))); /* We know that in the alphabetical ordering, entry and rec are identified. But in their binary form there may be differences if diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c index 7ed79d4c7f4..88737e2da69 100644 --- a/storage/xtradb/trx/trx0trx.c +++ b/storage/xtradb/trx/trx0trx.c @@ -881,6 +881,12 @@ trx_start_low( trx->no = IB_ULONGLONG_MAX; + /* Cache the state of fake_changes that transaction will use for + lifetime. Any change in session/global fake_changes configuration during + lifetime of transaction will not be honored by already started + transaction. */ + trx->fake_changes = thd_fake_changes(trx->mysql_thd); + trx->rseg = rseg; trx->state = TRX_ACTIVE; From 584c07bd8808919c0b7bbc68864074af68ae5035 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Wed, 21 Oct 2015 11:51:15 +0200 Subject: [PATCH 64/66] MDEV-8978 Specify GPL version in RPM metadata The License field in the MariaDB RPM packages is GPL. This does not tell the version of GPL and might confuse tools and users that rely on this field. Best practice in the RPM world is to use "GPLv2" for the GPL 2.0 license. The commit switches the license field of the RPM packages to GPLv2. --- cmake/cpack_rpm.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index bd8d96154b2..c5af3e68984 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -31,7 +31,7 @@ SET(CPACK_RPM_PACKAGE_NAME "MariaDB") SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}") SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}") -SET(CPACK_RPM_PACKAGE_LICENSE "GPL") +SET(CPACK_RPM_PACKAGE_LICENSE "GPLv2") SET(CPACK_RPM_PACKAGE_RELOCATABLE FALSE) SET(CPACK_RPM_PACKAGE_GROUP "Applications/Databases") SET(CPACK_RPM_PACKAGE_URL "http://mariadb.org") From fa4d4fc76eb2cc74dbccf8890aad7b5e0cac59d1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 10:06:28 +0100 Subject: [PATCH 65/66] unit tests for my_getopt --- unittest/mysys/CMakeLists.txt | 1 + unittest/mysys/my_getopt-t.c | 71 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 unittest/mysys/my_getopt-t.c diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt index effdd9bea1c..c4af7828e42 100644 --- a/unittest/mysys/CMakeLists.txt +++ b/unittest/mysys/CMakeLists.txt @@ -14,6 +14,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA MY_ADD_TESTS(bitmap base64 my_vsnprintf my_atomic my_rdtsc lf my_malloc + my_getopt LINK_LIBRARIES mysys) IF(WIN32) diff --git a/unittest/mysys/my_getopt-t.c b/unittest/mysys/my_getopt-t.c new file mode 100644 index 00000000000..afdb5e8b3b8 --- /dev/null +++ b/unittest/mysys/my_getopt-t.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2015 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include + +ulonglong opt_ull; +ulong opt_ul; +int argc, res; +char **argv, *args[100]; + +struct my_option my_long_options[]= +{ + {"ull", 0, "ull", &opt_ull, &opt_ull, + 0, GET_ULL, REQUIRED_ARG, 1, 0, ~0ULL, 0, 0, 0}, + {"ul", 0, "ul", &opt_ul, &opt_ul, + 0, GET_ULONG, REQUIRED_ARG, 1, 0, 0xFFFFFFFF, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +void run(const char *arg, ...) +{ + va_list ap; + va_start(ap, arg); + argv= args; + *argv++= (char*)""; + while (arg) + { + *argv++= (char*)arg; + arg= va_arg(ap, char*); + } + va_end(ap); + argc= argv - args; + argv= args; + res= handle_options(&argc, &argv, my_long_options, 0); +} + +int main() { + plan(3); + + run("--ull=100", NULL); + ok(res==0 && argc==0 && opt_ull==100, + "res:%d, argc:%d, opt_ull:%llu", res, argc, opt_ull); + + /* + negative numbers are wrapped. this is kinda questionable, + we might want to fix it eventually. but it'd be a change in behavior, + users might've got used to "-1" meaning "max possible value" + */ + run("--ull=-100", NULL); + ok(res==0 && argc==0 && opt_ull==18446744073709551516ULL, + "res:%d, argc:%d, opt_ull:%llu", res, argc, opt_ull); + run("--ul=-100", NULL); + ok(res==0 && argc==0 && opt_ul==4294967295UL, + "res:%d, argc:%d, opt_ul:%lu", res, argc, opt_ul); + return exit_status(); +} + From d67aacb4fbb449ffa8db4e3d70fe8756d62b5222 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 17:11:55 +0100 Subject: [PATCH 66/66] fix xtradb compilation on windows --- storage/xtradb/handler/ha_innodb.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index c04a502902d..f3b9167835e 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -13493,17 +13493,15 @@ static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method, /* Make this variable dynamic for debug builds to provide a testcase sync facility */ #define track_changed_pages_flags PLUGIN_VAR_NOCMDARG +#define track_changed_pages_check innodb_track_changed_pages_validate #else #define track_changed_pages_flags PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY +#define track_changed_pages_check NULL #endif static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages, track_changed_pages_flags, "Track the redo log for changed pages and output a changed page bitmap", -#ifdef UNIV_DEBUG - innodb_track_changed_pages_validate, -#else - NULL, -#endif + track_changed_pages_check, NULL, FALSE); static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size,