mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 09:14:17 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/my/mysql-5.0 BitKeeper/etc/logging_ok: auto-union include/mysql_com.h: Auto merged sql/filesort.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/mysqld.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_select.cc: Auto merged
This commit is contained in:
commit
1b002905b7
21 changed files with 191 additions and 88 deletions
|
@ -1593,6 +1593,22 @@ static int reconnect(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_current_db()
|
||||||
|
{
|
||||||
|
MYSQL_RES *res;
|
||||||
|
|
||||||
|
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
current_db= NULL;
|
||||||
|
/* In case of error below current_db will be NULL */
|
||||||
|
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
|
||||||
|
(res= mysql_use_result(&mysql)))
|
||||||
|
{
|
||||||
|
MYSQL_ROW row= mysql_fetch_row(res);
|
||||||
|
if (row[0])
|
||||||
|
current_db= my_strdup(row[0], MYF(MY_WME));
|
||||||
|
mysql_free_result(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
The different commands
|
The different commands
|
||||||
|
@ -1917,6 +1933,10 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||||
if (err >= 1)
|
if (err >= 1)
|
||||||
error= put_error(&mysql);
|
error= put_error(&mysql);
|
||||||
|
|
||||||
|
if (!error && !status.batch &&
|
||||||
|
(mysql.server_status & SERVER_STATUS_DB_DROPPED))
|
||||||
|
get_current_db();
|
||||||
|
|
||||||
return error; /* New command follows */
|
return error; /* New command follows */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2631,24 +2651,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
|
||||||
under our feet, for example if DROP DATABASE or RENAME DATABASE
|
under our feet, for example if DROP DATABASE or RENAME DATABASE
|
||||||
(latter one not yet available by the time the comment was written)
|
(latter one not yet available by the time the comment was written)
|
||||||
*/
|
*/
|
||||||
/* Let's reset current_db, assume it's gone */
|
get_current_db();
|
||||||
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
|
|
||||||
current_db= 0;
|
|
||||||
/*
|
|
||||||
We don't care about in case of an error below because current_db
|
|
||||||
was just set to 0.
|
|
||||||
*/
|
|
||||||
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
|
|
||||||
(res= mysql_use_result(&mysql)))
|
|
||||||
{
|
|
||||||
row= mysql_fetch_row(res);
|
|
||||||
if (row[0])
|
|
||||||
{
|
|
||||||
current_db= my_strdup(row[0], MYF(MY_WME));
|
|
||||||
}
|
|
||||||
(void) mysql_fetch_row(res); // Read eof
|
|
||||||
mysql_free_result(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current_db || cmp_database(charset_info, current_db,tmp))
|
if (!current_db || cmp_database(charset_info, current_db,tmp))
|
||||||
{
|
{
|
||||||
|
|
|
@ -865,6 +865,11 @@ static int dbConnect(char *host, char *user,char *passwd)
|
||||||
DBerror(&mysql_connection, "when trying to connect");
|
DBerror(&mysql_connection, "when trying to connect");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Don't dump SET NAMES with a pre-4.1 server (bug#7997).
|
||||||
|
*/
|
||||||
|
if (mysql_get_server_version(&mysql_connection) < 40100)
|
||||||
|
opt_set_charset= 0;
|
||||||
/*
|
/*
|
||||||
As we're going to set SQL_MODE, it would be lost on reconnect, so we
|
As we're going to set SQL_MODE, it would be lost on reconnect, so we
|
||||||
cannot reconnect.
|
cannot reconnect.
|
||||||
|
|
|
@ -147,6 +147,7 @@ enum enum_server_command
|
||||||
COM_FETCH command.
|
COM_FETCH command.
|
||||||
*/
|
*/
|
||||||
#define SERVER_STATUS_LAST_ROW_SENT 128
|
#define SERVER_STATUS_LAST_ROW_SENT 128
|
||||||
|
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
|
||||||
|
|
||||||
#define MYSQL_ERRMSG_SIZE 512
|
#define MYSQL_ERRMSG_SIZE 512
|
||||||
#define NET_READ_TIMEOUT 30 /* Timeout on read */
|
#define NET_READ_TIMEOUT 30 /* Timeout on read */
|
||||||
|
|
|
@ -2719,7 +2719,8 @@ scan_more:
|
||||||
/* Starting quote: remember the quote character. */
|
/* Starting quote: remember the quote character. */
|
||||||
quote = *sptr;
|
quote = *sptr;
|
||||||
} else if (*sptr == '#'
|
} else if (*sptr == '#'
|
||||||
|| (0 == memcmp("-- ", sptr, 3))) {
|
|| (sptr[0] == '-' && sptr[1] == '-' &&
|
||||||
|
sptr[2] == ' ')) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* In Unix a newline is 0x0A while in Windows
|
/* In Unix a newline is 0x0A while in Windows
|
||||||
it is 0x0D followed by 0x0A */
|
it is 0x0D followed by 0x0A */
|
||||||
|
|
|
@ -3817,13 +3817,6 @@ fil_io(
|
||||||
node = UT_LIST_GET_FIRST(space->chain);
|
node = UT_LIST_GET_FIRST(space->chain);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (space->id != 0 && node->size == 0) {
|
|
||||||
/* We do not know the size of a single-table tablespace
|
|
||||||
before we open the file */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: trying to access page number %lu in space %lu,\n"
|
"InnoDB: Error: trying to access page number %lu in space %lu,\n"
|
||||||
|
@ -3837,6 +3830,13 @@ fil_io(
|
||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (space->id != 0 && node->size == 0) {
|
||||||
|
/* We do not know the size of a single-table tablespace
|
||||||
|
before we open the file */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->size > block_offset) {
|
if (node->size > block_offset) {
|
||||||
/* Found! */
|
/* Found! */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3058,14 +3058,19 @@ row_search_for_mysql(
|
||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx->n_mysql_tables_in_use == 0) {
|
if (trx->n_mysql_tables_in_use == 0
|
||||||
|
&& prebuilt->select_lock_type == LOCK_NONE) {
|
||||||
|
/* Note that if MySQL uses an InnoDB temp table that it
|
||||||
|
created inside LOCK TABLES, then n_mysql_tables_in_use can
|
||||||
|
be zero; in that case select_lock_type is set to LOCK_X in
|
||||||
|
::start_stmt. */
|
||||||
|
|
||||||
fputs(
|
fputs(
|
||||||
"InnoDB: Error: MySQL is trying to perform a SELECT\n"
|
"InnoDB: Error: MySQL is trying to perform a SELECT\n"
|
||||||
"InnoDB: but it has not locked any tables in ::external_lock()!\n",
|
"InnoDB: but it has not locked any tables in ::external_lock()!\n",
|
||||||
stderr);
|
stderr);
|
||||||
trx_print(stderr, trx);
|
trx_print(stderr, trx);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
ut_a(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf(stderr, "Match mode %lu\n search tuple ", (ulong) match_mode);
|
/* fprintf(stderr, "Match mode %lu\n search tuple ", (ulong) match_mode);
|
||||||
|
|
|
@ -254,3 +254,4 @@ a
|
||||||
SELECT FOUND_ROWS();
|
SELECT FOUND_ROWS();
|
||||||
FOUND_ROWS()
|
FOUND_ROWS()
|
||||||
1
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
|
@ -29,6 +29,12 @@ a
|
||||||
A
|
A
|
||||||
a,A
|
a,A
|
||||||
a,A
|
a,A
|
||||||
|
select s from t1 order by concat(s);
|
||||||
|
s
|
||||||
|
A
|
||||||
|
a
|
||||||
|
a,A
|
||||||
|
a,A
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (c set('ae','oe','ue','ss') collate latin1_german2_ci);
|
CREATE TABLE t1 (c set('ae','oe','ue','ss') collate latin1_german2_ci);
|
||||||
INSERT INTO t1 VALUES ('ä'),('ö'),('ü'),('ß');
|
INSERT INTO t1 VALUES ('ä'),('ö'),('ü'),('ß');
|
||||||
|
@ -47,4 +53,16 @@ ss
|
||||||
ss
|
ss
|
||||||
ae,oe,ue,ss
|
ae,oe,ue,ss
|
||||||
ae,oe,ue,ss
|
ae,oe,ue,ss
|
||||||
|
SELECT c FROM t1 ORDER BY concat(c);
|
||||||
|
c
|
||||||
|
ae
|
||||||
|
ae
|
||||||
|
ae,oe,ue,ss
|
||||||
|
ae,oe,ue,ss
|
||||||
|
oe
|
||||||
|
oe
|
||||||
|
ss
|
||||||
|
ss
|
||||||
|
ue
|
||||||
|
ue
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
|
@ -175,3 +175,4 @@ CREATE TABLE t1 (a int, b int);
|
||||||
INSERT INTO t1 VALUES (1,2), (1,3), (1,4), (1,5);
|
INSERT INTO t1 VALUES (1,2), (1,3), (1,4), (1,5);
|
||||||
SELECT SQL_CALC_FOUND_ROWS DISTINCT 'a' FROM t1 GROUP BY b LIMIT 2;
|
SELECT SQL_CALC_FOUND_ROWS DISTINCT 'a' FROM t1 GROUP BY b LIMIT 2;
|
||||||
SELECT FOUND_ROWS();
|
SELECT FOUND_ROWS();
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
|
@ -23,6 +23,7 @@ create table t1 (s set ('a','A') character set latin1 collate latin1_bin);
|
||||||
show create table t1;
|
show create table t1;
|
||||||
insert into t1 values ('a'),('a,A'),('A,a'),('A');
|
insert into t1 values ('a'),('a,A'),('A,a'),('A');
|
||||||
select s from t1 order by s;
|
select s from t1 order by s;
|
||||||
|
select s from t1 order by concat(s);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -34,4 +35,5 @@ INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
|
||||||
INSERT INTO t1 VALUES ('ä,ö,ü,ß');
|
INSERT INTO t1 VALUES ('ä,ö,ü,ß');
|
||||||
INSERT INTO t1 VALUES ('ae,oe,ue,ss');
|
INSERT INTO t1 VALUES ('ae,oe,ue,ss');
|
||||||
SELECT c FROM t1 ORDER BY c;
|
SELECT c FROM t1 ORDER BY c;
|
||||||
|
SELECT c FROM t1 ORDER BY concat(c);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
|
@ -145,6 +145,10 @@ void my_end(int infoflag)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_GETRUSAGE
|
#ifdef HAVE_GETRUSAGE
|
||||||
struct rusage rus;
|
struct rusage rus;
|
||||||
|
#ifdef HAVE_purify
|
||||||
|
/* Purify assumes that rus is uninitialized after getrusage call */
|
||||||
|
bzero((char*) &rus, sizeof(rus));
|
||||||
|
#endif
|
||||||
if (!getrusage(RUSAGE_SELF, &rus))
|
if (!getrusage(RUSAGE_SELF, &rus))
|
||||||
fprintf(info_file,"\n\
|
fprintf(info_file,"\n\
|
||||||
User time %.2f, System time %.2f\n\
|
User time %.2f, System time %.2f\n\
|
||||||
|
|
|
@ -276,6 +276,7 @@ public:
|
||||||
virtual bool get_date(TIME *ltime,uint fuzzydate);
|
virtual bool get_date(TIME *ltime,uint fuzzydate);
|
||||||
virtual bool get_time(TIME *ltime);
|
virtual bool get_time(TIME *ltime);
|
||||||
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
|
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
|
||||||
|
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
|
||||||
virtual bool has_charset(void) const { return FALSE; }
|
virtual bool has_charset(void) const { return FALSE; }
|
||||||
virtual void set_charset(CHARSET_INFO *charset) { }
|
virtual void set_charset(CHARSET_INFO *charset) { }
|
||||||
bool set_warning(const unsigned int level, const unsigned int code,
|
bool set_warning(const unsigned int level, const unsigned int code,
|
||||||
|
@ -1255,6 +1256,8 @@ public:
|
||||||
bool optimize_range(uint idx, uint part) { return 0; }
|
bool optimize_range(uint idx, uint part) { return 0; }
|
||||||
bool eq_def(Field *field);
|
bool eq_def(Field *field);
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
|
/* enum and set are sorted as integers */
|
||||||
|
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
||||||
field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
|
field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1198,12 +1198,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sortorder->length=sortorder->field->pack_length();
|
sortorder->length=sortorder->field->pack_length();
|
||||||
/*
|
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
|
||||||
We must test cmp_type() to ensure that ENUM and SET are sorted
|
|
||||||
as numbers
|
|
||||||
*/
|
|
||||||
if (use_strnxfrm((cs=sortorder->field->charset())) &&
|
|
||||||
sortorder->field->cmp_type() == STRING_RESULT)
|
|
||||||
{
|
{
|
||||||
sortorder->need_strxnfrm= 1;
|
sortorder->need_strxnfrm= 1;
|
||||||
*multi_byte_charset= 1;
|
*multi_byte_charset= 1;
|
||||||
|
|
|
@ -283,7 +283,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
|
||||||
comparators= 0;
|
comparators= 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!(comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
|
if (!(comparators= new Arg_comparator[n]))
|
||||||
return 1;
|
return 1;
|
||||||
for (uint i=0; i < n; i++)
|
for (uint i=0; i < n; i++)
|
||||||
{
|
{
|
||||||
|
@ -1825,6 +1825,12 @@ in_row::in_row(uint elements, Item * item)
|
||||||
size= sizeof(cmp_item_row);
|
size= sizeof(cmp_item_row);
|
||||||
compare= (qsort2_cmp) cmp_row;
|
compare= (qsort2_cmp) cmp_row;
|
||||||
tmp.store_value(item);
|
tmp.store_value(item);
|
||||||
|
/*
|
||||||
|
We need to reset these as otherwise we will call sort() with
|
||||||
|
uninitialized (even if not used) elements
|
||||||
|
*/
|
||||||
|
used_count= elements;
|
||||||
|
collation= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_row::~in_row()
|
in_row::~in_row()
|
||||||
|
|
|
@ -552,6 +552,7 @@ extern "C" pthread_handler_decl(handle_slave,arg);
|
||||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
|
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
|
||||||
static void clean_up(bool print_message);
|
static void clean_up(bool print_message);
|
||||||
static void clean_up_mutexes(void);
|
static void clean_up_mutexes(void);
|
||||||
|
static void wait_for_signal_thread_to_end(void);
|
||||||
static int test_if_case_insensitive(const char *dir_name);
|
static int test_if_case_insensitive(const char *dir_name);
|
||||||
static void create_pid_file();
|
static void create_pid_file();
|
||||||
|
|
||||||
|
@ -943,6 +944,7 @@ extern "C" void unireg_abort(int exit_code)
|
||||||
sql_print_error("Aborting\n");
|
sql_print_error("Aborting\n");
|
||||||
clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */
|
clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */
|
||||||
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
||||||
|
wait_for_signal_thread_to_end();
|
||||||
clean_up_mutexes();
|
clean_up_mutexes();
|
||||||
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
||||||
exit(exit_code); /* purecov: inspected */
|
exit(exit_code); /* purecov: inspected */
|
||||||
|
@ -1051,6 +1053,29 @@ void clean_up(bool print_message)
|
||||||
} /* clean_up */
|
} /* clean_up */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is mainly needed when running with purify, but it's still nice to
|
||||||
|
know that all child threads have died when mysqld exits
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void wait_for_signal_thread_to_end()
|
||||||
|
{
|
||||||
|
#ifndef __NETWARE__
|
||||||
|
uint i;
|
||||||
|
/*
|
||||||
|
Wait up to 10 seconds for signal thread to die. We use this mainly to
|
||||||
|
avoid getting warnings that my_thread_end has not been called
|
||||||
|
*/
|
||||||
|
for (i= 0 ; i < 100 && signal_thread_in_use; i++)
|
||||||
|
{
|
||||||
|
if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
|
||||||
|
break;
|
||||||
|
my_sleep(100); // Give it time to die
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void clean_up_mutexes()
|
static void clean_up_mutexes()
|
||||||
{
|
{
|
||||||
(void) pthread_mutex_destroy(&LOCK_mysql_create_db);
|
(void) pthread_mutex_destroy(&LOCK_mysql_create_db);
|
||||||
|
@ -2146,6 +2171,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
|
||||||
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
|
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
|
||||||
if (cleanup_done)
|
if (cleanup_done)
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
signal_thread_in_use= 0;
|
signal_thread_in_use= 0;
|
||||||
pthread_exit(0); // Safety
|
pthread_exit(0); // Safety
|
||||||
|
@ -3176,21 +3202,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
||||||
CloseHandle(hEventShutdown);
|
CloseHandle(hEventShutdown);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef __NETWARE__
|
wait_for_signal_thread_to_end();
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
/*
|
|
||||||
Wait up to 10 seconds for signal thread to die. We use this mainly to
|
|
||||||
avoid getting warnings that my_thread_end has not been called
|
|
||||||
*/
|
|
||||||
for (i= 0 ; i < 100 && signal_thread_in_use; i++)
|
|
||||||
{
|
|
||||||
if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
|
|
||||||
break;
|
|
||||||
my_sleep(100); // Give it time to die
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
clean_up_mutexes();
|
clean_up_mutexes();
|
||||||
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
||||||
|
|
||||||
|
|
|
@ -668,7 +668,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
|
||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
|
thd->server_status|= SERVER_STATUS_DB_DROPPED;
|
||||||
send_ok(thd, (ulong) deleted);
|
send_ok(thd, (ulong) deleted);
|
||||||
|
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
|
@ -948,7 +948,8 @@ public:
|
||||||
thd.current_tablenr=0;
|
thd.current_tablenr=0;
|
||||||
thd.version=refresh_version;
|
thd.version=refresh_version;
|
||||||
thd.command=COM_DELAYED_INSERT;
|
thd.command=COM_DELAYED_INSERT;
|
||||||
thd.lex->current_select= 0; /* for my_message_sql */
|
thd.lex->current_select= 0; // for my_message_sql
|
||||||
|
thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
|
||||||
|
|
||||||
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
|
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
|
||||||
bzero((char*) &table_list, sizeof(table_list)); // Safety
|
bzero((char*) &table_list, sizeof(table_list)); // Safety
|
||||||
|
|
|
@ -171,27 +171,46 @@ enum tablespace_op_type
|
||||||
/*
|
/*
|
||||||
The state of the lex parsing for selects
|
The state of the lex parsing for selects
|
||||||
|
|
||||||
All select describing structures linked with following pointers:
|
master and slaves are pointers to select_lex.
|
||||||
- list of neighbors (next/prev) (prev of first element point to slave
|
master is pointer to upper level node.
|
||||||
pointer of upper structure)
|
slave is pointer to lower level node
|
||||||
- one level units for unit (union) structure
|
select_lex is a SELECT without union
|
||||||
- member of one union(unit) for ordinary select_lex
|
unit is container of either
|
||||||
- pointer to master
|
- One SELECT
|
||||||
- outer select_lex for unit (union)
|
- UNION of selects
|
||||||
- unit structure for ordinary select_lex
|
select_lex and unit are both inherited form select_lex_node
|
||||||
- pointer to slave
|
neighbors are two select_lex or units on the same level
|
||||||
- first list element of select_lex belonged to this unit for unit
|
|
||||||
- first unit in list of units that belong to this select_lex (as
|
|
||||||
subselects or derived tables) for ordinary select_lex
|
|
||||||
- list of all select_lex (for group operation like correcting list of opened
|
|
||||||
tables)
|
|
||||||
- if unit contain several selects (union) then it have special
|
|
||||||
select_lex called fake_select_lex. It used for storing global parameters
|
|
||||||
and executing union. subqueries of global ORDER BY clause will be
|
|
||||||
attached to this fake_select_lex, which will allow them correctly
|
|
||||||
resolve fields of 'upper' union and other more outer selects.
|
|
||||||
|
|
||||||
for example for following query:
|
All select describing structures linked with following pointers:
|
||||||
|
- list of neighbors (next/prev) (prev of first element point to slave
|
||||||
|
pointer of upper structure)
|
||||||
|
- For select this is a list of UNION's (or one element list)
|
||||||
|
- For units this is a list of sub queries for the upper level select
|
||||||
|
|
||||||
|
- pointer to master (master), which is
|
||||||
|
If this is a unit
|
||||||
|
- pointer to outer select_lex
|
||||||
|
If this is a select_lex
|
||||||
|
- pointer to outer unit structure for select
|
||||||
|
|
||||||
|
- pointer to slave (slave), which is either:
|
||||||
|
If this is a unit:
|
||||||
|
- first SELECT that belong to this unit
|
||||||
|
If this is a select_lex
|
||||||
|
- first unit that belong to this SELECT (subquries or derived tables)
|
||||||
|
|
||||||
|
- list of all select_lex (link_next/link_prev)
|
||||||
|
This is to be used for things like derived tables creation, where we
|
||||||
|
go through this list and create the derived tables.
|
||||||
|
|
||||||
|
If unit contain several selects (UNION now, INTERSECT etc later)
|
||||||
|
then it have special select_lex called fake_select_lex. It used for
|
||||||
|
storing global parameters (like ORDER BY, LIMIT) and executing union.
|
||||||
|
Subqueries used in global ORDER BY clause will be attached to this
|
||||||
|
fake_select_lex, which will allow them correctly resolve fields of
|
||||||
|
'upper' UNION and outer selects.
|
||||||
|
|
||||||
|
For example for following query:
|
||||||
|
|
||||||
select *
|
select *
|
||||||
from table1
|
from table1
|
||||||
|
@ -209,6 +228,11 @@ enum tablespace_op_type
|
||||||
|
|
||||||
we will have following structure:
|
we will have following structure:
|
||||||
|
|
||||||
|
select1: (select * from table1 ...)
|
||||||
|
select2: (select * from table2 ...)
|
||||||
|
select3: (select * from table3)
|
||||||
|
select1.1.1: (select * from table1_1_1)
|
||||||
|
...
|
||||||
|
|
||||||
main unit
|
main unit
|
||||||
fake0
|
fake0
|
||||||
|
@ -231,7 +255,12 @@ enum tablespace_op_type
|
||||||
|
|
||||||
|
|
||||||
relation in main unit will be following:
|
relation in main unit will be following:
|
||||||
|
(bigger picture for:
|
||||||
|
main unit
|
||||||
|
fake0
|
||||||
|
select1 select2 select3
|
||||||
|
in the above picture)
|
||||||
|
|
||||||
main unit
|
main unit
|
||||||
|^^^^|fake_select_lex
|
|^^^^|fake_select_lex
|
||||||
|||||+--------------------------------------------+
|
|||||+--------------------------------------------+
|
||||||
|
@ -427,7 +456,7 @@ public:
|
||||||
typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SELECT_LEX - store information of parsed SELECT_LEX statment
|
SELECT_LEX - store information of parsed SELECT statment
|
||||||
*/
|
*/
|
||||||
class st_select_lex: public st_select_lex_node
|
class st_select_lex: public st_select_lex_node
|
||||||
{
|
{
|
||||||
|
|
|
@ -214,7 +214,7 @@ bool log_in_use(const char* log_name)
|
||||||
if ((linfo = tmp->current_linfo))
|
if ((linfo = tmp->current_linfo))
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&linfo->lock);
|
pthread_mutex_lock(&linfo->lock);
|
||||||
result = !memcmp(log_name, linfo->log_file_name, log_name_len);
|
result = !bcmp(log_name, linfo->log_file_name, log_name_len);
|
||||||
pthread_mutex_unlock(&linfo->lock);
|
pthread_mutex_unlock(&linfo->lock);
|
||||||
if (result)
|
if (result)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -10920,8 +10920,8 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||||
{
|
{
|
||||||
byte *key_buffer, *key_pos, *record=table->record[0];
|
byte *key_buffer, *key_pos, *record=table->record[0];
|
||||||
int error;
|
int error;
|
||||||
handler *file=table->file;
|
handler *file= table->file;
|
||||||
ulong extra_length=ALIGN_SIZE(key_length)-key_length;
|
ulong extra_length= ALIGN_SIZE(key_length)-key_length;
|
||||||
uint *field_lengths,*field_length;
|
uint *field_lengths,*field_length;
|
||||||
HASH hash;
|
HASH hash;
|
||||||
DBUG_ENTER("remove_dup_with_hash_index");
|
DBUG_ENTER("remove_dup_with_hash_index");
|
||||||
|
@ -10935,22 +10935,34 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||||
NullS))
|
NullS))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
{
|
||||||
|
Field **ptr;
|
||||||
|
ulong total_length= 0;
|
||||||
|
for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
|
||||||
|
{
|
||||||
|
uint length= (*ptr)->pack_length();
|
||||||
|
(*field_length++)= length;
|
||||||
|
total_length+= length;
|
||||||
|
}
|
||||||
|
DBUG_PRINT("info",("field_count: %u key_length: %lu total_length: %lu",
|
||||||
|
field_count, key_length, total_length));
|
||||||
|
DBUG_ASSERT(total_length <= key_length);
|
||||||
|
key_length= total_length;
|
||||||
|
extra_length= ALIGN_SIZE(key_length)-key_length;
|
||||||
|
}
|
||||||
|
|
||||||
if (hash_init(&hash, &my_charset_bin, (uint) file->records, 0,
|
if (hash_init(&hash, &my_charset_bin, (uint) file->records, 0,
|
||||||
key_length,(hash_get_key) 0, 0, 0))
|
key_length, (hash_get_key) 0, 0, 0))
|
||||||
{
|
{
|
||||||
my_free((char*) key_buffer,MYF(0));
|
my_free((char*) key_buffer,MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
Field **ptr;
|
|
||||||
for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
|
|
||||||
(*field_length++)= (*ptr)->pack_length();
|
|
||||||
}
|
|
||||||
|
|
||||||
file->ha_rnd_init(1);
|
file->ha_rnd_init(1);
|
||||||
key_pos=key_buffer;
|
key_pos=key_buffer;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
byte *org_key_pos;
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
{
|
{
|
||||||
thd->send_kill_message();
|
thd->send_kill_message();
|
||||||
|
@ -10973,6 +10985,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy fields to key buffer */
|
/* copy fields to key buffer */
|
||||||
|
org_key_pos= key_pos;
|
||||||
field_length=field_lengths;
|
field_length=field_lengths;
|
||||||
for (Field **ptr= first_field ; *ptr ; ptr++)
|
for (Field **ptr= first_field ; *ptr ; ptr++)
|
||||||
{
|
{
|
||||||
|
@ -10980,14 +10993,14 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||||
key_pos+= *field_length++;
|
key_pos+= *field_length++;
|
||||||
}
|
}
|
||||||
/* Check if it exists before */
|
/* Check if it exists before */
|
||||||
if (hash_search(&hash,key_pos-key_length,key_length))
|
if (hash_search(&hash, org_key_pos, key_length))
|
||||||
{
|
{
|
||||||
/* Duplicated found ; Remove the row */
|
/* Duplicated found ; Remove the row */
|
||||||
if ((error=file->delete_row(record)))
|
if ((error=file->delete_row(record)))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(void) my_hash_insert(&hash, key_pos-key_length);
|
(void) my_hash_insert(&hash, org_key_pos);
|
||||||
key_pos+=extra_length;
|
key_pos+=extra_length;
|
||||||
}
|
}
|
||||||
my_free((char*) key_buffer,MYF(0));
|
my_free((char*) key_buffer,MYF(0));
|
||||||
|
|
|
@ -545,7 +545,6 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
register unsigned int cutlim;
|
register unsigned int cutlim;
|
||||||
register ulonglong i;
|
register ulonglong i;
|
||||||
register const char *s, *e;
|
register const char *s, *e;
|
||||||
register unsigned char c;
|
|
||||||
const char *save;
|
const char *save;
|
||||||
int overflow;
|
int overflow;
|
||||||
|
|
||||||
|
@ -608,8 +607,9 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
|
||||||
overflow = 0;
|
overflow = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
for (c = *s; s != e; c = *++s)
|
for ( ; s != e; s++)
|
||||||
{
|
{
|
||||||
|
register unsigned char c= *s;
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='Z')
|
else if (c>='A' && c<='Z')
|
||||||
|
@ -668,7 +668,6 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
|
||||||
register unsigned int cutlim;
|
register unsigned int cutlim;
|
||||||
register ulonglong i;
|
register ulonglong i;
|
||||||
register const char *s, *e;
|
register const char *s, *e;
|
||||||
register unsigned char c;
|
|
||||||
const char *save;
|
const char *save;
|
||||||
int overflow;
|
int overflow;
|
||||||
|
|
||||||
|
@ -731,8 +730,10 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
|
||||||
|
|
||||||
overflow = 0;
|
overflow = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
for (c = *s; s != e; c = *++s)
|
for ( ; s != e; s++)
|
||||||
{
|
{
|
||||||
|
register unsigned char c= *s;
|
||||||
|
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='Z')
|
else if (c>='A' && c<='Z')
|
||||||
|
|
Loading…
Add table
Reference in a new issue