merge with 4.1

BitKeeper/etc/ignore:
  auto-union
BitKeeper/etc/logging_ok:
  auto-union
client/mysql.cc:
  Auto merged
client/mysqldump.c:
  Auto merged
innobase/dict/dict0dict.c:
  Auto merged
innobase/fil/fil0fil.c:
  Auto merged
innobase/row/row0sel.c:
  Auto merged
mysql-test/r/select_found.result:
  Auto merged
mysql-test/r/type_set.result:
  Auto merged
mysys/default.c:
  Auto merged
sql/field.h:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_db.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
strings/ctype-simple.c:
  Auto merged
include/mysql_com.h:
  Merge
sql/filesort.cc:
  merge
This commit is contained in:
unknown 2005-02-28 12:18:39 +02:00
commit 45a26d449d
21 changed files with 191 additions and 88 deletions

View file

@ -1593,6 +1593,22 @@ static int reconnect(void)
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
@ -1917,6 +1933,10 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (err >= 1)
error= put_error(&mysql);
if (!error && !status.batch &&
(mysql.server_status & SERVER_STATUS_DB_DROPPED))
get_current_db();
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
(latter one not yet available by the time the comment was written)
*/
/* Let's reset current_db, assume it's gone */
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);
}
get_current_db();
if (!current_db || cmp_database(charset_info, current_db,tmp))
{

View file

@ -865,6 +865,11 @@ static int dbConnect(char *host, char *user,char *passwd)
DBerror(&mysql_connection, "when trying to connect");
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
cannot reconnect.

View file

@ -147,6 +147,7 @@ enum enum_server_command
COM_FETCH command.
*/
#define SERVER_STATUS_LAST_ROW_SENT 128
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
#define MYSQL_ERRMSG_SIZE 512
#define NET_READ_TIMEOUT 30 /* Timeout on read */

View file

@ -2719,7 +2719,8 @@ scan_more:
/* Starting quote: remember the quote character. */
quote = *sptr;
} else if (*sptr == '#'
|| (0 == memcmp("-- ", sptr, 3))) {
|| (sptr[0] == '-' && sptr[1] == '-' &&
sptr[2] == ' ')) {
for (;;) {
/* In Unix a newline is 0x0A while in Windows
it is 0x0D followed by 0x0A */

View file

@ -3817,13 +3817,6 @@ fil_io(
node = UT_LIST_GET_FIRST(space->chain);
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) {
fprintf(stderr,
"InnoDB: Error: trying to access page number %lu in space %lu,\n"
@ -3837,6 +3830,13 @@ fil_io(
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) {
/* Found! */
break;

View file

@ -3058,14 +3058,19 @@ row_search_for_mysql(
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(
"InnoDB: Error: MySQL is trying to perform a SELECT\n"
"InnoDB: but it has not locked any tables in ::external_lock()!\n",
stderr);
trx_print(stderr, trx);
fputc('\n', stderr);
ut_a(0);
}
/* fprintf(stderr, "Match mode %lu\n search tuple ", (ulong) match_mode);

View file

@ -254,3 +254,4 @@ a
SELECT FOUND_ROWS();
FOUND_ROWS()
1
DROP TABLE t1;

View file

@ -29,6 +29,12 @@ a
A
a,A
a,A
select s from t1 order by concat(s);
s
A
a
a,A
a,A
drop table t1;
CREATE TABLE t1 (c set('ae','oe','ue','ss') collate latin1_german2_ci);
INSERT INTO t1 VALUES ('ä'),('ö'),('ü'),('ß');
@ -47,4 +53,16 @@ ss
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;

View file

@ -175,3 +175,4 @@ CREATE TABLE t1 (a int, b int);
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 FOUND_ROWS();
DROP TABLE t1;

View file

@ -23,6 +23,7 @@ create table t1 (s set ('a','A') character set latin1 collate latin1_bin);
show create table t1;
insert into t1 values ('a'),('a,A'),('A,a'),('A');
select s from t1 order by s;
select s from t1 order by concat(s);
drop table t1;
#
@ -34,4 +35,5 @@ INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
INSERT INTO t1 VALUES ('ä,ö,ü,ß');
INSERT INTO t1 VALUES ('ae,oe,ue,ss');
SELECT c FROM t1 ORDER BY c;
SELECT c FROM t1 ORDER BY concat(c);
DROP TABLE t1;

View file

@ -145,6 +145,10 @@ void my_end(int infoflag)
{
#ifdef HAVE_GETRUSAGE
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))
fprintf(info_file,"\n\
User time %.2f, System time %.2f\n\

View file

@ -276,6 +276,7 @@ public:
virtual bool get_date(TIME *ltime,uint fuzzydate);
virtual bool get_time(TIME *ltime);
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 void set_charset(CHARSET_INFO *charset) { }
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 eq_def(Field *field);
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; }
};

View file

@ -1201,12 +1201,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
else
{
sortorder->length=sortorder->field->pack_length();
/*
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)
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
{
sortorder->need_strxnfrm= 1;
*multi_byte_charset= 1;

View file

@ -283,7 +283,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
comparators= 0;
return 1;
}
if (!(comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
if (!(comparators= new Arg_comparator[n]))
return 1;
for (uint i=0; i < n; i++)
{
@ -1825,6 +1825,12 @@ in_row::in_row(uint elements, Item * item)
size= sizeof(cmp_item_row);
compare= (qsort2_cmp) cmp_row;
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()

View file

@ -547,6 +547,7 @@ extern "C" pthread_handler_decl(handle_slave,arg);
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
static void clean_up(bool print_message);
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 void create_pid_file();
@ -938,6 +939,7 @@ extern "C" void unireg_abort(int exit_code)
sql_print_error("Aborting\n");
clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
wait_for_signal_thread_to_end();
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */
@ -1046,6 +1048,29 @@ void clean_up(bool print_message)
} /* 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()
{
(void) pthread_mutex_destroy(&LOCK_mysql_create_db);
@ -2141,6 +2166,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
if (cleanup_done)
{
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
my_thread_end();
signal_thread_in_use= 0;
pthread_exit(0); // Safety
@ -3171,21 +3197,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
CloseHandle(hEventShutdown);
}
#endif
#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
wait_for_signal_thread_to_end();
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);

View file

@ -668,7 +668,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
thd->clear_error();
mysql_bin_log.write(&qinfo);
}
thd->server_status|= SERVER_STATUS_DB_DROPPED;
send_ok(thd, (ulong) deleted);
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
}
exit:

View file

@ -948,7 +948,8 @@ public:
thd.current_tablenr=0;
thd.version=refresh_version;
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*) &table_list, sizeof(table_list)); // Safety

View file

@ -171,27 +171,46 @@ enum tablespace_op_type
/*
The state of the lex parsing for selects
master and slaves are pointers to select_lex.
master is pointer to upper level node.
slave is pointer to lower level node
select_lex is a SELECT without union
unit is container of either
- One SELECT
- UNION of selects
select_lex and unit are both inherited form select_lex_node
neighbors are two select_lex or units on the same level
All select describing structures linked with following pointers:
- list of neighbors (next/prev) (prev of first element point to slave
pointer of upper structure)
- one level units for unit (union) structure
- member of one union(unit) for ordinary select_lex
- pointer to master
- outer select_lex for unit (union)
- unit structure for ordinary select_lex
- pointer to slave
- 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 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
for example for following query:
- 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 *
from table1
@ -209,6 +228,11 @@ enum tablespace_op_type
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
fake0
@ -231,6 +255,11 @@ enum tablespace_op_type
relation in main unit will be following:
(bigger picture for:
main unit
fake0
select1 select2 select3
in the above picture)
main unit
|^^^^|fake_select_lex
@ -427,7 +456,7 @@ public:
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
{

View file

@ -214,7 +214,7 @@ bool log_in_use(const char* log_name)
if ((linfo = tmp->current_linfo))
{
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);
if (result)
break;

View file

@ -10921,22 +10921,34 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
NullS))
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,
key_length, (hash_get_key) 0, 0, 0))
{
my_free((char*) key_buffer,MYF(0));
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);
key_pos=key_buffer;
for (;;)
{
byte *org_key_pos;
if (thd->killed)
{
thd->send_kill_message();
@ -10959,6 +10971,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
}
/* copy fields to key buffer */
org_key_pos= key_pos;
field_length=field_lengths;
for (Field **ptr= first_field ; *ptr ; ptr++)
{
@ -10966,14 +10979,14 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
key_pos+= *field_length++;
}
/* 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 */
if ((error=file->delete_row(record)))
goto err;
}
else
(void) my_hash_insert(&hash, key_pos-key_length);
(void) my_hash_insert(&hash, org_key_pos);
key_pos+=extra_length;
}
my_free((char*) key_buffer,MYF(0));

View file

@ -545,7 +545,6 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
register unsigned int cutlim;
register ulonglong i;
register const char *s, *e;
register unsigned char c;
const char *save;
int overflow;
@ -608,8 +607,9 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
for ( ; s != e; s++)
{
register unsigned char c= *s;
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='Z')
@ -668,7 +668,6 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
register unsigned int cutlim;
register ulonglong i;
register const char *s, *e;
register unsigned char c;
const char *save;
int overflow;
@ -731,8 +730,10 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
for ( ; s != e; s++)
{
register unsigned char c= *s;
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='Z')