From 6d30383e78c8b9aba56f645421f437af63706efe Mon Sep 17 00:00:00 2001 From: Murthy Narkedimilli Date: Mon, 31 Aug 2015 20:36:03 +0200 Subject: 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= -- cgit v1.2.1 From 97ea06e807628b6d079ae5f72f5ee0c0ea391caf Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Tue, 1 Sep 2015 08:53:15 +0200 Subject: 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 -- cgit v1.2.1 From ddcad361d6ff2c3336221f27c4e31bfc8d1913b1 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Fri, 4 Sep 2015 11:10:57 +0530 Subject: 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); } -- cgit v1.2.1 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: 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" -- cgit v1.2.1 From 17387bc574a4054a9aeac7ba4aa60e25588dc7bf Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Wed, 16 Sep 2015 18:58:43 +0530 Subject: 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); -- cgit v1.2.1 From 4acc7615eedc167fbad6fcc14966a054de35fd75 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 18 Sep 2015 07:34:32 +0530 Subject: 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*))))) -- cgit v1.2.1 From 0632dae73fe3379cba00beeb65585f0d61f10d8c Mon Sep 17 00:00:00 2001 From: Robert Golebiowski Date: Fri, 18 Sep 2015 10:35:09 +0200 Subject: 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); } -- cgit v1.2.1 From 259cf3dc607dd0112d44c4647b07a3024cee268e Mon Sep 17 00:00:00 2001 From: Robert Golebiowski Date: Fri, 18 Sep 2015 11:18:25 +0200 Subject: 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); -- cgit v1.2.1 From 8ea80ecfeb88846ee47c65011eb9ff7eddab84b3 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Tue, 22 Sep 2015 06:21:13 +0200 Subject: 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 -- cgit v1.2.1 From 86375f7fa6a428bfc405f85335685cd1dff25302 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 22 Sep 2015 14:51:48 +0530 Subject: 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)) -- cgit v1.2.1 From ea9dbef661efdf5079b1b0e33679a863408e3166 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Tue, 22 Sep 2015 16:52:18 +0530 Subject: 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))) -- cgit v1.2.1 From 8ea58c474fbbcd79e9716379d226b8a46062b350 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 30 Sep 2015 10:27:26 +0530 Subject: 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 -- cgit v1.2.1 From 415faa122b9c683661dafac82fff414fa6864151 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Thu, 1 Oct 2015 07:45:27 +0530 Subject: 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 -- cgit v1.2.1 From 130b5fbf91520e504194eb59c16a6ce38006ff7a Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 6 Oct 2015 07:09:36 +0530 Subject: 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); -- cgit v1.2.1 -- cgit v1.2.1 From f92dd6ae6fb8922122049957b6ab7e07b6518bc2 Mon Sep 17 00:00:00 2001 From: Mithun C Y Date: Mon, 12 Oct 2015 12:56:36 +0530 Subject: 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; } } -- cgit v1.2.1 From 3846b085521bce8e4600d4860dc3f2ea5f2ceb2d Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Wed, 14 Oct 2015 11:08:49 +0530 Subject: 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); -- cgit v1.2.1 From a86191c69c95240ba3dcd9858341a30898c34285 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Wed, 14 Oct 2015 12:00:39 +0530 Subject: 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 +++++++++++++ mysql-test/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; -- cgit v1.2.1 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: 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; -- cgit v1.2.1 From dea23408660130f04af7e954811122d86656900f Mon Sep 17 00:00:00 2001 From: Mithun C Y Date: Thu, 22 Oct 2015 17:02:12 +0530 Subject: 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'; -- cgit v1.2.1 From a60740607c9581ed2bf92bdd087139ea8d872484 Mon Sep 17 00:00:00 2001 From: Srikanth B R Date: Mon, 26 Oct 2015 16:19:11 +0530 Subject: 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; -- cgit v1.2.1 From 1942506b82897e498493cc3ec274a2b402c4d105 Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Thu, 29 Oct 2015 13:35:32 +0530 Subject: 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 -- cgit v1.2.1 From 9b6ac73419256cf3c9554d8a782c4eaee6c6cf79 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Mon, 2 Nov 2015 16:30:57 +0530 Subject: 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; -- cgit v1.2.1 From 5e9a50efc37c233f1e2a3616f8bcb36315aba4c2 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 3 Nov 2015 07:43:54 +0530 Subject: 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++) -- cgit v1.2.1 From 75bfdea40f9c2954d8eadccbadc795231e310ab7 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 3 Nov 2015 07:59:57 +0530 Subject: 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'. + + @param to Variable length field we're copying to + @param from Variable length field we're copying from -static void do_varstring1(Copy_field *copy) + @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) + { + 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); + } + } + else { - 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); + 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); + } } - *(uchar*) copy->to_ptr= (uchar) length; - memcpy(copy->to_ptr+1, copy->from_ptr + 1, 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_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) - { - if (current_thd->count_cuted_fields) - copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1); - } - *copy->to_ptr= (uchar) length; - memcpy(copy->to_ptr + 1, from_ptr, length); -} + 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 -static void do_varstring2(Copy_field *copy) + @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()); -- cgit v1.2.1 From 5f2d3479ffed18e28435c9ad130d400e7290e0bb Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 4 Nov 2015 16:12:27 +0530 Subject: 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 -- cgit v1.2.1 From fd9831410dfc878420fcd95dc576b955e94d2c76 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Thu, 5 Nov 2015 16:33:47 +0530 Subject: 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 -- cgit v1.2.1 From 0dbd5a8797ed4bd18e8b883988fb62177eb0f73f Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Fri, 6 Nov 2015 16:41:55 +0530 Subject: 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)); -- cgit v1.2.1 From 40ae1b9b618fbbc3b494a896a9d074b74e414337 Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Sat, 7 Nov 2015 22:03:47 +0530 Subject: 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. -- cgit v1.2.1 From 13ad179c96ee8c8c4043806b8575c851e3676f0d Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 20 Nov 2015 14:50:18 +0100 Subject: 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) { -- cgit v1.2.1 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: 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 + .../innodb/t/innodb_information_schema_tables.opt | 29 ++++++++++ .../innodb/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); } -- cgit v1.2.1 From 9f07c6b383d776d430510de1256b3e4e8680bc60 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Dec 2015 16:08:54 +0400 Subject: 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`; -- cgit v1.2.1 From d87bc55b05046d6484659286fa831ff10dbd3af9 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 3 Dec 2015 20:43:54 +0400 Subject: 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); -- cgit v1.2.1 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: 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); } -- cgit v1.2.1 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: 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; -- cgit v1.2.1 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: 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]; -- cgit v1.2.1 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: 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++) -- cgit v1.2.1 From ee2fce5e88b3ea4a3193422105c83dc1582de29f Mon Sep 17 00:00:00 2001 From: Christian Loos Date: Tue, 20 Oct 2015 09:41:44 +0200 Subject: 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 -- cgit v1.2.1 From c8652eefe50fd1894f2e2360e8bd631a7b9c67f5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 11:22:25 +0100 Subject: 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; -- cgit v1.2.1 From ef47b62551b0f37770e5d174ea028150c5b71fd8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 11:29:00 +0100 Subject: 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); -- cgit v1.2.1 From e05883bf305ff6f9b85288e11d1e9b7458bb924e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 5 Dec 2015 15:25:15 +0100 Subject: 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; -- cgit v1.2.1 From 354e567c2384f95126ffa1e36382c4e0c206521c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 01:40:51 +0100 Subject: 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; - - tmp_txn.release(&io); + txn= &zero_txn; - DBUG_ASSERT(io == NULL); + txn->release(&io); + DBUG_ASSERT(io == NULL); - if ((error= free_share(&tmp_txn, share))) - retval= error; - } - else - { - txn->release(&io); - DBUG_ASSERT(io == NULL); + free_share(txn, share); - 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; -- cgit v1.2.1 From 18954ff25d27252f3ce9865e636c91e0783572af Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 01:48:07 +0100 Subject: 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 --- .../suite/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); } -- cgit v1.2.1 From d1fe928c4f128cc5440c30511b3900d7c5da65d7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 12:01:12 +0100 Subject: 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 () { -- cgit v1.2.1 From f18599a129cb64a65187a6c12a9b2505f39f85f5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 20:22:33 +0100 Subject: 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", -- cgit v1.2.1 From 8fd24b418d1a0935ff37d164a6548c9f956bf600 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:25:27 +0100 Subject: 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)); -- cgit v1.2.1 From 99774f150186d1624efe41a6600c437e556f6299 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 Dec 2015 11:51:57 +0100 Subject: 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 -- cgit v1.2.1 From 859a7369c1977baf6e204f4ed8f54b774790a179 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 14:07:36 +0100 Subject: 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 -- cgit v1.2.1 From 79d08e682ff70469abe7146f06b3b4103679e072 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 15:15:43 +0100 Subject: 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 */ -- cgit v1.2.1 From 544eeda30d740bf8eaa99e8a1f47fbbbc3ef2086 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:27:58 +0100 Subject: 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(); -- cgit v1.2.1 From f0d774d48416bb06063184380b684380ca005a41 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Dec 2015 20:06:54 +0100 Subject: 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); - X509_free (server_cert); + x509sn= X509_get_subject_name(server_cert); - if (!buf) - { - *errptr= "Out of memory"; - DBUG_RETURN(1); - } + if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0) + goto err; - 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); - } - } + 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); + +err: + X509_free(server_cert); *errptr= "SSL certificate validation failure"; - free(buf); DBUG_RETURN(1); } -- cgit v1.2.1 From c21b927145e2da7fe835bc84b2b2b57e9dc2c60a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 8 Dec 2015 10:13:13 +0100 Subject: 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 -- cgit v1.2.1 From 50a796dcba2abe5f25c1e4cd8a69d7ea43343a8d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 8 Dec 2015 10:16:41 +0100 Subject: 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); -- cgit v1.2.1 From dac3149f3f3cd79c8b2066f1030782eefb62ad15 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 8 Dec 2015 17:20:34 +0400 Subject: 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; -- cgit v1.2.1 From 9457139e591aa7fb0459788acdbc260db53b0f22 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 12:27:04 +0100 Subject: 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; -- cgit v1.2.1 From 584c07bd8808919c0b7bbc68864074af68ae5035 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Wed, 21 Oct 2015 11:51:15 +0200 Subject: 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") -- cgit v1.2.1 From fa4d4fc76eb2cc74dbccf8890aad7b5e0cac59d1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 10:06:28 +0100 Subject: 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(); +} + -- cgit v1.2.1 From d67aacb4fbb449ffa8db4e3d70fe8756d62b5222 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 17:11:55 +0100 Subject: 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, -- cgit v1.2.1 From fa25921b59aacdc6be050653f6cce17df12c6937 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 10 Dec 2015 11:22:53 +0100 Subject: MDEV-8407 Numeric errors, server crash with COLUMN_JSON() on DECIMAL with precision > 40 In fact it was error in decimal library (incorrect processing of buffer overflow) invisible from other server parts because of buffer allocation and precision tests. --- strings/decimal.c | 3 ++- unittest/my_decimal/my_decimal-t.cc | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/strings/decimal.c b/strings/decimal.c index 07ccc537e47..8dbe1bd57f4 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -383,7 +383,8 @@ int decimal2string(const decimal_t *from, char *to, int *to_len, } else frac-=j; - len= from->sign + intg_len + test(frac) + frac_len; + frac_len= frac; + len= from->sign + intg_len + test(frac) + frac; } *to_len=len; s[len]=0; diff --git a/unittest/my_decimal/my_decimal-t.cc b/unittest/my_decimal/my_decimal-t.cc index 48d00465af9..92c4bdee8e4 100644 --- a/unittest/my_decimal/my_decimal-t.cc +++ b/unittest/my_decimal/my_decimal-t.cc @@ -61,12 +61,42 @@ test_copy_and_compare() } +static int +test_decimal2string() +{ + decimal_t d1; + decimal_digit_t buffer[DECIMAL_BUFF_LENGTH+2]; + char *str_end; + const char strnum[]= "0.1234567890123456789012345678901234567890123467"; + char strbuff[50]; + int len= 40; + int i; + + bzero(strbuff, sizeof(strbuff)); + str_end= (char *)(strnum + (sizeof(strnum) - 1)); + + d1.len= DECIMAL_BUFF_LENGTH + 2; + d1.buf= buffer; + + string2decimal(strnum, &d1, &str_end); + decimal2string(&d1, strbuff, &len, 0, 0, 'X'); + + /* last digit is not checked due to possible rounding */ + for (i= 0; i < 38 && strbuff[i] == strnum[i]; i++); + ok(i == 38, "Number"); + for (i= 39; i < 50 && strbuff[i] == 0; i++); + ok(i == 50, "No overrun"); + + return 0; + +} int main() { - plan(13); + plan(15); diag("Testing my_decimal constructor and assignment operators"); test_copy_and_compare(); - + test_decimal2string(); + return exit_status(); } -- cgit v1.2.1 From c19972fc8708778bd6070715b449351a39edb0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 11 Dec 2015 14:33:41 +0200 Subject: MDEV-9251: Fix MySQL Bug#20755615: InnoDB compares column names case sensitively, while according to Storage Engine API column names should be compared case insensitively. This can cause FRM and InnoDB data dictionary to go out of sync. --- mysql-test/suite/innodb/r/innodb-dict.result | 40 ++++++++++++++++++++++++++++ mysql-test/suite/innodb/t/innodb-dict.test | 31 +++++++++++++++++++++ storage/innobase/dict/dict0dict.c | 2 +- storage/xtradb/dict/dict0dict.c | 2 +- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-dict.result create mode 100644 mysql-test/suite/innodb/t/innodb-dict.test diff --git a/mysql-test/suite/innodb/r/innodb-dict.result b/mysql-test/suite/innodb/r/innodb-dict.result new file mode 100644 index 00000000000..e3b2f0d5288 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-dict.result @@ -0,0 +1,40 @@ +CREATE TABLE t1 (D INT) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 MODIFY COLUMN d INT; +ALTER TABLE t1 ADD INDEX my_d (d); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` int(11) DEFAULT NULL, + KEY `my_d` (`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +EXPLAIN SELECT d FROM t1 WHERE d = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref my_d my_d 5 const 128 Using index +EXPLAIN SELECT D FROM t1 WHERE D = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref my_d my_d 5 const 128 Using index +ALTER TABLE t1 DROP INDEX my_d; +ALTER TABLE t1 MODIFY COLUMN D INT; +ALTER TABLE t1 ADD INDEX my_d (D); +EXPLAIN SELECT d FROM t1 WHERE d = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref my_d my_d 5 const 128 Using index +EXPLAIN SELECT D FROM t1 WHERE D = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref my_d my_d 5 const 128 Using index +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `D` int(11) DEFAULT NULL, + KEY `my_d` (`D`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-dict.test b/mysql-test/suite/innodb/t/innodb-dict.test new file mode 100644 index 00000000000..25a284569db --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-dict.test @@ -0,0 +1,31 @@ +--source include/have_innodb.inc + +# +# Fix MySQL Bug#20755615: InnoDB compares column names case sensitively, +# while according to Storage Engine API column names should be compared +# case insensitively. This can cause FRM and InnoDB data dictionary to +# go out of sync: +# + +CREATE TABLE t1 (D INT) ENGINE=innodb; +INSERT INTO t1 VALUES (10); +ALTER TABLE t1 MODIFY COLUMN d INT; +ALTER TABLE t1 ADD INDEX my_d (d); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +EXPLAIN SELECT d FROM t1 WHERE d = 5; +EXPLAIN SELECT D FROM t1 WHERE D = 5; +ALTER TABLE t1 DROP INDEX my_d; +ALTER TABLE t1 MODIFY COLUMN D INT; +ALTER TABLE t1 ADD INDEX my_d (D); +EXPLAIN SELECT d FROM t1 WHERE d = 5; +EXPLAIN SELECT D FROM t1 WHERE D = 5; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 17e9eb122df..33b110ce97a 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -2010,7 +2010,7 @@ dict_index_find_cols( dict_field_t* field = dict_index_get_nth_field(index, i); for (j = 0; j < table->n_cols; j++) { - if (!strcmp(dict_table_get_col_name(table, j), + if (!innobase_strcasecmp(dict_table_get_col_name(table, j), field->name)) { field->col = dict_table_get_nth_col(table, j); diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index 7351de5de2b..87d7a3b2403 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -2142,7 +2142,7 @@ dict_index_find_cols( dict_field_t* field = dict_index_get_nth_field(index, i); for (j = 0; j < table->n_cols; j++) { - if (!strcmp(dict_table_get_col_name(table, j), + if (!innobase_strcasecmp(dict_table_get_col_name(table, j), field->name)) { field->col = dict_table_get_nth_col(table, j); -- cgit v1.2.1 From 265e833fdd921c58c2525442a7064003da83c884 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 21:22:37 +0100 Subject: revert 415faa122b9c683661dafac82fff414fa6864151 that was mistakenly merged from mysql-5.5.47 --- sql/item_subselect.cc | 24 ------------------------ sql/sql_select.cc | 11 ----------- 2 files changed, 35 deletions(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 3020faf29d3..ba674743724 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1748,27 +1748,6 @@ 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, where_item); have_to_be_excluded= 1; @@ -2055,9 +2034,6 @@ Item_in_subselect::create_single_in_to_exists_cond(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 1b1464049df..3d39fc266db 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4114,17 +4114,6 @@ add_key_field(JOIN *join, Field *field, bool eq_func, Item **value, uint num_values, table_map usable_tables, SARGABLE_PARAM **sargables) { - 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; - } - uint optimize= 0; if (eq_func && ((join->is_allowed_hash_join_access() && -- cgit v1.2.1 From f560c1ba429e6fd1f1a8df8babed88c99f8d2952 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 10 Dec 2015 10:32:11 +0100 Subject: revert 5e9a50efc37c233f1e2a3616f8bcb36315aba4c2 that was mistakenly merged from mysql-5.5.47 (introduces valgrind failures in main.sp, because Field_varstring columns are created as FIELD_NORMAL and that causes aria to read bytes between the actual value length and field max length) --- sql/sql_select.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d39fc266db..f43f506692c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15433,9 +15433,7 @@ 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) + else if (field->real_type() == MYSQL_TYPE_VARCHAR) recinfo->type= FIELD_VARCHAR; else recinfo->type= FIELD_NORMAL; -- cgit v1.2.1 From ca28d9011cd57cdf8af7072a3bd8219054ae1191 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 Dec 2015 17:54:55 +0100 Subject: MDEV-7655 SHOW CREATE TABLE returns invalid DDL when using virtual columns along with a table collation --- mysql-test/suite/vcol/r/vcol_misc.result | 8 ++++++++ mysql-test/suite/vcol/t/vcol_misc.test | 7 +++++++ sql/sql_show.cc | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 8631789f15f..0aaed59ed6c 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -322,3 +322,11 @@ drop table t1; create table t1 (a int, b int as (b is null) virtual); ERROR HY000: A computed column cannot be based on a computed column # end of 5.3 tests +create table t1 (v1 varchar(255) as (c1) persistent, c1 varchar(50)) collate=latin1_general_ci; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v1` varchar(255) AS (c1) PERSISTENT, + `c1` varchar(50) COLLATE latin1_general_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci +drop table t1; diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index a4c1fc06ce9..12f46e9b002 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -283,3 +283,10 @@ drop table t1; create table t1 (a int, b int as (b is null) virtual); --echo # end of 5.3 tests + +# +# MDEV-7655 SHOW CREATE TABLE returns invalid DDL when using virtual columns along with a table collation +# +create table t1 (v1 varchar(255) as (c1) persistent, c1 varchar(50)) collate=latin1_general_ci; +show create table t1; +drop table t1; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 45bddc24820..af941c350e7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1611,7 +1611,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, For string types dump collation name only if collation is not primary for the given charset */ - if (!(field->charset()->state & MY_CS_PRIMARY)) + if (!(field->charset()->state & MY_CS_PRIMARY) && !field->vcol_info) { packet->append(STRING_WITH_LEN(" COLLATE ")); packet->append(field->charset()->name); -- cgit v1.2.1 From 0ed474484c037a32bea32abaecd3ff770f40bd49 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 11 Dec 2015 17:03:55 +0100 Subject: fix main.mysqldump test on windows --- mysql-test/t/mysqldump.test | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index b0285747e4e..f0ada44fafd 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2502,5 +2502,10 @@ 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 +--let shell_ready_db_name="a\\\\\\"'`b" +if (`select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows") = 0`) +{ + --let shell_ready_db_name=a\\\\\\"\\'\\`b +} +--exec $MYSQL_DUMP --routines --compact $shell_ready_db_name DROP DATABASE `a\"'``b`; -- cgit v1.2.1