Commit f5e57076 authored by joreland@mysql.com's avatar joreland@mysql.com

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/jonas/src/mysql-4.1
parents 5df05b72 60385695
......@@ -20,7 +20,7 @@ release_flags="-fast +O3"
# note on pointers below.
cflags="-g -z +O0"
cxxflags="-g0 -z +O0"
debug_conigure_options="--with-debug"
debug_configure_options="--with-debug"
while [ "$#" != 0 ]; do
case "$1" in
......
......@@ -423,6 +423,10 @@ SOURCE=..\mysys\my_static.c
# End Source File
# Begin Source File
SOURCE=..\strings\my_strtoll10.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_symlink.c
# End Source File
# Begin Source File
......
......@@ -383,6 +383,10 @@ SOURCE=..\mysys\my_static.c
# End Source File
# Begin Source File
SOURCE=..\strings\my_strtoll10.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_symlink.c
# End Source File
# Begin Source File
......
......@@ -264,7 +264,6 @@ static int write_to_table(char *filename, MYSQL *sock)
{
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
sql_statement[FN_REFLEN*16+256], *end;
my_bool local_file;
DBUG_ENTER("write_to_table");
DBUG_PRINT("enter",("filename: %s",filename));
......
......@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 4.1.6-gamma)
AM_INIT_AUTOMAKE(mysql, 4.1.7-gamma)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
......
......@@ -713,7 +713,7 @@ typedef void *gptr; /* Generic pointer */
typedef char *gptr; /* Generic pointer */
#endif
#ifndef HAVE_INT_8_16_32
typedef char int8; /* Signed integer >= 8 bits */
typedef signed char int8; /* Signed integer >= 8 bits */
typedef short int16; /* Signed integer >= 16 bits */
#endif
#ifndef HAVE_UCHAR
......
......@@ -3196,24 +3196,20 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
read_binary_{date,time,datetime}()
tm MYSQL_TIME structure to fill
pos pointer to current position in network buffer.
These functions increase pos to point to the beginning of this
field (this is just due to implementation of net_field_length
which is used to get length of binary representation of
time value).
These functions increase pos to point to the beginning of the
next column.
Auxiliary functions to read time (date, datetime) values from network
buffer and store in MYSQL_TIME structure. Jointly used by conversion
and no-conversion fetching.
*/
static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
static void read_binary_time(MYSQL_TIME *tm, uchar **pos)
{
uint length;
/* net_field_length will set pos to the first byte of data */
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
uint length= net_field_length(pos);
if (length)
{
uchar *to= *pos;
tm->neg= (bool) to[0];
......@@ -3226,17 +3222,18 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
tm->year= tm->month= 0;
tm->time_type= MYSQL_TIMESTAMP_TIME;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
{
uint length;
uint length= net_field_length(pos);
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
if (length)
{
uchar *to= *pos;
......@@ -3255,17 +3252,18 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
tm->hour= tm->minute= tm->second= 0;
tm->second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
tm->time_type= MYSQL_TIMESTAMP_DATETIME;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
{
uint length;
uint length= net_field_length(pos);
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
if (length)
{
uchar *to= *pos;
tm->year = (uint) sint2korr(to);
......@@ -3276,8 +3274,11 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
tm->second_part= 0;
tm->neg= 0;
tm->time_type= MYSQL_TIMESTAMP_DATE;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
......@@ -3604,18 +3605,18 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
uchar **row)
{
ulong length;
enum enum_field_types field_type= field->type;
uint field_is_unsigned= field->flags & UNSIGNED_FLAG;
switch (field_type) {
case MYSQL_TYPE_TINY:
{
char value= (char) **row;
longlong data= field_is_unsigned ? (longlong) (unsigned char) value :
(longlong) value;
uchar value= **row;
/* sic: we need to cast to 'signed char' as 'char' may be unsigned */
longlong data= field_is_unsigned ? (longlong) value :
(longlong) (signed char) value;
fetch_long_with_conversion(param, field, data);
length= 1;
*row+= 1;
break;
}
case MYSQL_TYPE_SHORT:
......@@ -3625,7 +3626,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong data= field_is_unsigned ? (longlong) (unsigned short) value :
(longlong) value;
fetch_long_with_conversion(param, field, data);
length= 2;
*row+= 2;
break;
}
case MYSQL_TYPE_INT24: /* mediumint is sent as 4 bytes int */
......@@ -3635,14 +3636,14 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong data= field_is_unsigned ? (longlong) (unsigned long) value :
(longlong) value;
fetch_long_with_conversion(param, field, data);
length= 4;
*row+= 4;
break;
}
case MYSQL_TYPE_LONGLONG:
{
longlong value= (longlong)sint8korr(*row);
fetch_long_with_conversion(param, field, value);
length= 8;
*row+= 8;
break;
}
case MYSQL_TYPE_FLOAT:
......@@ -3650,7 +3651,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
float value;
float4get(value,*row);
fetch_float_with_conversion(param, field, value, FLT_DIG);
length= 4;
*row+= 4;
break;
}
case MYSQL_TYPE_DOUBLE:
......@@ -3658,14 +3659,14 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
double value;
float8get(value,*row);
fetch_float_with_conversion(param, field, value, DBL_DIG);
length= 8;
*row+= 8;
break;
}
case MYSQL_TYPE_DATE:
{
MYSQL_TIME tm;
length= read_binary_date(&tm, row);
read_binary_date(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
......@@ -3673,7 +3674,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
{
MYSQL_TIME tm;
length= read_binary_time(&tm, row);
read_binary_time(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
......@@ -3682,16 +3683,18 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
{
MYSQL_TIME tm;
length= read_binary_datetime(&tm, row);
read_binary_datetime(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
default:
length= net_field_length(row);
{
ulong length= net_field_length(row);
fetch_string_with_conversion(param, (char*) *row, length);
*row+= length;
break;
}
*row+= length;
}
}
......@@ -3760,19 +3763,19 @@ static void fetch_result_double(MYSQL_BIND *param, uchar **row)
static void fetch_result_time(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_time(tm, row);
read_binary_time(tm, row);
}
static void fetch_result_date(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_date(tm, row);
read_binary_date(tm, row);
}
static void fetch_result_datetime(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_datetime(tm, row);
read_binary_datetime(tm, row);
}
static void fetch_result_bin(MYSQL_BIND *param, uchar **row)
......
......@@ -750,3 +750,43 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
id
4
DROP TABLE t1;
SET NAMES latin1;
CREATE TABLE t1 (
id int unsigned NOT NULL auto_increment,
list_id smallint unsigned NOT NULL,
term text NOT NULL,
PRIMARY KEY(id),
INDEX(list_id, term(19))
) TYPE=MyISAM CHARSET=utf8;
Warnings:
Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
INSERT INTO t1 set list_id = 1, term = "testtest";
INSERT INTO t1 set list_id = 1, term = "testetest";
INSERT INTO t1 set list_id = 1, term = "testtest";
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testtest");
id term
1 testtest
2 testetest
3 testtest
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testetest");
id term
1 testtest
2 testetest
3 testtest
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testtest");
id term
1 testtest
2 testetest
3 testtest
DROP TABLE t1;
set names utf8;
create table t1 (
a int primary key,
b varchar(6),
index b3(b(3))
) engine=innodb character set=utf8;
insert into t1 values(1,'foo'),(2,'foobar');
select * from t1 where b like 'foob%';
a b
2 foobar
drop table t1;
......@@ -336,3 +336,42 @@ id select_type table type possible_keys key key_len ref rows Extra
- - - - - - - - NULL Impossible WHERE
drop table t1;
deallocate prepare stmt;
create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4);
set @precision=10000000000;
select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer) from t1;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer)
- 6570515219 -
- 1282061302 -
- 6698761160 -
- 9647622201 -
prepare stmt from
"select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer),
cast(rand(?)*@precision as unsigned integer) from t1";
set @var=1;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 - 4054035371
- 1282061302 - 8716141803
- 6698761160 - 1418603212
- 9647622201 - 944590960
set @var=2;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 1559528654 6555866465
- 1282061302 6238114970 1223466192
- 6698761160 6511989195 6449731873
- 9647622201 3845601374 8578261098
set @var=3;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 1559528654 9057697559
- 1282061302 6238114970 3730790581
- 6698761160 6511989195 1480860534
- 9647622201 3845601374 6211931236
drop table t1;
deallocate prepare stmt;
......@@ -221,7 +221,9 @@ drop table t1;
# Bug 4521: unique key prefix interacts poorly with utf8
# InnoDB: keys with prefix compression, case insensitive collation.
#
--disable_warnings
create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb;
--enable_warnings
insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z');
insert into t1 values ('aaaaaaaaaa');
--error 1062
......@@ -269,7 +271,9 @@ drop table t1;
# Bug 4521: unique key prefix interacts poorly with utf8
# InnoDB: fixed length keys, case insensitive collation
#
--disable_warnings
create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb;
--enable_warnings
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
insert into t1 values ('a');
insert into t1 values ('aa');
......@@ -504,10 +508,12 @@ drop table t1;
# Bug#4594: column index make = failed for gbk, but like works
# Check InnoDB
#
--disable_warnings
create table t1 (
str varchar(255) character set utf8 not null,
key str (str(2))
) engine=innodb;
--enable_warnings
INSERT INTO t1 VALUES ('str');
INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str';
......@@ -563,10 +569,12 @@ DROP TABLE t1;
# Bug #5723: length(<varchar utf8 field>) returns varying results
#
SET NAMES utf8;
--disable_warnings
CREATE TABLE t1 (
subject varchar(255) character set utf8 collate utf8_unicode_ci,
p varchar(15) character set utf8
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--enable_warnings
INSERT INTO t1 VALUES ('谷川俊二と申しますが、インターネット予約の会員登録をしましたところ、メールアドレスを間違えてしまい会員IDが受け取ることが出来ませんでした。間違えアドレスはtani-shun@n.vodafone.ne.jpを書き込みました。どうすればよいですか? その他、住所等は間違えありません。連絡ください。よろしくお願いします。m(__)m','040312-000057');
INSERT INTO t1 VALUES ('aaa','bbb');
SELECT length(subject) FROM t1;
......@@ -592,3 +600,38 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterb");
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
DROP TABLE t1;
#
# Bug #6043 erratic searching for diacriticals in indexed MyISAM UTF-8 table
#
SET NAMES latin1;
CREATE TABLE t1 (
id int unsigned NOT NULL auto_increment,
list_id smallint unsigned NOT NULL,
term text NOT NULL,
PRIMARY KEY(id),
INDEX(list_id, term(19))
) TYPE=MyISAM CHARSET=utf8;
INSERT INTO t1 set list_id = 1, term = "testtest";
INSERT INTO t1 set list_id = 1, term = "testetest";
INSERT INTO t1 set list_id = 1, term = "testtest";
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testtest");
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testetest");
SELECT id, term FROM t1 where (list_id = 1) AND (term = "testtest");
DROP TABLE t1;
#
# Bug #6019 SELECT tries to use too short prefix index on utf8 data
#
set names utf8;
--disable_warnings
create table t1 (
a int primary key,
b varchar(6),
index b3(b(3))
) engine=innodb character set=utf8;
--enable_warnings
insert into t1 values(1,'foo'),(2,'foobar');
select * from t1 where b like 'foob%';
drop table t1;
......@@ -363,4 +363,30 @@ execute stmt using @v;
drop table t1;
deallocate prepare stmt;
#
# A test case for Bug#5985 prepare stmt from "select rand(?)" crashes
# server. Check that Item_func_rand is prepared-statements friendly.
#
create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4);
set @precision=10000000000;
--replace_column 1 - 3 -
select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer) from t1;
prepare stmt from
"select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer),
cast(rand(?)*@precision as unsigned integer) from t1";
set @var=1;
--replace_column 1 - 3 -
execute stmt using @var;
set @var=2;
--replace_column 1 -
execute stmt using @var;
set @var=3;
--replace_column 1 -
execute stmt using @var;
drop table t1;
deallocate prepare stmt;
......@@ -5000,10 +5000,10 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
int Field_blob::cmp(const char *a,uint32 a_length, const char *b,
uint32 b_length)
{
int diff=my_strnncoll(field_charset,
(const uchar*)a,min(a_length,b_length),
(const uchar*)b,min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
return field_charset->coll->strnncoll(field_charset,
(const uchar*)a, a_length,
(const uchar*)b, b_length,
0);
}
......@@ -5087,8 +5087,8 @@ void Field_blob::get_key_image(char *buff,uint length,
get_ptr(&blob);
uint char_length= length / cs->mbmaxlen;
char_length= my_charpos(cs, blob, blob + length, char_length);
set_if_smaller(length, char_length);
char_length= my_charpos(cs, blob, blob + blob_length, char_length);
set_if_smaller(blob_length, char_length);
if ((uint32) length > blob_length)
{
......
......@@ -1010,21 +1010,38 @@ double Item_func_round::val()
}
void Item_func_rand::fix_length_and_dec()
bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
Item **ref)
{
decimals=NOT_FIXED_DEC;
max_length=float_length(decimals);
Item_real_func::fix_fields(thd, tables, ref);
used_tables_cache|= RAND_TABLE_BIT;
if (arg_count)
{ // Only use argument once in query
uint32 tmp= (uint32) (args[0]->val_int());
if ((rand= (struct rand_struct*) sql_alloc(sizeof(*rand))))
randominit(rand,(uint32) (tmp*0x10001L+55555555L),
/*
Allocate rand structure once: we must use thd->current_arena
to create rand in proper mem_root if it's a prepared statement or
stored procedure.
*/
if (!rand && !(rand= (struct rand_struct*)
thd->current_arena->alloc(sizeof(*rand))))
return TRUE;
/*
PARAM_ITEM is returned if we're in statement prepare and consequently
no placeholder value is set yet.
*/
if (args[0]->type() != PARAM_ITEM)
{
/*
TODO: do not do reinit 'rand' for every execute of PS/SP if
args[0] is a constant.
*/
uint32 tmp= (uint32) args[0]->val_int();
randominit(rand, (uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L));
}
}
else
{
THD *thd= current_thd;
/*
No need to send a Rand log event if seed was given eg: RAND(seed),
as it will be replicated in the query as such.
......@@ -1038,6 +1055,7 @@ void Item_func_rand::fix_length_and_dec()
thd->rand_saved_seed2=thd->rand.seed2;
rand= &thd->rand;
}
return FALSE;
}
void Item_func_rand::update_used_tables()
......
......@@ -512,13 +512,13 @@ class Item_func_rand :public Item_real_func
{
struct rand_struct *rand;
public:
Item_func_rand(Item *a) :Item_real_func(a) {}
Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
Item_func_rand() :Item_real_func() {}
double val();
const char *func_name() const { return "rand"; }
bool const_item() const { return 0; }
void update_used_tables();
void fix_length_and_dec();
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
};
......
......@@ -1284,7 +1284,8 @@ int subselect_uniquesubquery_engine::exec()
error= table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND)
if (error &&
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
error= report_error(table, error);
else
{
......@@ -1336,7 +1337,8 @@ int subselect_indexsubquery_engine::exec()
error= table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND)
if (error &&
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
error= report_error(table, error);
else
{
......
......@@ -447,6 +447,7 @@ bool is_update_query(enum enum_sql_command command);
bool alloc_query(THD *thd, char *packet, ulong packet_length);
void mysql_init_select(LEX *lex);
void mysql_init_query(THD *thd, uchar *buf, uint length);
void mysql_reset_thd_for_next_command(THD *thd);
bool mysql_new_select(LEX *lex, bool move_down);
void create_select_for_variable(const char *var_name);
void mysql_init_multi_delete(LEX *lex);
......
......@@ -1498,7 +1498,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
}
void Statement::end_statement()
void THD::end_statement()
{
/* Cleanup SQL processing state to resuse this statement in next query. */
lex_end(lex);
......
......@@ -582,12 +582,6 @@ public:
void restore_backup_statement(Statement *stmt, Statement *backup);
/* return class type */
virtual Type type() const;
/*
Cleanup statement parse state (parse tree, lex) after execution of
a non-prepared SQL statement.
*/
void end_statement();
};
......@@ -1063,6 +1057,12 @@ public:
void nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot);
void rollback_item_tree_changes();
/*
Cleanup statement parse state (parse tree, lex) and execution
state after execution of a non-prepared SQL statement.
*/
void end_statement();
};
/* Flags for the THD::system_thread (bitmap) variable */
......
......@@ -117,7 +117,30 @@ void lex_free(void)
void lex_start(THD *thd, uchar *buf,uint length)
{
LEX *lex= thd->lex;
lex->unit.init_query();
lex->unit.init_select();
lex->thd= thd;
lex->unit.thd= thd;
lex->select_lex.init_query();
lex->value_list.empty();
lex->param_list.empty();
lex->unit.next= lex->unit.master=
lex->unit.link_next= lex->unit.return_to= 0;
lex->unit.prev= lex->unit.link_prev= 0;
lex->unit.slave= lex->unit.global_parameters= lex->current_select=
lex->all_selects_list= &lex->select_lex;
lex->select_lex.master= &lex->unit;
lex->select_lex.prev= &lex->unit.slave;
lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
lex->select_lex.options= 0;
lex->describe= 0;
lex->derived_tables= FALSE;
lex->lock_option= TL_READ;
lex->found_colon= 0;
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
lex->select_lex.select_number= 1;
lex->next_state=MY_LEX_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
......
......@@ -369,7 +369,7 @@ public:
ulong init_prepare_fake_select_lex(THD *thd);
int change_result(select_subselect *result, select_subselect *old_result);
friend void mysql_init_query(THD *thd, uchar *buf, uint length);
friend void lex_start(THD *thd, uchar *buf, uint length);
friend int subselect_union_engine::exec();
private:
bool create_total_list_n_last_return(THD *thd, st_lex *lex,
......@@ -508,7 +508,7 @@ public:
bool test_limit();
friend void mysql_init_query(THD *thd, uchar *buf, uint length);
friend void lex_start(THD *thd, uchar *buf, uint length);
st_select_lex() {}
void make_empty_select()
{
......
......@@ -1001,16 +1001,15 @@ pthread_handler_decl(handle_one_connection,arg)
net->compress=1; // Use compression
thd->version= refresh_version;
thd->proc_info= 0;
thd->set_time();
thd->init_for_queries();
if (sys_init_connect.value_length && !(thd->master_access & SUPER_ACL))
{
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
if (thd->query_error)
thd->killed= 1;
}
thd->proc_info=0;
thd->set_time();
thd->init_for_queries();
while (!net->error && net->vio != 0 && !thd->killed)
{
if (do_command(thd))
......@@ -3854,7 +3853,6 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
return 0;
}
/****************************************************************************
Initialize global thd variables needed for query
****************************************************************************/
......@@ -3863,33 +3861,31 @@ void
mysql_init_query(THD *thd, uchar *buf, uint length)
{
DBUG_ENTER("mysql_init_query");
LEX *lex= thd->lex;
lex->unit.init_query();
lex->unit.init_select();
lex->unit.thd= thd;
lex->select_lex.init_query();
lex->value_list.empty();
lex->param_list.empty();
lex->unit.next= lex->unit.master=
lex->unit.link_next= lex->unit.return_to=0;
lex->unit.prev= lex->unit.link_prev= 0;
lex->unit.slave= lex->unit.global_parameters= lex->current_select=
lex->all_selects_list= &lex->select_lex;
lex->select_lex.master= &lex->unit;
lex->select_lex.prev= &lex->unit.slave;
lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
lex->select_lex.options=0;
lex->describe= 0;
lex->derived_tables= FALSE;
lex->lock_option= TL_READ;
lex->found_colon= 0;
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
lex_start(thd, buf, length);
thd->select_number= lex->select_lex.select_number= 1;
mysql_reset_thd_for_next_command(thd);
DBUG_VOID_RETURN;
}
/*
Reset THD part responsible for command processing state.
DESCRIPTION
This needs to be called before execution of every statement
(prepared or conventional).
TODO
Make it a method of THD and align its name with the rest of
reset/end/start/init methods.
Call it after we use THD for queries, not before.
*/
void mysql_reset_thd_for_next_command(THD *thd)
{
DBUG_ENTER("mysql_reset_thd_for_next_command");
thd->free_list= 0;
thd->total_warn_count=0; // Warnings for this query
thd->select_number= 1;
thd->total_warn_count= 0; // Warnings for this query
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
thd->sent_row_count= thd->examined_row_count= 0;
thd->is_fatal_error= thd->rand_used= thd->time_zone_used= 0;
......
......@@ -1760,6 +1760,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
DBUG_VOID_RETURN;
}
DBUG_ASSERT(thd->free_list == NULL);
mysql_reset_thd_for_next_command(thd);
#ifndef EMBEDDED_LIBRARY
if (stmt->param_count)
{
......@@ -1778,7 +1780,6 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query))
goto set_params_data_err;
#endif
DBUG_ASSERT(thd->free_list == NULL);
thd->protocol= &thd->protocol_prep; // Switch to binary protocol
execute_stmt(thd, stmt, &expanded_query, true);
thd->protocol= &thd->protocol_simple; // Use normal protocol
......@@ -1823,7 +1824,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
}
DBUG_ASSERT(thd->free_list == NULL);
/* Must go before setting variables, as it clears thd->user_var_events */
mysql_reset_thd_for_next_command(thd);
thd->set_n_backup_statement(stmt, &thd->stmt_backup);
if (stmt->set_params_from_vars(stmt,
thd->stmt_backup.lex->prepared_stmt_params,
......@@ -1932,6 +1934,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
*/
reset_stmt_params(stmt);
mysql_reset_thd_for_next_command(thd);
send_ok(thd);
DBUG_VOID_RETURN;
......
......@@ -499,6 +499,10 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
{
char buf[10];
uint buflen;
uint charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen);
if (charlen < (uint) (min_str - min_org))
min_str= min_org + charlen;
/* Write min key */
*min_length= (uint) (min_str - min_org);
......
......@@ -2059,7 +2059,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
my_strnncoll_utf8,
my_strnncollsp_utf8,
my_strnxfrm_utf8,
my_like_range_simple,
my_like_range_mb,
my_wildcmp_mb,
my_strcasecmp_utf8,
my_instr_mb,
......@@ -2119,7 +2119,7 @@ CHARSET_INFO my_charset_utf8_general_ci=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
255, /* max_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
&my_collation_ci_handler
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment