summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql.cc11
-rw-r--r--extra/yassl/include/openssl/rsa.h2
-rw-r--r--extra/yassl/include/openssl/ssl.h2
-rw-r--r--extra/yassl/include/yassl_int.hpp4
-rw-r--r--extra/yassl/include/yassl_types.hpp5
-rw-r--r--extra/yassl/src/handshake.cpp17
-rw-r--r--extra/yassl/src/template_instnt.cpp2
-rw-r--r--extra/yassl/src/yassl_int.cpp22
-rw-r--r--extra/yassl/taocrypt/include/integer.hpp2
-rw-r--r--extra/yassl/taocrypt/include/misc.hpp5
-rw-r--r--extra/yassl/taocrypt/include/runtime.hpp26
-rw-r--r--extra/yassl/taocrypt/src/algebra.cpp4
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp21
-rw-r--r--extra/yassl/taocrypt/src/template_instnt.cpp1
-rw-r--r--innobase/dict/dict0dict.c38
-rw-r--r--innobase/dict/dict0load.c17
-rw-r--r--innobase/dict/dict0mem.c18
-rw-r--r--innobase/ibuf/ibuf0ibuf.c6
-rw-r--r--innobase/include/dict0dict.h9
-rw-r--r--innobase/include/dict0mem.h7
-rw-r--r--innobase/include/univ.i3
-rw-r--r--innobase/log/log0recv.c6
-rw-r--r--innobase/row/row0mysql.c18
-rwxr-xr-xmysql-test/mysql-test-run.pl3
-rw-r--r--mysql-test/mysql-test-run.sh6
-rw-r--r--mysql-test/ndb/ndbcluster.sh6
-rw-r--r--mysql-test/r/func_gconcat.result10
-rw-r--r--mysql-test/r/func_str.result10
-rw-r--r--mysql-test/r/innodb.result2
-rw-r--r--mysql-test/r/key_cache.result42
-rw-r--r--mysql-test/r/ndb_bitfield.result4
-rw-r--r--mysql-test/r/order_by.result32
-rw-r--r--mysql-test/r/rpl_deadlock.result105
-rw-r--r--mysql-test/t/func_gconcat.test11
-rw-r--r--mysql-test/t/func_str.test9
-rw-r--r--mysql-test/t/innodb.test6
-rw-r--r--mysql-test/t/innodb_unsafe_binlog-master.opt2
-rw-r--r--mysql-test/t/key_cache.test41
-rw-r--r--mysql-test/t/order_by.test14
-rw-r--r--mysql-test/t/rpl_deadlock.test8
-rw-r--r--mysys/mf_keycache.c12
-rw-r--r--ndb/include/kernel/signaldata/TupFrag.hpp3
-rw-r--r--ndb/include/util/NdbSqlUtil.hpp6
-rw-r--r--ndb/include/util/ndb_opts.h6
-rw-r--r--ndb/src/common/util/NdbSqlUtil.cpp52
-rw-r--r--ndb/src/kernel/SimBlockList.cpp4
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp5
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp5
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.cpp18
-rw-r--r--ndb/src/ndbapi/NdbScanOperation.cpp5
-rw-r--r--sql/item_strfunc.cc14
-rw-r--r--sql/item_strfunc.h1
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/lock.cc56
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_parse.cc103
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_yacc.yy24
60 files changed, 720 insertions, 162 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 8589bdb05ed..12c86e02dc4 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -653,7 +653,7 @@ static struct my_option my_long_options[] =
"Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"socket", 'S', "Socket file to use for connection. (This will override --port unless --protocol=TCP is specified.)",
+ {"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
@@ -939,14 +939,7 @@ static int get_options(int argc, char **argv)
opt_reconnect= 0;
connect_flag= 0; /* Not in interactive mode */
}
-
- if (opt_mysql_port && (!opt_protocol) && (!opt_mysql_unix_port))
- {
- /* Not checking return type since we are using a constant value */
- /* straight from the initialization of sql_protocol_typelib. */
- opt_protocol= find_type("TCP", &sql_protocol_typelib, 0);
- }
-
+
if (strcmp(default_charset, charset_info->csname) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME))))
diff --git a/extra/yassl/include/openssl/rsa.h b/extra/yassl/include/openssl/rsa.h
index 1ab9d13b89f..fe64e655bdc 100644
--- a/extra/yassl/include/openssl/rsa.h
+++ b/extra/yassl/include/openssl/rsa.h
@@ -1,7 +1,7 @@
/* rsa.h for openSSL */
-#ifndef ysSSL_rsa_h__
+#ifndef yaSSL_rsa_h__
#define yaSSL_rsa_h__
enum { RSA_F4 = 1 };
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 1c8291c2f13..8a87196b7ed 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -23,7 +23,7 @@
*
*/
-#ifndef ysSSL_openssl_h__
+#ifndef yaSSL_openssl_h__
#define yaSSL_openssl_h__
#include <stdio.h> /* ERR_print fp */
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 60a78a3970e..e75294ad073 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -123,8 +123,6 @@ public:
friend sslFactory& GetSSL_Factory(); // singleton creator
private:
- static sslFactory instance_;
-
sslFactory(const sslFactory&); // hide copy
sslFactory& operator=(const sslFactory&); // and assign
};
@@ -216,8 +214,6 @@ public:
friend Sessions& GetSessions(); // singleton creator
private:
- static Sessions instance_;
-
Sessions(const Sessions&); // hide copy
Sessions& operator=(const Sessions&); // and assign
};
diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp
index ec9e6fb7ceb..66cc6aa3c68 100644
--- a/extra/yassl/include/yassl_types.hpp
+++ b/extra/yassl/include/yassl_types.hpp
@@ -34,6 +34,11 @@
namespace yaSSL {
+
+// Delete static singleton memory holders
+void CleanUp();
+
+
// library allocation
struct new_t {}; // yaSSL New type
extern new_t ys; // pass in parameter
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index d7df438b8df..16c9bde2003 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -648,8 +648,6 @@ void build_certHashes(SSL& ssl, Hashes& hashes)
}
-mySTL::auto_ptr<input_buffer> null_buffer(ysDelete);
-
// do process input requests
mySTL::auto_ptr<input_buffer>
DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
@@ -659,7 +657,8 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
if (!ready) {
// Nothing to receive after blocking wait => error
ssl.SetError(receive_error);
- return buffered= null_buffer;
+ buffered.reset(0);
+ return buffered;
}
// add buffered data if its there
@@ -667,10 +666,10 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
input_buffer buffer(buffSz + ready);
if (buffSz) {
buffer.assign(buffered.get()->get_buffer(), buffSz);
- buffered = null_buffer;
+ buffered.reset(0);
}
- // add new (ys) data
+ // add new data
uint read = ssl.getSocket().receive(buffer.get_buffer() + buffSz, ready);
buffer.add_size(read);
uint offset = 0;
@@ -703,11 +702,15 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_), ysDelete);
if (!msg.get()) {
ssl.SetError(factory_error);
- return buffered = null_buffer;
+ buffered.reset(0);
+ return buffered;
}
buffer >> *msg;
msg->Process(buffer, ssl);
- if (ssl.GetError()) return buffered = null_buffer;
+ if (ssl.GetError()) {
+ buffered.reset(0);
+ return buffered;
+ }
}
offset += hdr.length_ + RECORD_HEADER;
}
diff --git a/extra/yassl/src/template_instnt.cpp b/extra/yassl/src/template_instnt.cpp
index 5ee57e76aed..c55ca39bec2 100644
--- a/extra/yassl/src/template_instnt.cpp
+++ b/extra/yassl/src/template_instnt.cpp
@@ -87,6 +87,8 @@ template void ysDelete<BulkCipher>(BulkCipher*);
template void ysDelete<Digest>(Digest*);
template void ysDelete<X509>(X509*);
template void ysDelete<Message>(Message*);
+template void ysDelete<sslFactory>(sslFactory*);
+template void ysDelete<Sessions>(Sessions*);
template void ysArrayDelete<unsigned char>(unsigned char*);
template void ysArrayDelete<char>(char*);
}
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 740618ce701..87d990b3506 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -1361,19 +1361,31 @@ SSL_SESSION::~SSL_SESSION()
}
-Sessions Sessions::instance_; // simple singleton
+static Sessions* sessionsInstance = 0;
Sessions& GetSessions()
{
- return Sessions::instance_;
+ if (!sessionsInstance)
+ sessionsInstance = new (ys) Sessions;
+ return *sessionsInstance;
}
-sslFactory sslFactory::instance_; // simple singleton
+static sslFactory* sslFactoryInstance = 0;
sslFactory& GetSSL_Factory()
-{
- return sslFactory::instance_;
+{
+ if (!sslFactoryInstance)
+ sslFactoryInstance = new (ys) sslFactory;
+ return *sslFactoryInstance;
+}
+
+
+void CleanUp()
+{
+ TaoCrypt::CleanUp();
+ ysDelete(sslFactoryInstance);
+ ysDelete(sessionsInstance);
}
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index 76034c3ae8f..d3bd731e2bd 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -275,8 +275,6 @@ private:
AlignedWordBlock reg_;
Sign sign_;
- static const Integer zero_;
- static const Integer one_;
};
inline bool operator==(const Integer& a, const Integer& b)
diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp
index f705cc99970..26383d4c96b 100644
--- a/extra/yassl/taocrypt/include/misc.hpp
+++ b/extra/yassl/taocrypt/include/misc.hpp
@@ -34,6 +34,11 @@
namespace TaoCrypt {
+
+// Delete static singleton holders
+void CleanUp();
+
+
// library allocation
struct new_t {}; // TaoCrypt New type
extern new_t tc; // pass in parameter
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index 254e67a7f64..d9d7877bd93 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -25,11 +25,27 @@
-#if !defined(yaSSL_NEW_HPP) && defined(__GNUC__)
-#if !(defined(__ICC) || defined(__INTEL_COMPILER))
-
+#ifndef yaSSL_NEW_HPP
#define yaSSL_NEW_HPP
+
+#ifdef __sun
+
+#include <assert.h>
+
+// Handler for pure virtual functions
+namespace __Crun {
+ static void pure_error(void)
+ {
+ assert("Pure virtual method called." == "Aborted");
+ }
+} // namespace __Crun
+
+#endif // __sun
+
+
+#if defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
+
#if __GNUC__ > 2
extern "C" {
@@ -47,6 +63,6 @@ static int __cxa_pure_virtual()
} // extern "C"
#endif // __GNUC__ > 2
-#endif // ! _ICC
-#endif // yaSSL_NEW_HPP && __GNUC__
+#endif // compiler check
+#endif // yaSSL_NEW_HPP
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index 45bbcfa662a..8f4ce051a43 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -76,7 +76,9 @@ const Integer& AbstractEuclideanDomain::Mod(const Element &a,
const Integer& AbstractEuclideanDomain::Gcd(const Element &a,
const Element &b) const
{
- Element g[3]={b, a};
+ mySTL::vector<Element> g(3);
+ g[0]= b;
+ g[1]= a;
unsigned int i0=0, i1=1, i2=2;
while (!Equal(g[i1], this->Identity()))
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 71324b04b92..4ade5491530 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -2709,19 +2709,32 @@ unsigned int Integer::Encode(byte* output, unsigned int outputLen,
}
-const Integer Integer::zero_;
+static Integer* zero = 0;
const Integer &Integer::Zero()
{
- return zero_;
+ if (!zero)
+ zero = new (tc) Integer;
+ return *zero;
}
-const Integer Integer::one_(1,2);
+static Integer* one = 0;
const Integer &Integer::One()
{
- return one_;
+ if (!one)
+ one = new (tc) Integer(1,2);
+ return *one;
+}
+
+
+// Clean up static singleton holders, not a leak, but helpful to have gone
+// when checking for leaks
+void CleanUp()
+{
+ tcDelete(one);
+ tcDelete(zero);
}
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 9a3c12badfc..59814d03209 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -41,6 +41,7 @@ template class RSA_Decryptor<RSA_BlockType2>;
template class RSA_Encryptor<RSA_BlockType1>;
template class RSA_Encryptor<RSA_BlockType2>;
template void tcDelete<HASH>(HASH*);
+template void tcDelete<Integer>(Integer*);
template void tcArrayDelete<byte>(byte*);
template AllocatorWithCleanup<byte>::pointer StdReallocate<byte, AllocatorWithCleanup<byte> >(AllocatorWithCleanup<byte>&, byte*, AllocatorWithCleanup<byte>::size_type, AllocatorWithCleanup<byte>::size_type, bool);
template void tcArrayDelete<word>(word*);
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 653addd9ede..bad8886d0be 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1249,15 +1249,13 @@ dict_table_remove_from_cache(
/* Remove table from LRU list of tables */
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
- mutex_free(&(table->autoinc_mutex));
-
size = mem_heap_get_size(table->heap);
ut_ad(dict_sys->size >= size);
dict_sys->size -= size;
- mem_heap_free(table->heap);
+ dict_mem_table_free(table);
}
/**************************************************************************
@@ -1378,6 +1376,38 @@ dict_col_reposition_in_cache(
HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
}
+/********************************************************************
+If the given column name is reserved for InnoDB system columns, return
+TRUE. */
+
+ibool
+dict_col_name_is_reserved(
+/*======================*/
+ /* out: TRUE if name is reserved */
+ const char* name) /* in: column name */
+{
+ /* This check reminds that if a new system column is added to
+ the program, it should be dealt with here. */
+#if DATA_N_SYS_COLS != 4
+#error "DATA_N_SYS_COLS != 4"
+#endif
+
+ static const char* reserved_names[] = {
+ "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
+ };
+
+ ulint i;
+
+ for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
+ if (strcmp(name, reserved_names[i]) == 0) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
/**************************************************************************
Adds an index to the dictionary cache. */
@@ -1551,7 +1581,7 @@ dict_index_remove_from_cache(
dict_sys->size -= size;
- mem_heap_free(index->heap);
+ dict_mem_index_free(index);
}
/***********************************************************************
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 6415cc56b61..bd93a719f6c 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -767,7 +767,7 @@ dict_load_table(
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) {
/* Not found */
-
+ err_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
mem_heap_free(heap);
@@ -779,11 +779,8 @@ dict_load_table(
/* Check if the table name in record is the searched one */
if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) {
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
- mem_heap_free(heap);
-
- return(NULL);
+
+ goto err_exit;
}
ut_a(0 == ut_strcmp("SPACE",
@@ -844,6 +841,14 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 5, &len);
table->type = mach_read_from_4(field);
+ if (UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: table %s: unknown table type %lu\n",
+ name, (ulong) table->type);
+ goto err_exit;
+ }
+
if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
ut_error;
#if 0 /* clustered tables have not been implemented yet */
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index eec35310039..98ef44a4969 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -97,6 +97,21 @@ dict_mem_table_create(
return(table);
}
+/********************************************************************
+Free a table memory object. */
+
+void
+dict_mem_table_free(
+/*================*/
+ dict_table_t* table) /* in: table */
+{
+ ut_ad(table);
+ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+ mutex_free(&(table->autoinc_mutex));
+ mem_heap_free(table->heap);
+}
+
/**************************************************************************
Creates a cluster memory object. */
@@ -290,5 +305,8 @@ dict_mem_index_free(
/*================*/
dict_index_t* index) /* in: index */
{
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
mem_heap_free(index->heap);
}
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index d7fa48b6e66..e4694ed52ae 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -1160,9 +1160,9 @@ ibuf_dummy_index_free(
dict_index_t* index) /* in: dummy index */
{
dict_table_t* table = index->table;
- mem_heap_free(index->heap);
- mutex_free(&(table->autoinc_mutex));
- mem_heap_free(table->heap);
+
+ dict_mem_index_free(index);
+ dict_mem_table_free(table);
}
/*************************************************************************
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 4396611e529..642037494b5 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -98,6 +98,15 @@ ulint
dict_col_get_clust_pos(
/*===================*/
dict_col_t* col);
+/********************************************************************
+If the given column name is reserved for InnoDB system columns, return
+TRUE. */
+
+ibool
+dict_col_name_is_reserved(
+/*======================*/
+ /* out: TRUE if name is reserved */
+ const char* name); /* in: column name */
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already
initialized counter. */
diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h
index 7eec86d0bcb..3c10e82342b 100644
--- a/innobase/include/dict0mem.h
+++ b/innobase/include/dict0mem.h
@@ -56,6 +56,13 @@ dict_mem_table_create(
a member of a cluster */
ulint n_cols, /* in: number of columns */
ibool comp); /* in: TRUE=compact page format */
+/********************************************************************
+Free a table memory object. */
+
+void
+dict_mem_table_free(
+/*================*/
+ dict_table_t* table); /* in: table */
/**************************************************************************
Creates a cluster memory object. */
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index 04b254a8221..bc3bd031f0c 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -261,6 +261,9 @@ it is read or written. */
/* Tell the compiler that cond is unlikely to hold */
#define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
+/* Compile-time constant of the given array's size. */
+#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
#include <stdio.h>
#include "ut0dbg.h"
#include "ut0ut.h"
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index 42e854398ba..7c56fe35d48 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -890,9 +890,9 @@ recv_parse_or_apply_log_rec_body(
ut_ad(!page || ptr);
if (index) {
dict_table_t* table = index->table;
- mem_heap_free(index->heap);
- mutex_free(&(table->autoinc_mutex));
- mem_heap_free(table->heap);
+
+ dict_mem_index_free(index);
+ dict_mem_table_free(table);
}
return(ptr);
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 937056c300e..89b82882d93 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1673,7 +1673,9 @@ row_mysql_recover_tmp_table(
if (!ptr) {
/* table name does not begin with "/rsql" */
+ dict_mem_table_free(table);
trx_commit_for_mysql(trx);
+
return(DB_ERROR);
}
else {
@@ -1785,6 +1787,7 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
+ ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
@@ -1802,6 +1805,7 @@ row_create_table_for_mysql(
"InnoDB: with raw, and innodb_force_... is removed.\n",
stderr);
+ dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
@@ -1816,11 +1820,25 @@ row_create_table_for_mysql(
"InnoDB: MySQL system tables must be of the MyISAM type!\n",
table->name);
+ dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
}
+ /* Check that no reserved column names are used. */
+ for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
+ dict_col_t* col = dict_table_get_nth_col(table, i);
+
+ if (dict_col_name_is_reserved(col->name)) {
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ return(DB_ERROR);
+ }
+ }
+
trx_start_if_not_started(trx);
if (row_mysql_is_recovered_tmp_table(table->name)) {
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index a045441e046..ea0e11a69d9 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1457,7 +1457,8 @@ sub ndbcluster_start ($) {
# FIXME, we want to _append_ output to file $file_ndb_testrun_log instead of /dev/null
if ( mtr_run("$glob_mysql_test_dir/ndb/ndbcluster",
["--port=$opt_ndbcluster_port",
- "--data-dir=$opt_vardir"],
+ "--data-dir=$opt_vardir",
+ "--character-sets-dir=$path_charsetsdir"],
"", "/dev/null", "", "") )
{
mtr_error("Error ndbcluster_start");
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index d7e976f9d49..c41344548f5 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -631,7 +631,9 @@ fi
[ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp
[ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run
[ -d $MYSQL_TEST_DIR/var/log ] || mkdir $MYSQL_TEST_DIR/var/log
-if ! test -L $MYSQL_TEST_DIR/var/std_data_ln ; then
+
+# Use 'test', not '[' as the shell builtin might not have '-L
+if test ! -L "$MYSQL_TEST_DIR/var/std_data_ln" ; then
ln -s $MYSQL_TEST_DIR/std_data/ $MYSQL_TEST_DIR/var/std_data_ln
fi
@@ -1241,7 +1243,7 @@ start_ndbcluster()
else
NDBCLUSTER_EXTRA_OPTS="--small"
fi
- ./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --initial || NDB_STATUS_OK=0
+ ./ndb/ndbcluster $NDBCLUSTER_OPTS --character-sets-dir=$CHARSETSDIR $NDBCLUSTER_EXTRA_OPTS --initial || NDB_STATUS_OK=0
if [ x$NDB_STATUS_OK != x1 ] ; then
if [ x$FORCE != x1 ] ; then
exit 1
diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh
index c09c013552e..ad01f6574cf 100644
--- a/mysql-test/ndb/ndbcluster.sh
+++ b/mysql-test/ndb/ndbcluster.sh
@@ -60,6 +60,7 @@ ndb_imem=24M
NDB_MGM_EXTRA_OPTS=
NDB_MGMD_EXTRA_OPTS=
NDBD_EXTRA_OPTS=
+CHARSETSDIR=
while test $# -gt 0; do
case "$1" in
@@ -106,6 +107,9 @@ while test $# -gt 0; do
--ndbd-extra-opts=*)
NDBD_EXTRA_OPTS=`echo "$1" | sed -e "s;--ndbd-extra-opts=;;"`
;;
+ --character-sets-dir=*)
+ CHARSETSDIR=`echo "$1" | sed -e "s;--character-sets-dir=;;"`
+ ;;
-- ) shift; break ;;
--* ) $ECHO "Unrecognized option: $1"; exit 1 ;;
* ) break ;;
@@ -135,7 +139,7 @@ fi
exec_mgmtclient="$exec_mgmtclient --no-defaults $NDB_MGM_EXTRA_OPTS"
exec_mgmtsrvr="$exec_mgmtsrvr --no-defaults $NDB_MGMD_EXTRA_OPTS"
-exec_ndb="$exec_ndb --no-defaults $NDBD_EXTRA_OPTS"
+exec_ndb="$exec_ndb --no-defaults $NDBD_EXTRA_OPTS --character-sets-dir=$CHARSETSDIR"
exec_waiter="$exec_waiter --no-defaults"
ndb_host="localhost"
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 7889f8953f4..d8a539da3fe 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -611,6 +611,16 @@ count(distinct (f1+1))
1
3
drop table t1;
+create table t1 (f1 int unsigned, f2 varchar(255));
+insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
+select f2,group_concat(f1) from t1 group by f2;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 t1 f2 f2 253 255 255 Y 0 0 8
+def group_concat(f1) 253 400 1 Y 128 0 63
+f2 group_concat(f1)
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2
+drop table t1;
set names latin1;
create table t1 (a char, b char);
insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b');
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 911d6eea033..aed79e7f8fa 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1030,3 +1030,13 @@ c res
y,abc abc
y,abc abc
drop table t1;
+select cast(rtrim(' 20.06 ') as decimal(19,2));
+cast(rtrim(' 20.06 ') as decimal(19,2))
+20.06
+select cast(ltrim(' 20.06 ') as decimal(19,2));
+cast(ltrim(' 20.06 ') as decimal(19,2))
+20.06
+select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
+cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2))
+20.06
+End of 5.0 tests
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 75e41e7a94f..d32cd405ce8 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -3241,6 +3241,8 @@ where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
a a
2005-10-01 2005-10-01
drop table t1, t2;
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+ERROR HY000: Can't create table './test/t1.frm' (errno: -1)
CREATE TABLE t1 (
a BIGINT(20) NOT NULL,
PRIMARY KEY (a)
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index de9a2b2c003..99f5277f817 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -289,6 +289,48 @@ check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY);
+SET GLOBAL key_cache_block_size=1536;
+INSERT INTO t1 VALUES (1);
+SELECT @@key_cache_block_size;
+@@key_cache_block_size
+1536
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
+CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
+SET GLOBAL key_cache_block_size=1536;
+INSERT INTO t1 VALUES (1,0);
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+4181
+SELECT @@key_cache_block_size;
+@@key_cache_block_size
+1536
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1,t2;
set @@global.key_buffer_size=0;
Warnings:
Warning 1438 Cannot drop default keycache
diff --git a/mysql-test/r/ndb_bitfield.result b/mysql-test/r/ndb_bitfield.result
index 9a941862854..389e19f2893 100644
--- a/mysql-test/r/ndb_bitfield.result
+++ b/mysql-test/r/ndb_bitfield.result
@@ -201,13 +201,13 @@ create table t1 (
pk1 bit(9) not null primary key,
b int
) engine=ndbcluster;
-ERROR HY000: Can't create table './test/t1.frm' (errno: 739)
+ERROR HY000: Can't create table './test/t1.frm' (errno: 906)
create table t1 (
pk1 int not null primary key,
b bit(9),
key(b)
) engine=ndbcluster;
-ERROR HY000: Can't create table './test/t1.frm' (errno: 743)
+ERROR HY000: Can't create table './test/t1.frm' (errno: 906)
create table t1 (
pk1 int primary key,
b bit(32) not null
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 6864c35dbfc..a36935a583d 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -820,3 +820,35 @@ a
2
2
DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
+(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a;
+b a
+10 1
+10 2
+20 1
+20 2
+30 1
+30 2
+(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC;
+b
+10
+10
+20
+20
+30
+30
+(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b;
+b a
+10 1
+20 1
+30 1
+10 2
+20 2
+30 2
+(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b;
+b a
+10 1
+20 1
+10 2
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_deadlock.result b/mysql-test/r/rpl_deadlock.result
index c25cb1e6a53..541e12b806f 100644
--- a/mysql-test/r/rpl_deadlock.result
+++ b/mysql-test/r/rpl_deadlock.result
@@ -44,8 +44,39 @@ select * from t2;
a
22
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 Yes Yes 0 0 18911 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 18911
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running Yes
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 18911
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
stop slave;
change master to master_log_pos=532;
begin;
@@ -62,8 +93,39 @@ select * from t2;
a
22
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 Yes Yes 0 0 18911 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 18911
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+Slave_SQL_Running Yes
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 18911
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
set global max_relay_log_size=0;
stop slave;
change master to master_log_pos=532;
@@ -82,6 +144,37 @@ select * from t2;
a
22
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 # Yes 0 0 18911 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 18911
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+Slave_SQL_Running Yes
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 18911
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
drop table t1,t2,t3,t4;
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index aa28c9d5f52..fbfdfa3b5d0 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -397,6 +397,17 @@ insert into t1 values(1),(2),(3);
select f1, group_concat(f1+1) from t1 group by f1 with rollup;
select count(distinct (f1+1)) from t1 group by f1 with rollup;
drop table t1;
+
+#
+# Bug#14169 type of group_concat() result changed to blob if tmp_table was used
+#
+create table t1 (f1 int unsigned, f2 varchar(255));
+insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
+--enable_metadata
+select f2,group_concat(f1) from t1 group by f2;
+--disable_metadata
+drop table t1;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index ef20d766bce..85cedee0f4a 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -684,4 +684,11 @@ insert into t1 values ('y,abc'),('y,abc');
select c, substring_index(lcase(c), @q:=',', -1) as res from t1;
drop table t1;
-# End of 5.0 tests
+#
+# Bug #17043: Casting trimmed string to decimal loses precision
+#
+select cast(rtrim(' 20.06 ') as decimal(19,2));
+select cast(ltrim(' 20.06 ') as decimal(19,2));
+select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index fe5da58d4e7..fea4890286c 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -2133,13 +2133,17 @@ disconnect b;
#
create table t1(a date) engine=innodb;
-create table t2(a date, key(a)) engine=innodb;
+create table t2(a date, key(a)) engine=innodb;
insert into t1 values('2005-10-01');
insert into t2 values('2005-10-01');
select * from t1, t2
where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
drop table t1, t2;
+# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
+--error 1005
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+
#
# Bug #17152: Wrong result with BINARY comparison on aliased column
#
diff --git a/mysql-test/t/innodb_unsafe_binlog-master.opt b/mysql-test/t/innodb_unsafe_binlog-master.opt
index 503c8457b2c..5c0136b5db3 100644
--- a/mysql-test/t/innodb_unsafe_binlog-master.opt
+++ b/mysql-test/t/innodb_unsafe_binlog-master.opt
@@ -1 +1 @@
---innodb_locks_unsafe_for_binlog=true
+--loose-innodb_locks_unsafe_for_binlog=true
diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test
index df584021af1..4001e0df4af 100644
--- a/mysql-test/t/key_cache.test
+++ b/mysql-test/t/key_cache.test
@@ -149,6 +149,7 @@ show status like 'key_blocks_used';
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
show status like 'key_blocks_unused';
+
# Cleanup
# We don't reset keycache2 as we want to ensure that mysqld will reset it
set global keycache2.key_buffer_size=0;
@@ -157,7 +158,7 @@ set global keycache2.key_buffer_size=0;
set global keycache3.key_buffer_size=100;
set global keycache3.key_buffer_size=0;
-# Test case for buf 6447
+# Test case for bug 6447
create table t1 (mytext text, FULLTEXT (mytext));
insert t1 values ('aaabbb');
@@ -169,6 +170,44 @@ check table t1;
drop table t1;
#
+# Bug #19079: corrupted index when key_cache_block_size is not multiple of
+# myisam_block_size
+
+CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY);
+SET GLOBAL key_cache_block_size=1536;
+INSERT INTO t1 VALUES (1);
+SELECT @@key_cache_block_size;
+CHECK TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
+CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
+SET GLOBAL key_cache_block_size=1536;
+INSERT INTO t1 VALUES (1,0);
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+INSERT INTO t2(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t2;
+SELECT COUNT(*) FROM t1;
+SELECT @@key_cache_block_size;
+CHECK TABLE t1;
+DROP TABLE t1,t2;
+
+#
# Bug#10473 - Can't set 'key_buffer_size' system variable to ZERO
# (One cannot drop the default key cache.)
#
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index b1807579b20..98e542dac95 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -563,4 +563,18 @@ SELECT a FROM t1 ORDER BY a;
(SELECT a FROM t1) ORDER BY a;
DROP TABLE t1;
+#
+# Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was
+# ignored or 'concatened' to the latter.
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
+
+(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a;
+(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC;
+(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b;
+(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b;
+
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_deadlock.test b/mysql-test/t/rpl_deadlock.test
index c74ed989ece..684cb54611c 100644
--- a/mysql-test/t/rpl_deadlock.test
+++ b/mysql-test/t/rpl_deadlock.test
@@ -67,7 +67,9 @@ select * from t2;
# check that no error is reported
--replace_column 1 # 8 # 9 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
+--vertical_results
show slave status;
+--horizontal_results
# 2) Test lock wait timeout
@@ -82,9 +84,11 @@ sync_with_master;
select * from t1; # check that slave succeeded finally
select * from t2;
# check that no error is reported
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 11 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
+--vertical_results
show slave status;
+--horizontal_results
# Now we repeat 2), but with BEGIN in the same relay log as
# COMMIT (to see if seeking into hot log is ok).
@@ -104,7 +108,9 @@ select * from t1;
select * from t2;
--replace_column 1 # 8 # 9 # 11 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
+--vertical_results
show slave status;
+--horizontal_results
connection master;
drop table t1,t2,t3,t4;
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 3b5e277b56d..11e27bb19ad 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -1805,6 +1805,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
uint status;
int page_st;
+ offset= (uint) (filepos & (keycache->key_cache_block_size-1));
/* Read data in key_cache_block_size increments */
do
{
@@ -1814,7 +1815,6 @@ byte *key_cache_read(KEY_CACHE *keycache,
keycache_pthread_mutex_unlock(&keycache->cache_lock);
goto no_key_cache;
}
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
filepos-= offset;
read_length= length;
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
@@ -1890,6 +1890,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
#endif
buff+= read_length;
filepos+= read_length+offset;
+ offset= 0;
} while ((length-= read_length));
DBUG_RETURN(start);
@@ -1941,17 +1942,17 @@ int key_cache_insert(KEY_CACHE *keycache,
uint read_length;
int page_st;
int error;
+ uint offset;
+ offset= (uint) (filepos & (keycache->key_cache_block_size-1));
do
{
- uint offset;
keycache_pthread_mutex_lock(&keycache->cache_lock);
if (!keycache->can_be_used)
{
keycache_pthread_mutex_unlock(&keycache->cache_lock);
DBUG_RETURN(0);
}
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
/* Read data into key cache from buff in key_cache_block_size incr. */
filepos-= offset;
read_length= length;
@@ -2009,6 +2010,7 @@ int key_cache_insert(KEY_CACHE *keycache,
buff+= read_length;
filepos+= read_length+offset;
+ offset= 0;
} while ((length-= read_length));
}
@@ -2075,17 +2077,17 @@ int key_cache_write(KEY_CACHE *keycache,
/* Key cache is used */
uint read_length;
int page_st;
+ uint offset;
+ offset= (uint) (filepos & (keycache->key_cache_block_size-1));
do
{
- uint offset;
keycache_pthread_mutex_lock(&keycache->cache_lock);
if (!keycache->can_be_used)
{
keycache_pthread_mutex_unlock(&keycache->cache_lock);
goto no_key_cache;
}
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
/* Write data in key_cache_block_size increments */
filepos-= offset;
read_length= length;
diff --git a/ndb/include/kernel/signaldata/TupFrag.hpp b/ndb/include/kernel/signaldata/TupFrag.hpp
index 8acb3d28bd6..5fb9d7bcf42 100644
--- a/ndb/include/kernel/signaldata/TupFrag.hpp
+++ b/ndb/include/kernel/signaldata/TupFrag.hpp
@@ -146,7 +146,8 @@ public:
enum ErrorCode {
NoError = 0,
InvalidCharset = 743,
- TooManyBitsUsed = 831
+ TooManyBitsUsed = 831,
+ UnsupportedType = 906
};
private:
Uint32 userPtr;
diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp
index 3e98dcd1805..36a75136c45 100644
--- a/ndb/include/util/NdbSqlUtil.hpp
+++ b/ndb/include/util/NdbSqlUtil.hpp
@@ -117,9 +117,9 @@ public:
/**
* Check character set.
*/
- static bool usable_in_pk(Uint32 typeId, const void* info);
- static bool usable_in_hash_index(Uint32 typeId, const void* info);
- static bool usable_in_ordered_index(Uint32 typeId, const void* info);
+ static uint check_column_for_pk(Uint32 typeId, const void* info);
+ static uint check_column_for_hash_index(Uint32 typeId, const void* info);
+ static uint check_column_for_ordered_index(Uint32 typeId, const void* info);
/**
* Get number of length bytes and length from variable length string.
diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h
index 787c32f06fd..08ab4a2e9df 100644
--- a/ndb/include/util/ndb_opts.h
+++ b/ndb/include/util/ndb_opts.h
@@ -84,7 +84,10 @@ const char *opt_debug= 0;
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\
{ "core-file", OPT_WANT_CORE, "Write core on errors.",\
(gptr*) &opt_core, (gptr*) &opt_core, 0,\
- GET_BOOL, NO_ARG, OPT_WANT_CORE_DEFAULT, 0, 0, 0, 0, 0}
+ GET_BOOL, NO_ARG, OPT_WANT_CORE_DEFAULT, 0, 0, 0, 0, 0},\
+ {"character-sets-dir", OPT_CHARSETS_DIR,\
+ "Directory where character sets are.", (gptr*) &charsets_dir,\
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}\
#ifndef DBUG_OFF
#define NDB_STD_OPTS(prog_name) \
@@ -111,6 +114,7 @@ enum ndb_std_options {
OPT_WANT_CORE,
OPT_NDB_MGMD,
OPT_NDB_NODEID,
+ OPT_CHARSETS_DIR,
NDB_STD_OPTIONS_LAST /* should always be last in this enum */
};
diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp
index 09e150dbacf..f2506eda6d4 100644
--- a/ndb/src/common/util/NdbSqlUtil.cpp
+++ b/ndb/src/common/util/NdbSqlUtil.cpp
@@ -872,8 +872,8 @@ NdbSqlUtil::likeLongvarbinary(const void* info, const void* p1, unsigned n1, con
// check charset
-bool
-NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
+uint
+NdbSqlUtil::check_column_for_pk(Uint32 typeId, const void* info)
{
const Type& type = getType(typeId);
switch (type.m_typeId) {
@@ -882,12 +882,14 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
case Type::Longvarchar:
{
const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
- return
- cs != 0 &&
- cs->cset != 0 &&
- cs->coll != 0 &&
- cs->coll->strnxfrm != 0 &&
- cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY;
+ if(cs != 0 &&
+ cs->cset != 0 &&
+ cs->coll != 0 &&
+ cs->coll->strnxfrm != 0 &&
+ cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
+ return 0;
+ else
+ return 743;
}
break;
case Type::Undefined:
@@ -896,19 +898,19 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
case Type::Bit:
break;
default:
- return true;
+ return 0;
}
- return false;
+ return 906;
}
-bool
-NdbSqlUtil::usable_in_hash_index(Uint32 typeId, const void* info)
+uint
+NdbSqlUtil::check_column_for_hash_index(Uint32 typeId, const void* info)
{
- return usable_in_pk(typeId, info);
+ return check_column_for_pk(typeId, info);
}
-bool
-NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
+uint
+NdbSqlUtil::check_column_for_ordered_index(Uint32 typeId, const void* info)
{
const Type& type = getType(typeId);
if (type.m_cmp == NULL)
@@ -919,13 +921,15 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
case Type::Longvarchar:
{
const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
- return
- cs != 0 &&
- cs->cset != 0 &&
- cs->coll != 0 &&
- cs->coll->strnxfrm != 0 &&
- cs->coll->strnncollsp != 0 &&
- cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY;
+ if (cs != 0 &&
+ cs->cset != 0 &&
+ cs->coll != 0 &&
+ cs->coll->strnxfrm != 0 &&
+ cs->coll->strnncollsp != 0 &&
+ cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
+ return 0;
+ else
+ return 743;
}
break;
case Type::Undefined:
@@ -934,9 +938,9 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
case Type::Bit: // can be fixed
break;
default:
- return true;
+ return 0;
}
- return false;
+ return 906;
}
// utilities
diff --git a/ndb/src/kernel/SimBlockList.cpp b/ndb/src/kernel/SimBlockList.cpp
index 6029fc7e225..271d515dc92 100644
--- a/ndb/src/kernel/SimBlockList.cpp
+++ b/ndb/src/kernel/SimBlockList.cpp
@@ -111,8 +111,12 @@ SimBlockList::unload(){
if(theList != 0){
for(int i = 0; i<noOfBlocks; i++){
if(theList[i] != 0){
+#ifdef VM_TRACE
theList[i]->~SimulatedBlock();
free(theList[i]);
+#else
+ delete(theList[i]);
+#endif
theList[i] = 0;
}
}
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
index 93c4a583624..c85c8384081 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
@@ -217,11 +217,12 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
break;
}
if (descAttr.m_charset != 0) {
+ uint err;
CHARSET_INFO *cs = all_charsets[descAttr.m_charset];
ndbrequire(cs != 0);
- if (! NdbSqlUtil::usable_in_ordered_index(descAttr.m_typeId, cs)) {
+ if ((err = NdbSqlUtil::check_column_for_ordered_index(descAttr.m_typeId, cs))) {
jam();
- errorCode = TuxAddAttrRef::InvalidCharset;
+ errorCode = (TuxAddAttrRef::ErrorCode) err;
break;
}
}
diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
index 564501526a8..08251348b2b 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
@@ -25,7 +25,10 @@
void Ndbcntr::initData()
{
-
+ c_start.reset();
+ cmasterNodeId = 0;
+ cnoStartNodes = 0;
+ cnoWaitrep = 0;
// Records with constant sizes
ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC];
}//Ndbcntr::initData()
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index f7a28eb989c..6cb8e1f9a24 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -1573,7 +1573,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
bool alter)
{
DBUG_ENTER("NdbDictInterface::createOrAlterTable");
- unsigned i;
+ unsigned i, err;
if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){
m_error.code= 4317;
DBUG_RETURN(-1);
@@ -1683,8 +1683,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
DBUG_RETURN(-1);
}
// primary key type check
- if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) {
- m_error.code= (col->m_cs != 0 ? 743 : 739);
+ if (col->m_pk &&
+ (err = NdbSqlUtil::check_column_for_pk(col->m_type, col->m_cs)))
+ {
+ m_error.code= err;
DBUG_RETURN(-1);
}
// distribution key not supported for Char attribute
@@ -2157,7 +2159,7 @@ NdbDictInterface::createIndex(Ndb & ndb,
{
//validate();
//aggregate();
- unsigned i;
+ unsigned i, err;
UtilBufferWriter w(m_buffer);
const size_t len = strlen(impl.m_externalName.c_str()) + 1;
if(len > MAX_TAB_NAME_SIZE) {
@@ -2208,10 +2210,12 @@ NdbDictInterface::createIndex(Ndb & ndb,
// index key type check
if (it == DictTabInfo::UniqueHashIndex &&
- ! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) ||
+ (err = NdbSqlUtil::check_column_for_hash_index(col->m_type, col->m_cs))
+ ||
it == DictTabInfo::OrderedIndex &&
- ! NdbSqlUtil::usable_in_ordered_index(col->m_type, col->m_cs)) {
- m_error.code = 743;
+ (err = NdbSqlUtil::check_column_for_ordered_index(col->m_type, col->m_cs)))
+ {
+ m_error.code = err;
return -1;
}
attributeList.id[i] = col->m_attrId;
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 9f8a2916d2f..869704c7bb3 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -1086,6 +1086,11 @@ int
NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
int type, const void* aValue, Uint32 len)
{
+ if (!tAttrInfo)
+ {
+ setErrorCodeAbort(4318); // Invalid attribute
+ return -1;
+ }
if (theOperationType == OpenRangeScanRequest &&
(0 <= type && type <= 4) &&
len <= 8000) {
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a3e47154bc3..60183ac9b5a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -80,6 +80,20 @@ String *Item_str_func::check_well_formed_result(String *str)
}
+my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value)
+{
+ DBUG_ASSERT(fixed == 1);
+ char buff[64];
+ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
+ res= val_str(&tmp);
+ if (!res)
+ return 0;
+ (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
+ res->length(), res->charset(), decimal_value);
+ return decimal_value;
+}
+
+
double Item_str_func::val_real()
{
DBUG_ASSERT(fixed == 1);
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 6a95a9e5d1f..7d7b62df0dc 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -33,6 +33,7 @@ public:
Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; }
longlong val_int();
double val_real();
+ my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length();
String *check_well_formed_result(String *str);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 8826144266e..962454e237e 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -377,12 +377,12 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
case INT_RESULT:
return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag);
case STRING_RESULT:
- if (max_length > 255 && convert_blob_length)
+ if (max_length/collation.collation->mbmaxlen > 255 && convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null,
name, table,
collation.collation);
return make_string_field(table);
- case DECIMAL_RESULT:
+case DECIMAL_RESULT:
return new Field_new_decimal(max_length, maybe_null, name, table,
decimals, unsigned_flag);
case ROW_RESULT:
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 328f8dd8400..f4ff257aa4e 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1121,7 +1121,7 @@ public:
virtual Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const
{
- if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
+ if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
return FIELD_TYPE_BLOB;
else
return MYSQL_TYPE_VARCHAR;
diff --git a/sql/lock.cc b/sql/lock.cc
index a584b063a0b..8ea13b2117c 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -78,6 +78,7 @@ extern HASH open_cache;
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
uint flags, TABLE **write_locked);
+static void reset_lock_data(MYSQL_LOCK *sql_lock);
static int lock_external(THD *thd, TABLE **table,uint count);
static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error, const char *);
@@ -135,12 +136,16 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
*/
if (wait_if_global_read_lock(thd, 1, 1))
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
- }
+ }
if (thd->version != refresh_version)
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
goto retry;
}
@@ -149,6 +154,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->proc_info="System lock";
if (lock_external(thd, tables, count))
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
@@ -699,7 +706,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*write_lock_used=table;
if (table->db_stat & HA_READ_ONLY)
{
- my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias);
+ my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias);
+ /* Clear the lock type of the lock data that are stored already. */
+ sql_lock->lock_count= locks - sql_lock->locks;
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
DBUG_RETURN(0);
}
@@ -724,6 +734,48 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
}
+/*
+ Reset lock type in lock data.
+
+ SYNOPSIS
+ reset_lock_data()
+ sql_lock The MySQL lock.
+
+ DESCRIPTION
+
+ After a locking error we want to quit the locking of the table(s).
+ The test case in the bug report for Bug #18544 has the following
+ cases: 1. Locking error in lock_external() due to InnoDB timeout.
+ 2. Locking error in get_lock_data() due to missing write permission.
+ 3. Locking error in wait_if_global_read_lock() due to lock conflict.
+
+ In all these cases we have already set the lock type into the lock
+ data of the open table(s). If the table(s) are in the open table
+ cache, they could be reused with the non-zero lock type set. This
+ could lead to ignoring a different lock type with the next lock.
+
+ Clear the lock type of all lock data. This ensures that the next
+ lock request will set its lock type properly.
+
+ RETURN
+ void
+*/
+
+static void reset_lock_data(MYSQL_LOCK *sql_lock)
+{
+ THR_LOCK_DATA **ldata;
+ THR_LOCK_DATA **ldata_end;
+
+ for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count;
+ ldata < ldata_end;
+ ldata++)
+ {
+ /* Reset lock type. */
+ (*ldata)->type= TL_UNLOCK;
+ }
+}
+
+
/*****************************************************************************
Lock table based on the name.
This is used when we need total access to a closed, not open table
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 8512c075f69..34e7ee969b6 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -454,6 +454,7 @@ public:
void print(String *str);
+ bool add_fake_select_lex(THD *thd);
void init_prepare_fake_select_lex(THD *thd);
inline bool is_prepared() { return prepared; }
bool change_result(select_subselect *result, select_subselect *old_result);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 38eadb5a738..c58628cd856 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5544,48 +5544,17 @@ mysql_new_select(LEX *lex, bool move_down)
}
else
{
- Name_resolution_context *outer_context;
if (lex->current_select->order_list.first && !lex->current_select->braces)
{
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
DBUG_RETURN(1);
}
select_lex->include_neighbour(lex->current_select);
- /*
- we are not sure that we have one level of SELECTs above, so we take
- outer_context address from first select of unit
- */
- outer_context=
- select_lex->master_unit()->first_select()->context.outer_context;
- SELECT_LEX_UNIT *unit= select_lex->master_unit();
- SELECT_LEX *fake= unit->fake_select_lex;
- if (!fake)
- {
- /*
- as far as we included SELECT_LEX for UNION unit should have
- fake SELECT_LEX for UNION processing
- */
- if (!(fake= unit->fake_select_lex= new (thd->mem_root) SELECT_LEX()))
- DBUG_RETURN(1);
- fake->include_standalone(unit,
- (SELECT_LEX_NODE**)&unit->fake_select_lex);
- fake->select_number= INT_MAX;
- fake->parent_lex= lex; /* Used in init_query. */
- fake->make_empty_select();
- fake->linkage= GLOBAL_OPTIONS_TYPE;
- fake->select_limit= 0;
-
- fake->context.outer_context= outer_context;
- /* allow item list resolving in fake select for ORDER BY */
- fake->context.resolve_in_select_list= TRUE;
- fake->context.select_lex= fake;
- /*
- Remove the name resolution context of the fake select from the
- context stack.
- */
- lex->pop_context();
- }
- select_lex->context.outer_context= outer_context;
+ SELECT_LEX_UNIT *unit= select_lex->master_unit();
+ if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
+ DBUG_RETURN(1);
+ select_lex->context.outer_context=
+ unit->first_select()->context.outer_context;
}
select_lex->master_unit()->global_parameters= select_lex;
@@ -6358,6 +6327,68 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
/*
+ Create a fake SELECT_LEX for a unit
+
+ SYNOPSIS:
+ add_fake_select_lex()
+ thd thread handle
+
+ DESCRIPTION
+ The method create a fake SELECT_LEX object for a unit.
+ This object is created for any union construct containing a union
+ operation and also for any single select union construct of the form
+ (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
+ or of the form
+ (SELECT ... ORDER BY LIMIT n) ORDER BY ...
+
+ NOTES
+ The object is used to retrieve rows from the temporary table
+ where the result on the union is obtained.
+
+ RETURN VALUES
+ 1 on failure to create the object
+ 0 on success
+*/
+
+bool st_select_lex_unit::add_fake_select_lex(THD *thd)
+{
+ SELECT_LEX *first_sl= first_select();
+ DBUG_ENTER("add_fake_select_lex");
+ DBUG_ASSERT(!fake_select_lex);
+
+ if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
+ DBUG_RETURN(1);
+ fake_select_lex->include_standalone(this,
+ (SELECT_LEX_NODE**)&fake_select_lex);
+ fake_select_lex->select_number= INT_MAX;
+ fake_select_lex->parent_lex= thd->lex; /* Used in init_query. */
+ fake_select_lex->make_empty_select();
+ fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
+ fake_select_lex->select_limit= 0;
+
+ fake_select_lex->context.outer_context=first_sl->context.outer_context;
+ /* allow item list resolving in fake select for ORDER BY */
+ fake_select_lex->context.resolve_in_select_list= TRUE;
+ fake_select_lex->context.select_lex= fake_select_lex;
+
+ if (!first_sl->next_select())
+ {
+ /*
+ This works only for
+ (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
+ (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
+ just before the parser starts processing order_list
+ */
+ global_parameters= fake_select_lex;
+ fake_select_lex->no_table_names_allowed= 1;
+ thd->lex->current_select= fake_select_lex;
+ }
+ thd->lex->pop_context();
+ DBUG_RETURN(0);
+}
+
+
+/*
Push a new name resolution context for a JOIN ... ON clause to the
context stack of a query block.
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0211539e784..47c5281b258 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -224,7 +224,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
register SELECT_LEX *select_lex = &lex->select_lex;
DBUG_ENTER("handle_select");
- if (select_lex->next_select())
+ if (select_lex->next_select() || select_lex->master_unit()->fake_select_lex)
res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
else
{
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index dee88af7d83..c5af81ae55a 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -202,7 +202,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= sl= first_sl;
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
- is_union= test(first_sl->next_select());
+ is_union= first_sl->next_select() || fake_select_lex;
/* Global option */
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c3d9cb5913b..6473163a6ec 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5609,14 +5609,32 @@ order_clause:
ORDER_SYM BY
{
LEX *lex=Lex;
- if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
- lex->current_select->olap !=
- UNSPECIFIED_OLAP_TYPE)
+ SELECT_LEX *sel= lex->current_select;
+ SELECT_LEX_UNIT *unit= sel-> master_unit();
+ if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
+ sel->olap != UNSPECIFIED_OLAP_TYPE)
{
my_error(ER_WRONG_USAGE, MYF(0),
"CUBE/ROLLUP", "ORDER BY");
YYABORT;
}
+ if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
+ {
+ /*
+ A query of the of the form (SELECT ...) ORDER BY order_list is
+ executed in the same way as the query
+ SELECT ... ORDER BY order_list
+ unless the SELECT construct contains ORDER BY or LIMIT clauses.
+ Otherwise we create a fake SELECT_LEX if it has not been created
+ yet.
+ */
+ SELECT_LEX *first_sl= unit->first_select();
+ if (!first_sl->next_select() &&
+ (first_sl->order_list.elements ||
+ first_sl->select_limit) &&
+ unit->add_fake_select_lex(lex->thd))
+ YYABORT;
+ }
} order_list;
order_list: