mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
Merge baker@bk-internal.mysql.com:/home/bk/mysql-5.0
into zim.(none):/home/brian/mysql/mysql-5.0
This commit is contained in:
commit
d30bfd323a
65 changed files with 856 additions and 719 deletions
|
@ -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"
|
||||
|
@ -940,13 +940,6 @@ static int get_options(int argc, char **argv)
|
|||
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))))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* rsa.h for openSSL */
|
||||
|
||||
|
||||
#ifndef ysSSL_rsa_h__
|
||||
#ifndef yaSSL_rsa_h__
|
||||
#define yaSSL_rsa_h__
|
||||
|
||||
enum { RSA_F4 = 1 };
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ysSSL_openssl_h__
|
||||
#ifndef yaSSL_openssl_h__
|
||||
#define yaSSL_openssl_h__
|
||||
|
||||
#include <stdio.h> /* ERR_print fp */
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -72,3 +72,10 @@ set @@max_allowed_packet=1048576*100;
|
|||
select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null;
|
||||
compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null
|
||||
0
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
uncompress(a) uncompressed_length(a)
|
||||
NULL NULL
|
||||
a 1
|
||||
drop table t1;
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -74,3 +74,61 @@ SET FOREIGN_KEY_CHECKS=0;
|
|||
INSERT INTO t1 VALUES (1),(1);
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
drop table t1;
|
||||
drop function if exists bug15728;
|
||||
drop function if exists bug15728_insert;
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (
|
||||
id int not null auto_increment,
|
||||
last_id int,
|
||||
primary key (id)
|
||||
);
|
||||
create function bug15728() returns int(11)
|
||||
return last_insert_id();
|
||||
insert into t1 (last_id) values (0);
|
||||
insert into t1 (last_id) values (last_insert_id());
|
||||
insert into t1 (last_id) values (bug15728());
|
||||
create table t2 (
|
||||
id int not null auto_increment,
|
||||
last_id int,
|
||||
primary key (id)
|
||||
);
|
||||
create function bug15728_insert() returns int(11) modifies sql data
|
||||
begin
|
||||
insert into t2 (last_id) values (bug15728());
|
||||
return bug15728();
|
||||
end|
|
||||
create trigger t1_bi before insert on t1 for each row
|
||||
begin
|
||||
declare res int;
|
||||
select bug15728_insert() into res;
|
||||
set NEW.last_id = res;
|
||||
end|
|
||||
insert into t1 (last_id) values (0);
|
||||
drop trigger t1_bi;
|
||||
select last_insert_id();
|
||||
last_insert_id()
|
||||
4
|
||||
select bug15728_insert();
|
||||
bug15728_insert()
|
||||
2
|
||||
select last_insert_id();
|
||||
last_insert_id()
|
||||
4
|
||||
insert into t1 (last_id) values (bug15728());
|
||||
select last_insert_id();
|
||||
last_insert_id()
|
||||
5
|
||||
select * from t1;
|
||||
id last_id
|
||||
1 0
|
||||
2 1
|
||||
3 2
|
||||
4 1
|
||||
5 4
|
||||
select * from t2;
|
||||
id last_id
|
||||
1 3
|
||||
2 4
|
||||
drop function bug15728;
|
||||
drop function bug15728_insert;
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
drop table if exists t1;
|
||||
create table t1 (
|
||||
id char(16) not null default '',
|
||||
data int not null
|
||||
);
|
||||
drop procedure if exists goto1//
|
||||
create procedure goto1()
|
||||
begin
|
||||
declare y int;
|
||||
label a;
|
||||
select * from t1;
|
||||
select count(*) into y from t1;
|
||||
if y > 2 then
|
||||
goto b;
|
||||
end if;
|
||||
insert into t1 values ("j", y);
|
||||
goto a;
|
||||
label b;
|
||||
end//
|
||||
call goto1()//
|
||||
id data
|
||||
id data
|
||||
j 0
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
drop procedure goto1//
|
||||
drop procedure if exists goto2//
|
||||
create procedure goto2(a int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S98' set x = 1;
|
||||
label a;
|
||||
select * from t1;
|
||||
b:
|
||||
while x < 2 do
|
||||
begin
|
||||
declare continue handler for sqlstate '42S99' set x = 2;
|
||||
if a = 0 then
|
||||
set x = x + 1;
|
||||
iterate b;
|
||||
elseif a = 1 then
|
||||
leave b;
|
||||
elseif a = 2 then
|
||||
set a = 1;
|
||||
goto a;
|
||||
end if;
|
||||
end;
|
||||
end while b;
|
||||
select * from t1;
|
||||
end//
|
||||
call goto2(0)//
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call goto2(1)//
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call goto2(2)//
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
drop procedure goto2//
|
||||
delete from t1//
|
||||
drop procedure if exists goto3//
|
||||
create procedure goto3()
|
||||
begin
|
||||
label L1;
|
||||
begin
|
||||
end;
|
||||
goto L1;
|
||||
end//
|
||||
drop procedure goto3//
|
||||
drop procedure if exists goto4//
|
||||
create procedure goto4()
|
||||
begin
|
||||
begin
|
||||
label lab1;
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
end;
|
||||
end//
|
||||
drop procedure goto4//
|
||||
drop procedure if exists goto5//
|
||||
create procedure goto5()
|
||||
begin
|
||||
begin
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
label lab1;
|
||||
end;
|
||||
end//
|
||||
drop procedure goto5//
|
||||
drop procedure if exists goto6//
|
||||
create procedure goto6()
|
||||
begin
|
||||
label L1;
|
||||
goto L5;
|
||||
begin
|
||||
label L2;
|
||||
goto L1;
|
||||
goto L5;
|
||||
begin
|
||||
label L3;
|
||||
goto L1;
|
||||
goto L2;
|
||||
goto L3;
|
||||
goto L4;
|
||||
goto L5;
|
||||
end;
|
||||
goto L2;
|
||||
goto L4;
|
||||
label L4;
|
||||
end;
|
||||
label L5;
|
||||
goto L1;
|
||||
end//
|
||||
drop procedure goto6//
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
end//
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
goto foo;
|
||||
end//
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end//
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end//
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
end//
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure p()
|
||||
begin
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
goto L1;
|
||||
end;
|
||||
select field from t1;
|
||||
label L1;
|
||||
end//
|
||||
ERROR HY000: GOTO is not allowed in a stored procedure handler
|
||||
drop procedure if exists bug6898//
|
||||
create procedure bug6898()
|
||||
begin
|
||||
goto label1;
|
||||
label label1;
|
||||
begin end;
|
||||
goto label1;
|
||||
end//
|
||||
drop procedure bug6898//
|
||||
drop table t1;
|
|
@ -4848,4 +4848,60 @@ c 2
|
|||
b 3
|
||||
a 1
|
||||
delete from t1|
|
||||
drop function if exists bug15728|
|
||||
drop table if exists t3|
|
||||
create table t3 (
|
||||
id int not null auto_increment,
|
||||
primary key (id)
|
||||
)|
|
||||
create function bug15728() returns int(11)
|
||||
return last_insert_id()|
|
||||
insert into t3 values (0)|
|
||||
select last_insert_id()|
|
||||
last_insert_id()
|
||||
1
|
||||
select bug15728()|
|
||||
bug15728()
|
||||
1
|
||||
drop function bug15728|
|
||||
drop table t3|
|
||||
drop procedure if exists bug18787|
|
||||
create procedure bug18787()
|
||||
begin
|
||||
declare continue handler for sqlexception begin end;
|
||||
select no_such_function();
|
||||
end|
|
||||
call bug18787()|
|
||||
no_such_function()
|
||||
NULL
|
||||
drop procedure bug18787|
|
||||
create database bug18344_012345678901|
|
||||
use bug18344_012345678901|
|
||||
create procedure bug18344() begin end|
|
||||
create procedure bug18344_2() begin end|
|
||||
create database bug18344_0123456789012|
|
||||
use bug18344_0123456789012|
|
||||
create procedure bug18344() begin end|
|
||||
create procedure bug18344_2() begin end|
|
||||
use test|
|
||||
select schema_name from information_schema.schemata where
|
||||
schema_name like 'bug18344%'|
|
||||
schema_name
|
||||
bug18344_012345678901
|
||||
bug18344_0123456789012
|
||||
select routine_name,routine_schema from information_schema.routines where
|
||||
routine_schema like 'bug18344%'|
|
||||
routine_name routine_schema
|
||||
bug18344 bug18344_012345678901
|
||||
bug18344_2 bug18344_012345678901
|
||||
bug18344 bug18344_0123456789012
|
||||
bug18344_2 bug18344_0123456789012
|
||||
drop database bug18344_012345678901|
|
||||
drop database bug18344_0123456789012|
|
||||
select schema_name from information_schema.schemata where
|
||||
schema_name like 'bug18344%'|
|
||||
schema_name
|
||||
select routine_name,routine_schema from information_schema.routines where
|
||||
routine_schema like 'bug18344%'|
|
||||
routine_name routine_schema
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
drop tables if exists t1, t2;
|
||||
drop view if exists v1;
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
delete from mysql.tables_priv where user like 'mysqltest\_%';
|
||||
|
@ -59,3 +61,18 @@ delete from mysql.db where user like 'mysqltest\_%';
|
|||
delete from mysql.tables_priv where user like 'mysqltest\_%';
|
||||
flush privileges;
|
||||
drop table t1, t2;
|
||||
create table t1 (a int, b datetime);
|
||||
insert into t1 values (1, 20010101000000), (2, 20020101000000);
|
||||
grant all privileges on test.* to mysqltest_1@localhost;
|
||||
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
|
||||
select * from v1;
|
||||
a lb
|
||||
1 2001-01-01 03:00:00
|
||||
2 2002-01-01 03:00:00
|
||||
select * from v1, mysql.time_zone;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
|
||||
drop view v1;
|
||||
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
|
||||
ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
|
||||
drop table t1;
|
||||
drop user mysqltest_1@localhost;
|
||||
|
|
|
@ -949,9 +949,42 @@ insert into t1 values
|
|||
create function f2() returns int return (select max(b) from t2);
|
||||
insert into t2 select a, f2() from t1;
|
||||
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
|
||||
drop table t1;
|
||||
drop tables t1, t2;
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
|
||||
create table t2(i int not null, n numeric(15,2), primary key(i));
|
||||
create trigger t1_ai after insert on t1 for each row
|
||||
begin
|
||||
declare sn numeric(15,2);
|
||||
select sum(n) into sn from t1 where i=new.i;
|
||||
replace into t2 values(new.i, sn);
|
||||
end|
|
||||
insert into t1 values
|
||||
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
|
||||
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
|
||||
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
|
||||
select * from t1;
|
||||
i j n
|
||||
1 1 10.00
|
||||
1 2 10.00
|
||||
1 3 10.00
|
||||
1 4 10.00
|
||||
1 5 10.00
|
||||
1 6 10.00
|
||||
1 7 10.00
|
||||
1 8 10.00
|
||||
1 9 10.00
|
||||
1 10 10.00
|
||||
1 11 10.00
|
||||
1 12 10.00
|
||||
1 13 10.00
|
||||
1 14 10.00
|
||||
1 15 10.00
|
||||
select * from t2;
|
||||
i n
|
||||
1 150.00
|
||||
drop tables t1, t2;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (
|
||||
conn_id INT,
|
||||
|
|
|
@ -2623,3 +2623,29 @@ select * from v1;
|
|||
ERROR HY000: Recursive stored functions and triggers are not allowed.
|
||||
drop function f1;
|
||||
drop view t1, v1;
|
||||
create table t1 (dt datetime);
|
||||
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
|
||||
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
|
||||
select * from v1;
|
||||
ldt
|
||||
2004-01-01 03:00:00
|
||||
2005-01-01 03:00:00
|
||||
2006-01-01 03:00:00
|
||||
drop view v1;
|
||||
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
|
||||
select * from v1;
|
||||
dt
|
||||
2005-01-01 00:00:00
|
||||
2006-01-01 00:00:00
|
||||
create view v2 as select * from v1 where dt < 20060101000000;
|
||||
select * from v2;
|
||||
dt
|
||||
2005-01-01 00:00:00
|
||||
drop view v2;
|
||||
create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
|
||||
select * from v2;
|
||||
ldt
|
||||
2005-01-01 03:00:00
|
||||
2006-01-01 03:00:00
|
||||
drop view v1, v2;
|
||||
drop table t1;
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
sp-goto : GOTO is currently is disabled - will be fixed in the future
|
||||
ndb_load : Bug#17233
|
||||
udf : Bug#18564 (Permission by Brian)
|
||||
|
|
|
@ -47,4 +47,13 @@ set @@max_allowed_packet=1048576*100;
|
|||
--replace_result "''" XXX "'1'" XXX
|
||||
eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null;
|
||||
|
||||
#
|
||||
# Bug #18643: problem with null values
|
||||
#
|
||||
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -398,6 +398,16 @@ 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
|
||||
|
||||
#
|
||||
|
|
|
@ -2140,6 +2140,10 @@ 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
|
||||
#
|
||||
|
|
|
@ -1 +1 @@
|
|||
--innodb_locks_unsafe_for_binlog=true
|
||||
--loose-innodb_locks_unsafe_for_binlog=true
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -78,3 +78,73 @@ connection master;
|
|||
drop table t1;
|
||||
sync_slave_with_master;
|
||||
# End of 4.1 tests
|
||||
|
||||
|
||||
#
|
||||
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
|
||||
#
|
||||
# The solution is not to reset last_insert_id on enter to sub-statement.
|
||||
#
|
||||
connection master;
|
||||
--disable_warnings
|
||||
drop function if exists bug15728;
|
||||
drop function if exists bug15728_insert;
|
||||
drop table if exists t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (
|
||||
id int not null auto_increment,
|
||||
last_id int,
|
||||
primary key (id)
|
||||
);
|
||||
create function bug15728() returns int(11)
|
||||
return last_insert_id();
|
||||
|
||||
insert into t1 (last_id) values (0);
|
||||
insert into t1 (last_id) values (last_insert_id());
|
||||
insert into t1 (last_id) values (bug15728());
|
||||
|
||||
# Check that nested call replicates too.
|
||||
create table t2 (
|
||||
id int not null auto_increment,
|
||||
last_id int,
|
||||
primary key (id)
|
||||
);
|
||||
delimiter |;
|
||||
create function bug15728_insert() returns int(11) modifies sql data
|
||||
begin
|
||||
insert into t2 (last_id) values (bug15728());
|
||||
return bug15728();
|
||||
end|
|
||||
create trigger t1_bi before insert on t1 for each row
|
||||
begin
|
||||
declare res int;
|
||||
select bug15728_insert() into res;
|
||||
set NEW.last_id = res;
|
||||
end|
|
||||
delimiter ;|
|
||||
|
||||
insert into t1 (last_id) values (0);
|
||||
|
||||
drop trigger t1_bi;
|
||||
|
||||
# Check that nested call doesn't affect outer context.
|
||||
select last_insert_id();
|
||||
select bug15728_insert();
|
||||
select last_insert_id();
|
||||
insert into t1 (last_id) values (bug15728());
|
||||
# This should be exactly one greater than in the previous call.
|
||||
select last_insert_id();
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
connection master;
|
||||
|
||||
drop function bug15728;
|
||||
drop function bug15728_insert;
|
||||
drop table t1, t2;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
@ -1,238 +0,0 @@
|
|||
#
|
||||
# The non-standard GOTO, for compatibility
|
||||
#
|
||||
# QQQ The "label" syntax is temporary, it will (hopefully)
|
||||
# change to the more common "L:" syntax soon.
|
||||
# For the time being, this feature is disabled, until
|
||||
# the syntax (and some other known bugs) can be fixed.
|
||||
#
|
||||
# Test cases for bugs are added at the end. See template there.
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
create table t1 (
|
||||
id char(16) not null default '',
|
||||
data int not null
|
||||
);
|
||||
|
||||
delimiter //;
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists goto1//
|
||||
--enable_warnings
|
||||
create procedure goto1()
|
||||
begin
|
||||
declare y int;
|
||||
|
||||
label a;
|
||||
select * from t1;
|
||||
select count(*) into y from t1;
|
||||
if y > 2 then
|
||||
goto b;
|
||||
end if;
|
||||
insert into t1 values ("j", y);
|
||||
goto a;
|
||||
label b;
|
||||
end//
|
||||
|
||||
call goto1()//
|
||||
drop procedure goto1//
|
||||
|
||||
# With dummy handlers, just to test restore of contexts with jumps
|
||||
--disable_warnings
|
||||
drop procedure if exists goto2//
|
||||
--enable_warnings
|
||||
create procedure goto2(a int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S98' set x = 1;
|
||||
|
||||
label a;
|
||||
select * from t1;
|
||||
b:
|
||||
while x < 2 do
|
||||
begin
|
||||
declare continue handler for sqlstate '42S99' set x = 2;
|
||||
|
||||
if a = 0 then
|
||||
set x = x + 1;
|
||||
iterate b;
|
||||
elseif a = 1 then
|
||||
leave b;
|
||||
elseif a = 2 then
|
||||
set a = 1;
|
||||
goto a;
|
||||
end if;
|
||||
end;
|
||||
end while b;
|
||||
|
||||
select * from t1;
|
||||
end//
|
||||
|
||||
call goto2(0)//
|
||||
call goto2(1)//
|
||||
call goto2(2)//
|
||||
|
||||
drop procedure goto2//
|
||||
delete from t1//
|
||||
|
||||
# Check label visibility for some more cases. We don't call these.
|
||||
--disable_warnings
|
||||
drop procedure if exists goto3//
|
||||
--enable_warnings
|
||||
create procedure goto3()
|
||||
begin
|
||||
label L1;
|
||||
begin
|
||||
end;
|
||||
goto L1;
|
||||
end//
|
||||
drop procedure goto3//
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists goto4//
|
||||
--enable_warnings
|
||||
create procedure goto4()
|
||||
begin
|
||||
begin
|
||||
label lab1;
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
end;
|
||||
end//
|
||||
drop procedure goto4//
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists goto5//
|
||||
--enable_warnings
|
||||
create procedure goto5()
|
||||
begin
|
||||
begin
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
label lab1;
|
||||
end;
|
||||
end//
|
||||
drop procedure goto5//
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists goto6//
|
||||
--enable_warnings
|
||||
create procedure goto6()
|
||||
begin
|
||||
label L1;
|
||||
goto L5;
|
||||
begin
|
||||
label L2;
|
||||
goto L1;
|
||||
goto L5;
|
||||
begin
|
||||
label L3;
|
||||
goto L1;
|
||||
goto L2;
|
||||
goto L3;
|
||||
goto L4;
|
||||
goto L5;
|
||||
end;
|
||||
goto L2;
|
||||
goto L4;
|
||||
label L4;
|
||||
end;
|
||||
label L5;
|
||||
goto L1;
|
||||
end//
|
||||
drop procedure goto6//
|
||||
|
||||
# Mismatching labels
|
||||
--error 1308
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
end//
|
||||
--error 1308
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
goto foo;
|
||||
end//
|
||||
--error 1308
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end//
|
||||
--error 1308
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end//
|
||||
--error 1308
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
end//
|
||||
|
||||
# No goto in a handler
|
||||
--error 1358
|
||||
create procedure p()
|
||||
begin
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
goto L1;
|
||||
end;
|
||||
|
||||
select field from t1;
|
||||
label L1;
|
||||
end//
|
||||
|
||||
|
||||
#
|
||||
# Test cases for old bugs
|
||||
#
|
||||
|
||||
#
|
||||
# BUG#6898: Stored procedure crash if GOTO statements exist
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug6898//
|
||||
--enable_warnings
|
||||
create procedure bug6898()
|
||||
begin
|
||||
goto label1;
|
||||
label label1;
|
||||
begin end;
|
||||
goto label1;
|
||||
end//
|
||||
drop procedure bug6898//
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
#--disable_warnings
|
||||
#drop procedure if exists bugNNNN//
|
||||
#--enable_warnings
|
||||
#create procedure bugNNNN...
|
||||
|
||||
|
||||
# Add bugs above this line. Use existing tables t1 and t2 when
|
||||
# practical, or create table t3, t4 etc temporarily (and drop them).
|
||||
delimiter ;//
|
||||
drop table t1;
|
|
@ -5698,6 +5698,81 @@ select * from t1 order by @x|
|
|||
delete from t1|
|
||||
|
||||
|
||||
#
|
||||
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
|
||||
#
|
||||
# The solution is not to reset last_insert_id on enter to sub-statement.
|
||||
#
|
||||
--disable_warnings
|
||||
drop function if exists bug15728|
|
||||
drop table if exists t3|
|
||||
--enable_warnings
|
||||
|
||||
create table t3 (
|
||||
id int not null auto_increment,
|
||||
primary key (id)
|
||||
)|
|
||||
create function bug15728() returns int(11)
|
||||
return last_insert_id()|
|
||||
|
||||
insert into t3 values (0)|
|
||||
select last_insert_id()|
|
||||
select bug15728()|
|
||||
|
||||
drop function bug15728|
|
||||
drop table t3|
|
||||
|
||||
|
||||
#
|
||||
# BUG#18787: Server crashed when calling a stored procedure containing
|
||||
# a misnamed function
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug18787|
|
||||
--enable_warnings
|
||||
create procedure bug18787()
|
||||
begin
|
||||
declare continue handler for sqlexception begin end;
|
||||
|
||||
select no_such_function();
|
||||
end|
|
||||
|
||||
call bug18787()|
|
||||
drop procedure bug18787|
|
||||
|
||||
|
||||
#
|
||||
# BUG#18344: DROP DATABASE does not drop associated routines
|
||||
# (... if the database name is longer than 21 characters)
|
||||
#
|
||||
# 1234567890123456789012
|
||||
create database bug18344_012345678901|
|
||||
use bug18344_012345678901|
|
||||
create procedure bug18344() begin end|
|
||||
create procedure bug18344_2() begin end|
|
||||
|
||||
create database bug18344_0123456789012|
|
||||
use bug18344_0123456789012|
|
||||
create procedure bug18344() begin end|
|
||||
create procedure bug18344_2() begin end|
|
||||
|
||||
use test|
|
||||
|
||||
select schema_name from information_schema.schemata where
|
||||
schema_name like 'bug18344%'|
|
||||
select routine_name,routine_schema from information_schema.routines where
|
||||
routine_schema like 'bug18344%'|
|
||||
|
||||
drop database bug18344_012345678901|
|
||||
drop database bug18344_0123456789012|
|
||||
|
||||
# Should be nothing left.
|
||||
select schema_name from information_schema.schemata where
|
||||
schema_name like 'bug18344%'|
|
||||
select routine_name,routine_schema from information_schema.routines where
|
||||
routine_schema like 'bug18344%'|
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
# Embedded server testing does not support grants
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop tables if exists t1, t2;
|
||||
drop view if exists v1;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# Test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone
|
||||
# tables". We should allow implicit access to time zone description tables
|
||||
|
@ -82,3 +87,29 @@ flush privileges;
|
|||
drop table t1, t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Additional test for bug #15153: CONVERT_TZ() is not allowed in all
|
||||
# places in views.
|
||||
#
|
||||
# Let us check that usage of CONVERT_TZ() function in view does not
|
||||
# require additional privileges.
|
||||
|
||||
# Let us rely on that previous tests done proper cleanups
|
||||
create table t1 (a int, b datetime);
|
||||
insert into t1 values (1, 20010101000000), (2, 20020101000000);
|
||||
grant all privileges on test.* to mysqltest_1@localhost;
|
||||
connect (tzuser3, localhost, mysqltest_1,,);
|
||||
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
|
||||
select * from v1;
|
||||
# Of course we should not be able select from mysql.time_zone tables
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from v1, mysql.time_zone;
|
||||
drop view v1;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
|
||||
connection default;
|
||||
drop table t1;
|
||||
drop user mysqltest_1@localhost;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
@ -1111,10 +1111,34 @@ insert into t1 values
|
|||
create function f2() returns int return (select max(b) from t2);
|
||||
insert into t2 select a, f2() from t1;
|
||||
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
|
||||
drop table t1;
|
||||
drop tables t1, t2;
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
|
||||
#
|
||||
# Test for bug #16021 "Wrong index given to function in trigger" which
|
||||
# was caused by the same bulk insert optimization as bug #17764 but had
|
||||
# slightly different symptoms (instead of reporting table as crashed
|
||||
# storage engine reported error number 124)
|
||||
#
|
||||
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
|
||||
create table t2(i int not null, n numeric(15,2), primary key(i));
|
||||
delimiter |;
|
||||
create trigger t1_ai after insert on t1 for each row
|
||||
begin
|
||||
declare sn numeric(15,2);
|
||||
select sum(n) into sn from t1 where i=new.i;
|
||||
replace into t2 values(new.i, sn);
|
||||
end|
|
||||
delimiter ;|
|
||||
insert into t1 values
|
||||
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
|
||||
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
|
||||
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
drop tables t1, t2;
|
||||
|
||||
#
|
||||
# Test for Bug #16461 connection_id() does not work properly inside trigger
|
||||
#
|
||||
|
|
|
@ -2485,3 +2485,30 @@ rename table v2 to t1;
|
|||
select * from v1;
|
||||
drop function f1;
|
||||
drop view t1, v1;
|
||||
|
||||
#
|
||||
# Bug #15153: CONVERT_TZ() is not allowed in all places in VIEWs
|
||||
#
|
||||
# Error was reported when one tried to use CONVERT_TZ() function
|
||||
# select list of view which was processed using MERGE algorithm.
|
||||
# (Also see additional test in timezone_grant.test)
|
||||
create table t1 (dt datetime);
|
||||
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
|
||||
# Let us test that convert_tz() can be used in view's select list
|
||||
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# And in its where part
|
||||
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
|
||||
select * from v1;
|
||||
# Other interesting case - a view which uses convert_tz() function
|
||||
# through other view.
|
||||
create view v2 as select * from v1 where dt < 20060101000000;
|
||||
select * from v2;
|
||||
drop view v2;
|
||||
# And even more interesting case when view uses convert_tz() both
|
||||
# directly and indirectly
|
||||
create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
|
||||
select * from v2;
|
||||
drop view v1, v2;
|
||||
drop table t1;
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -4744,7 +4744,9 @@ Item_func_sp::sp_result_field(void) const
|
|||
share->table_cache_key = empty_name;
|
||||
share->table_name = empty_name;
|
||||
}
|
||||
field= m_sp->create_result_field(max_length, name, dummy_table);
|
||||
if (!(field= m_sp->create_result_field(max_length, name, dummy_table)))
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
|
||||
DBUG_RETURN(field);
|
||||
}
|
||||
|
||||
|
@ -4772,8 +4774,9 @@ Item_func_sp::execute(Field **flp)
|
|||
{
|
||||
if (!(*flp= f= sp_result_field()))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
return 0;
|
||||
/* Error set by sp_result_field() */
|
||||
null_value= 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
f->move_field((f->pack_length() > sizeof(result_buf)) ?
|
||||
|
@ -4928,16 +4931,19 @@ longlong Item_func_found_rows::val_int()
|
|||
Field *
|
||||
Item_func_sp::tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
Field *res= 0;
|
||||
Field *field= 0;
|
||||
DBUG_ENTER("Item_func_sp::tmp_table_field");
|
||||
|
||||
if (m_sp)
|
||||
res= m_sp->create_result_field(max_length, (const char*) name, t_arg);
|
||||
field= m_sp->create_result_field(max_length, (const char*) name, t_arg);
|
||||
|
||||
if (!res)
|
||||
res= Item_func::tmp_table_field(t_arg);
|
||||
if (!field)
|
||||
field= Item_func::tmp_table_field(t_arg);
|
||||
|
||||
DBUG_RETURN(res);
|
||||
if (!field)
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
|
||||
DBUG_RETURN(field);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2941,6 +2941,7 @@ String *Item_func_uncompress::val_str(String *str)
|
|||
|
||||
if (!res)
|
||||
goto err;
|
||||
null_value= 0;
|
||||
if (res->is_empty())
|
||||
return res;
|
||||
|
||||
|
|
|
@ -215,9 +215,6 @@ static SYMBOL symbols[] = {
|
|||
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
|
||||
{ "GET_FORMAT", SYM(GET_FORMAT)},
|
||||
{ "GLOBAL", SYM(GLOBAL_SYM)},
|
||||
#ifdef SP_GOTO
|
||||
{ "GOTO", SYM(GOTO_SYM)},
|
||||
#endif
|
||||
{ "GRANT", SYM(GRANT)},
|
||||
{ "GRANTS", SYM(GRANTS)},
|
||||
{ "GROUP", SYM(GROUP)},
|
||||
|
@ -265,10 +262,6 @@ static SYMBOL symbols[] = {
|
|||
{ "KEY", SYM(KEY_SYM)},
|
||||
{ "KEYS", SYM(KEYS)},
|
||||
{ "KILL", SYM(KILL_SYM)},
|
||||
#ifdef SP_GOTO
|
||||
/* QQ This will go away when the GOTO label syntax is fixed */
|
||||
{ "LABEL", SYM(LABEL_SYM)},
|
||||
#endif
|
||||
{ "LANGUAGE", SYM(LANGUAGE_SYM)},
|
||||
{ "LAST", SYM(LAST_SYM)},
|
||||
{ "LEADING", SYM(LEADING)},
|
||||
|
|
20
sql/sp.cc
20
sql/sp.cc
|
@ -886,28 +886,23 @@ int
|
|||
sp_drop_db_routines(THD *thd, char *db)
|
||||
{
|
||||
TABLE *table;
|
||||
byte key[64]; // db
|
||||
uint keylen;
|
||||
int ret;
|
||||
uint key_len;
|
||||
DBUG_ENTER("sp_drop_db_routines");
|
||||
DBUG_PRINT("enter", ("db: %s", db));
|
||||
|
||||
// Put the key used to read the row together
|
||||
keylen= strlen(db);
|
||||
if (keylen > 64)
|
||||
keylen= 64;
|
||||
memcpy(key, db, keylen);
|
||||
memset(key+keylen, (int)' ', 64-keylen); // Pad with space
|
||||
keylen= sizeof(key);
|
||||
|
||||
ret= SP_OPEN_TABLE_FAILED;
|
||||
if (!(table= open_proc_table_for_update(thd)))
|
||||
goto err;
|
||||
|
||||
table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
|
||||
key_len= table->key_info->key_part[0].store_length;
|
||||
|
||||
ret= SP_OK;
|
||||
table->file->ha_index_init(0);
|
||||
if (! table->file->index_read(table->record[0],
|
||||
key, keylen, HA_READ_KEY_EXACT))
|
||||
(byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
|
||||
key_len, HA_READ_KEY_EXACT))
|
||||
{
|
||||
int nxtres;
|
||||
bool deleted= FALSE;
|
||||
|
@ -923,7 +918,8 @@ sp_drop_db_routines(THD *thd, char *db)
|
|||
break;
|
||||
}
|
||||
} while (! (nxtres= table->file->index_next_same(table->record[0],
|
||||
key, keylen)));
|
||||
(byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
|
||||
key_len)));
|
||||
if (nxtres != HA_ERR_END_OF_FILE)
|
||||
ret= SP_KEY_NOT_FOUND;
|
||||
if (deleted)
|
||||
|
|
|
@ -1670,44 +1670,11 @@ sp_head::backpatch(sp_label_t *lab)
|
|||
|
||||
while ((bp= li++))
|
||||
{
|
||||
if (bp->lab == lab ||
|
||||
(bp->lab->type == SP_LAB_REF &&
|
||||
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
|
||||
{
|
||||
if (bp->lab->type != SP_LAB_REF)
|
||||
if (bp->lab == lab)
|
||||
bp->instr->backpatch(dest, lab->ctx);
|
||||
else
|
||||
{
|
||||
sp_label_t *dstlab= bp->lab->ctx->find_label(lab->name);
|
||||
|
||||
if (dstlab)
|
||||
{
|
||||
bp->lab= lab;
|
||||
bp->instr->backpatch(dest, dstlab->ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sp_head::check_backpatch(THD *thd)
|
||||
{
|
||||
bp_t *bp;
|
||||
List_iterator_fast<bp_t> li(m_backpatch);
|
||||
|
||||
while ((bp= li++))
|
||||
{
|
||||
if (bp->lab->type == SP_LAB_REF)
|
||||
{
|
||||
my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Prepare an instance of create_field for field creation (fill all necessary
|
||||
attributes).
|
||||
|
|
|
@ -263,13 +263,6 @@ public:
|
|||
void
|
||||
backpatch(struct sp_label *);
|
||||
|
||||
// Check that no unresolved references exist.
|
||||
// If none found, 0 is returned, otherwise errors have been issued
|
||||
// and -1 is returned.
|
||||
// This is called by the parser at the end of a create procedure/function.
|
||||
int
|
||||
check_backpatch(THD *thd);
|
||||
|
||||
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
|
||||
void
|
||||
new_cont_backpatch(sp_instr_opt_meta *i);
|
||||
|
|
|
@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip)
|
|||
{
|
||||
lab->name= name;
|
||||
lab->ip= ip;
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->type= SP_LAB_IMPL;
|
||||
lab->ctx= this;
|
||||
m_label.push_front(lab);
|
||||
}
|
||||
|
|
|
@ -48,10 +48,9 @@ typedef struct sp_variable
|
|||
} sp_variable_t;
|
||||
|
||||
|
||||
#define SP_LAB_REF 0 // Unresolved reference (for goto)
|
||||
#define SP_LAB_GOTO 1 // Free goto label
|
||||
#define SP_LAB_BEGIN 2 // Label at BEGIN
|
||||
#define SP_LAB_ITER 3 // Label at iteration control
|
||||
#define SP_LAB_IMPL 0 // Implicit label generated by parser
|
||||
#define SP_LAB_BEGIN 1 // Label at BEGIN
|
||||
#define SP_LAB_ITER 2 // Label at iteration control
|
||||
|
||||
/*
|
||||
An SQL/PSM label. Can refer to the identifier used with the
|
||||
|
|
|
@ -2025,7 +2025,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
|
|||
The following things is done
|
||||
- Disable binary logging for the duration of the statement
|
||||
- Disable multi-result-sets for the duration of the statement
|
||||
- Value of last_insert_id() is reset and restored
|
||||
- Value of last_insert_id() is saved and restored
|
||||
- Value set by 'SET INSERT_ID=#' is reset and restored
|
||||
- Value for found_rows() is reset and restored
|
||||
- examined_row_count is added to the total
|
||||
|
@ -2037,6 +2037,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
|
|||
We reset examined_row_count and cuted_fields and add these to the
|
||||
result to ensure that if we have a bug that would reset these within
|
||||
a function, we are not loosing any rows from the main statement.
|
||||
|
||||
We do not reset value of last_insert_id().
|
||||
****************************************************************************/
|
||||
|
||||
void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
||||
|
@ -2062,7 +2064,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
|||
/* Disable result sets */
|
||||
client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
||||
in_sub_stmt|= new_state;
|
||||
last_insert_id= 0;
|
||||
next_insert_id= 0;
|
||||
insert_id_used= 0;
|
||||
examined_row_count= 0;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()))
|
||||
if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
|
||||
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->context.outer_context=
|
||||
unit->first_select()->context.outer_context;
|
||||
}
|
||||
|
||||
select_lex->master_unit()->global_parameters= select_lex;
|
||||
|
@ -6357,6 +6326,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.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -1057,15 +1057,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
|
|||
!old_lex->can_not_use_merged())
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
|
||||
/*
|
||||
Currently 'view_main_select_tables' differs from 'view_tables'
|
||||
only then view has CONVERT_TZ() function in its select list.
|
||||
This may change in future, for example if we enable merging
|
||||
of views with subqueries in select list.
|
||||
*/
|
||||
TABLE_LIST *view_main_select_tables=
|
||||
(TABLE_LIST*)lex->select_lex.table_list.first;
|
||||
/* lex should contain at least one table */
|
||||
DBUG_ASSERT(view_tables != 0);
|
||||
DBUG_ASSERT(view_main_select_tables != 0);
|
||||
|
||||
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
|
||||
DBUG_PRINT("info", ("algorithm: MERGE"));
|
||||
table->updatable= (table->updatable_view != 0);
|
||||
table->effective_with_check=
|
||||
old_lex->get_effective_with_check(table);
|
||||
table->merge_underlying_list= view_tables;
|
||||
table->merge_underlying_list= view_main_select_tables;
|
||||
/*
|
||||
Let us set proper lock type for tables of the view's main select
|
||||
since we may want to perform update or insert on view. This won't
|
||||
|
@ -1081,7 +1089,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
|
|||
}
|
||||
|
||||
/* prepare view context */
|
||||
lex->select_lex.context.resolve_in_table_list_only(view_tables);
|
||||
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
|
||||
lex->select_lex.context.outer_context= 0;
|
||||
lex->select_lex.context.select_lex= table->select_lex;
|
||||
lex->select_lex.select_n_having_items+=
|
||||
|
@ -1097,7 +1105,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
|
|||
tbl->select_lex= table->select_lex;
|
||||
|
||||
{
|
||||
if (view_tables->next_local)
|
||||
if (view_main_select_tables->next_local)
|
||||
{
|
||||
table->multitable_view= TRUE;
|
||||
if (table->belong_to_view)
|
||||
|
|
114
sql/sql_yacc.yy
114
sql/sql_yacc.yy
|
@ -301,7 +301,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token GEOMFROMWKB
|
||||
%token GET_FORMAT
|
||||
%token GLOBAL_SYM
|
||||
%token GOTO_SYM
|
||||
%token GRANT
|
||||
%token GRANTS
|
||||
%token GREATEST_SYM
|
||||
|
@ -1332,8 +1331,6 @@ create_function_tail:
|
|||
if (sp->is_not_allowed_in_function("function"))
|
||||
YYABORT;
|
||||
|
||||
if (sp->check_backpatch(YYTHD))
|
||||
YYABORT;
|
||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||
sp->init_strings(YYTHD, lex, lex->spname);
|
||||
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||
|
@ -2054,91 +2051,6 @@ sp_proc_stmt:
|
|||
sp->add_instr(i);
|
||||
}
|
||||
}
|
||||
| LABEL_SYM IDENT
|
||||
{
|
||||
#ifdef SP_GOTO
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
|
||||
if (lab)
|
||||
{
|
||||
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
lab= ctx->push_label($2.str, sp->instructions());
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->ctx= ctx;
|
||||
sp->backpatch(lab);
|
||||
}
|
||||
#else
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
#endif
|
||||
}
|
||||
| GOTO_SYM IDENT
|
||||
{
|
||||
#ifdef SP_GOTO
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab;
|
||||
sp_instr_jump *i;
|
||||
sp_instr_hpop *ih;
|
||||
sp_instr_cpop *ic;
|
||||
|
||||
if (sp->m_in_handler)
|
||||
{
|
||||
my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0));
|
||||
YYABORT;
|
||||
}
|
||||
lab= ctx->find_label($2.str);
|
||||
if (! lab)
|
||||
{
|
||||
lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t));
|
||||
lab->name= $2.str;
|
||||
lab->ip= 0;
|
||||
lab->type= SP_LAB_REF;
|
||||
lab->ctx= ctx;
|
||||
|
||||
ih= new sp_instr_hpop(ip++, ctx, 0);
|
||||
sp->push_backpatch(ih, lab);
|
||||
sp->add_instr(ih);
|
||||
ic= new sp_instr_cpop(ip++, ctx, 0);
|
||||
sp->add_instr(ic);
|
||||
sp->push_backpatch(ic, lab);
|
||||
i= new sp_instr_jump(ip, ctx);
|
||||
sp->push_backpatch(i, lab); /* Jumping forward */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint n;
|
||||
|
||||
n= ctx->diff_handlers(lab->ctx);
|
||||
if (n)
|
||||
{
|
||||
ih= new sp_instr_hpop(ip++, ctx, n);
|
||||
sp->add_instr(ih);
|
||||
}
|
||||
n= ctx->diff_cursors(lab->ctx);
|
||||
if (n)
|
||||
{
|
||||
ic= new sp_instr_cpop(ip++, ctx, n);
|
||||
sp->add_instr(ic);
|
||||
}
|
||||
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
#else
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
#endif
|
||||
}
|
||||
| OPEN_SYM ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
|
@ -5697,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:
|
||||
|
@ -9228,8 +9158,6 @@ sp_tail:
|
|||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
if (sp->check_backpatch(YYTHD))
|
||||
YYABORT;
|
||||
sp->init_strings(YYTHD, lex, $3);
|
||||
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
|
||||
/* Restore flag if it was cleared above */
|
||||
|
|
Loading…
Reference in a new issue