Commit 17a0c389 authored by unknown's avatar unknown

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0

into  poseidon.ndb.mysql.com:/home/tomas/mysql-5.0-main

parents 00f4ef12 2dd1dc62
...@@ -144,6 +144,10 @@ SOURCE=.\readline.cpp ...@@ -144,6 +144,10 @@ SOURCE=.\readline.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\mysys\my_conio.c
# End Source File
# Begin Source File
SOURCE=.\sql_string.cpp SOURCE=.\sql_string.cpp
# End Source File # End Source File
# End Target # End Target
......
...@@ -130,6 +130,10 @@ SOURCE=.\readline.cpp ...@@ -130,6 +130,10 @@ SOURCE=.\readline.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\mysys\my_conio.c
# End Source File
# Begin Source File
SOURCE=.\sql_string.cpp SOURCE=.\sql_string.cpp
# End Source File # End Source File
# End Target # End Target
......
...@@ -453,25 +453,24 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) ...@@ -453,25 +453,24 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
if ((uint) share->base.auto_key -1 == key) if ((uint) share->base.auto_key -1 == key)
{ {
/* Check that auto_increment key is bigger than max key value */ /* Check that auto_increment key is bigger than max key value */
ulonglong save_auto_value=info->s->state.auto_increment; ulonglong auto_increment;
info->s->state.auto_increment=0;
info->lastinx=key; info->lastinx=key;
_mi_read_key_record(info, 0L, info->rec_buff); _mi_read_key_record(info, 0L, info->rec_buff);
update_auto_increment(info, info->rec_buff); auto_increment= retrieve_auto_increment(info, info->rec_buff);
if (info->s->state.auto_increment > save_auto_value) if (auto_increment > info->s->state.auto_increment)
{ {
mi_check_print_warning(param, mi_check_print_warning(param, "Auto-increment value: %s is smaller "
"Auto-increment value: %s is smaller than max used value: %s", "than max used value: %s",
llstr(save_auto_value,buff2), llstr(info->s->state.auto_increment,buff2),
llstr(info->s->state.auto_increment, buff)); llstr(auto_increment, buff));
} }
if (param->testflag & T_AUTO_INC) if (param->testflag & T_AUTO_INC)
{ {
set_if_bigger(info->s->state.auto_increment, set_if_bigger(info->s->state.auto_increment,
param->auto_increment_value); auto_increment);
set_if_bigger(info->s->state.auto_increment,
param->auto_increment_value);
} }
else
info->s->state.auto_increment=save_auto_value;
/* Check that there isn't a row with auto_increment = 0 in the table */ /* Check that there isn't a row with auto_increment = 0 in the table */
mi_extra(info,HA_EXTRA_KEYREAD,0); mi_extra(info,HA_EXTRA_KEYREAD,0);
...@@ -481,8 +480,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) ...@@ -481,8 +480,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
{ {
/* Don't count this as a real warning, as myisamchk can't correct it */ /* Don't count this as a real warning, as myisamchk can't correct it */
uint save=param->warning_printed; uint save=param->warning_printed;
mi_check_print_warning(param, mi_check_print_warning(param, "Found row where the auto_increment "
"Found row where the auto_increment column has the value 0"); "column has the value 0");
param->warning_printed=save; param->warning_printed=save;
} }
mi_extra(info,HA_EXTRA_NO_KEYREAD,0); mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
...@@ -4099,11 +4098,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, ...@@ -4099,11 +4098,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
} }
else else
{ {
ulonglong auto_increment= (repair_only ? info->s->state.auto_increment : ulonglong auto_increment= retrieve_auto_increment(info, record);
param->auto_increment_value);
info->s->state.auto_increment=0;
update_auto_increment(info, record);
set_if_bigger(info->s->state.auto_increment,auto_increment); set_if_bigger(info->s->state.auto_increment,auto_increment);
if (!repair_only)
set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
} }
mi_extra(info,HA_EXTRA_NO_KEYREAD,0); mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
my_free((char*) record, MYF(0)); my_free((char*) record, MYF(0));
......
...@@ -507,22 +507,21 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -507,22 +507,21 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
return(-1); /* Wrong data to read */ return(-1); /* Wrong data to read */
} }
/* /*
Update auto_increment info Retrieve auto_increment info
SYNOPSIS SYNOPSIS
update_auto_increment() retrieve_auto_increment()
info MyISAM handler info MyISAM handler
record Row to update record Row to update
IMPLEMENTATION IMPLEMENTATION
Only replace the auto_increment value if it is higher than the previous For signed columns we don't retrieve the auto increment value if it's
one. For signed columns we don't update the auto increment value if it's
less than zero. less than zero.
*/ */
void update_auto_increment(MI_INFO *info,const byte *record) ulonglong retrieve_auto_increment(MI_INFO *info,const byte *record)
{ {
ulonglong value= 0; /* Store unsigned values here */ ulonglong value= 0; /* Store unsigned values here */
longlong s_value= 0; /* Store signed values here */ longlong s_value= 0; /* Store signed values here */
...@@ -587,6 +586,5 @@ void update_auto_increment(MI_INFO *info,const byte *record) ...@@ -587,6 +586,5 @@ void update_auto_increment(MI_INFO *info,const byte *record)
and if s_value == 0 then value will contain either s_value or the and if s_value == 0 then value will contain either s_value or the
correct value. correct value.
*/ */
set_if_bigger(info->s->state.auto_increment, return (s_value > 0) ? (ulonglong) s_value : value;
(s_value > 0) ? (ulonglong) s_value : value);
} }
...@@ -164,7 +164,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) ...@@ -164,7 +164,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
key_changed|= HA_STATE_CHANGED; /* Must update index file */ key_changed|= HA_STATE_CHANGED; /* Must update index file */
} }
if (auto_key_changed) if (auto_key_changed)
update_auto_increment(info,newrec); set_if_bigger(info->s->state.auto_increment,
retrieve_auto_increment(info, newrec));
if (share->calc_checksum) if (share->calc_checksum)
info->state->checksum+=(info->checksum - old_checksum); info->state->checksum+=(info->checksum - old_checksum);
......
...@@ -149,7 +149,8 @@ int mi_write(MI_INFO *info, byte *record) ...@@ -149,7 +149,8 @@ int mi_write(MI_INFO *info, byte *record)
info->state->checksum+=info->checksum; info->state->checksum+=info->checksum;
} }
if (share->base.auto_key) if (share->base.auto_key)
update_auto_increment(info,record); set_if_bigger(info->s->state.auto_increment,
retrieve_auto_increment(info, record));
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED); HA_STATE_ROW_CHANGED);
info->state->records++; info->state->records++;
......
...@@ -582,7 +582,7 @@ extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old, ...@@ -582,7 +582,7 @@ extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf); extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos, extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
uint length,int re_read_if_possibly); uint length,int re_read_if_possibly);
extern void update_auto_increment(MI_INFO *info,const byte *record); extern ulonglong retrieve_auto_increment(MI_INFO *info,const byte *record);
extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**); extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
#define mi_get_rec_buff_ptr(info,buf) \ #define mi_get_rec_buff_ptr(info,buf) \
......
...@@ -671,6 +671,12 @@ sub command_line_setup () { ...@@ -671,6 +671,12 @@ sub command_line_setup () {
{ {
push(@opt_extra_mysqld_opt, $arg); push(@opt_extra_mysqld_opt, $arg);
} }
elsif ( $arg =~ /^--$/ )
{
# It is an effect of setting 'pass_through' in option processing
# that the lone '--' separating options from arguments survives,
# simply ignore it.
}
elsif ( $arg =~ /^-/ ) elsif ( $arg =~ /^-/ )
{ {
usage("Invalid option \"$arg\""); usage("Invalid option \"$arg\"");
...@@ -3428,6 +3434,13 @@ sub valgrind_arguments { ...@@ -3428,6 +3434,13 @@ sub valgrind_arguments {
############################################################################## ##############################################################################
sub usage ($) { sub usage ($) {
my $message= shift;
if ( $message )
{
print STDERR "$message \n";
}
print STDERR <<HERE; print STDERR <<HERE;
mysql-test-run [ OPTIONS ] [ TESTCASE ] mysql-test-run [ OPTIONS ] [ TESTCASE ]
......
...@@ -172,6 +172,6 @@ c2h ...@@ -172,6 +172,6 @@ c2h
ab_def ab_def
drop table t1; drop table t1;
SET NAMES sjis; SET NAMES sjis;
SELECT HEX('佐淘 \圭') FROM DUAL; SELECT HEX('@\') FROM DUAL;
HEX('佐淘 圭') HEX('@\')
8DB2939181408C5C 8DB2939181408C5C
...@@ -7,20 +7,20 @@ period_add("9602",-12) period_diff(199505,"9404") ...@@ -7,20 +7,20 @@ period_add("9602",-12) period_diff(199505,"9404")
199502 13 199502 13
select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now()); select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now()) now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now())
0 0 0 0.000000 0 0
select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0; select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0 from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0
1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112 1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112.000000
select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"), select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
sec_to_time(time_to_sec("0:30:47")/6.21); sec_to_time(time_to_sec("0:30:47")/6.21);
sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21) sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21)
02:30:01 23001 54742 00:04:57 02:30:01 23001.000000 54742 00:04:57
select sec_to_time(time_to_sec('-838:59:59')); select sec_to_time(time_to_sec('-838:59:59'));
sec_to_time(time_to_sec('-838:59:59')) sec_to_time(time_to_sec('-838:59:59'))
-838:59:59 -838:59:59
select now()-curdate()*1000000-curtime(); select now()-curdate()*1000000-curtime();
now()-curdate()*1000000-curtime() now()-curdate()*1000000-curtime()
0 0.000000
select strcmp(current_timestamp(),concat(current_date()," ",current_time())); select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
strcmp(current_timestamp(),concat(current_date()," ",current_time())) strcmp(current_timestamp(),concat(current_date()," ",current_time()))
0 0
...@@ -751,6 +751,10 @@ select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')), ...@@ -751,6 +751,10 @@ select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m')); monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
NULL NULL January NULL NULL NULL January NULL
select now() - now() + 0, curtime() - curtime() + 0,
sec_to_time(1) + 0, from_unixtime(1) + 0;
now() - now() + 0 curtime() - curtime() + 0 sec_to_time(1) + 0 from_unixtime(1) + 0
0.000000 0.000000 1.000000 19700101030001.000000
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
......
...@@ -43,6 +43,14 @@ Field Type Null Key Default Extra ...@@ -43,6 +43,14 @@ Field Type Null Key Default Extra
a int(11) YES NULL a int(11) YES NULL
unlock tables; unlock tables;
drop table t1; drop table t1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
DROP DATABASE mysqltest_1;
DROP DATABASE mysqltest_1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
UNLOCK TABLES;
DROP DATABASE mysqltest_1;
ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist
use mysql; use mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES; FLUSH TABLES;
......
...@@ -776,3 +776,9 @@ insert into t1 values ("Monty"),("WAX"),("Walrus"); ...@@ -776,3 +776,9 @@ insert into t1 values ("Monty"),("WAX"),("Walrus");
alter table t1 engine=MERGE; alter table t1 engine=MERGE;
ERROR HY000: Table storage engine for 't1' doesn't have this option ERROR HY000: Table storage engine for 't1' doesn't have this option
drop table t1; drop table t1;
create table t1 (b bit(1));
create table t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm;
b
drop table tm, t1, t2;
set timestamp=1; set timestamp=1;
SELECT sleep(1),NOW()-SYSDATE() as zero; SELECT sleep(1),NOW()-SYSDATE() as zero;
sleep(1) zero sleep(1) zero
0 0 0 0.000000
...@@ -78,6 +78,6 @@ SET collation_connection='sjis_bin'; ...@@ -78,6 +78,6 @@ SET collation_connection='sjis_bin';
--character_set sjis --character_set sjis
SET NAMES sjis; SET NAMES sjis;
SELECT HEX('@\\') FROM DUAL; SELECT HEX('@\') FROM DUAL;
# End of 4.1 tests # End of 4.1 tests
...@@ -367,6 +367,13 @@ select last_day('2005-01-00'); ...@@ -367,6 +367,13 @@ select last_day('2005-01-00');
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')), select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m')); monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
#
# Bug #16546
#
select now() - now() + 0, curtime() - curtime() + 0,
sec_to_time(1) + 0, from_unixtime(1) + 0;
# End of 4.1 tests # End of 4.1 tests
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
......
...@@ -109,6 +109,39 @@ unlock tables; ...@@ -109,6 +109,39 @@ unlock tables;
drop table t1; drop table t1;
# #
# Bug#19815 - CREATE/RENAME/DROP DATABASE can deadlock on a global read lock
#
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
#
connection con1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
#
# With bug in place: acquire LOCK_mysql_create_table and
# wait in wait_if_global_read_lock().
connection con2;
send DROP DATABASE mysqltest_1;
--sleep 1
#
# With bug in place: try to acquire LOCK_mysql_create_table...
# When fixed: Reject dropping db because of the read lock.
connection con1;
--error ER_CANT_UPDATE_WITH_READLOCK
DROP DATABASE mysqltest_1;
UNLOCK TABLES;
#
connection con2;
reap;
#
connection default;
disconnect con1;
disconnect con2;
# This must have been dropped by connection 2 already,
# which waited until the global read lock was released.
--error ER_DB_DROP_EXISTS
DROP DATABASE mysqltest_1;
# Bug#16986 - Deadlock condition with MyISAM tables # Bug#16986 - Deadlock condition with MyISAM tables
# #
connection locker; connection locker;
......
...@@ -390,4 +390,13 @@ insert into t1 values ("Monty"),("WAX"),("Walrus"); ...@@ -390,4 +390,13 @@ insert into t1 values ("Monty"),("WAX"),("Walrus");
alter table t1 engine=MERGE; alter table t1 engine=MERGE;
drop table t1; drop table t1;
#
# BUG#19648 - Merge table does not work with bit types
#
create table t1 (b bit(1));
create table t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm;
drop table tm, t1, t2;
# End of 5.0 tests # End of 5.0 tests
...@@ -2267,7 +2267,7 @@ NdbDictionaryImpl::dropIndex(const char * indexName, ...@@ -2267,7 +2267,7 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
m_error.code = 4243; m_error.code = 4243;
return -1; return -1;
} }
int ret = dropIndex(*idx); //, tableName); int ret = dropIndex(*idx);
// If index stored in cache is incompatible with the one in the kernel // If index stored in cache is incompatible with the one in the kernel
// we must clear the cache and try again // we must clear the cache and try again
if (ret == INCOMPATIBLE_VERSION) { if (ret == INCOMPATIBLE_VERSION) {
......
...@@ -395,7 +395,6 @@ public: ...@@ -395,7 +395,6 @@ public:
int createIndex(NdbIndexImpl &ix); int createIndex(NdbIndexImpl &ix);
int dropIndex(const char * indexName, int dropIndex(const char * indexName,
const char * tableName); const char * tableName);
// int dropIndex(NdbIndexImpl &, const char * tableName);
int dropIndex(NdbIndexImpl &); int dropIndex(NdbIndexImpl &);
NdbTableImpl * getIndexTable(NdbIndexImpl * index, NdbTableImpl * getIndexTable(NdbIndexImpl * index,
NdbTableImpl * table); NdbTableImpl * table);
......
...@@ -37,7 +37,8 @@ class ha_myisammrg: public handler ...@@ -37,7 +37,8 @@ class ha_myisammrg: public handler
{ {
return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_READ_RND_SAME | return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_READ_RND_SAME |
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
HA_CAN_INSERT_DELAYED | HA_ANY_INDEX_MAY_BE_UNIQUE); HA_CAN_INSERT_DELAYED | HA_ANY_INDEX_MAY_BE_UNIQUE |
HA_CAN_BIT_FIELD);
} }
ulong index_flags(uint inx, uint part, bool all_parts) const ulong index_flags(uint inx, uint part, bool all_parts) const
{ {
......
...@@ -1391,7 +1391,7 @@ void Item_func_curtime::fix_length_and_dec() ...@@ -1391,7 +1391,7 @@ void Item_func_curtime::fix_length_and_dec()
{ {
TIME ltime; TIME ltime;
decimals=0; decimals= DATETIME_DEC;
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
store_now_in_TIME(&ltime); store_now_in_TIME(&ltime);
value= TIME_to_ulonglong_time(&ltime); value= TIME_to_ulonglong_time(&ltime);
...@@ -1438,7 +1438,7 @@ String *Item_func_now::val_str(String *str) ...@@ -1438,7 +1438,7 @@ String *Item_func_now::val_str(String *str)
void Item_func_now::fix_length_and_dec() void Item_func_now::fix_length_and_dec()
{ {
decimals=0; decimals= DATETIME_DEC;
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
store_now_in_TIME(&ltime); store_now_in_TIME(&ltime);
...@@ -1785,7 +1785,7 @@ void Item_func_from_unixtime::fix_length_and_dec() ...@@ -1785,7 +1785,7 @@ void Item_func_from_unixtime::fix_length_and_dec()
{ {
thd= current_thd; thd= current_thd;
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
decimals=0; decimals= DATETIME_DEC;
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null= 1; maybe_null= 1;
thd->time_zone_used= 1; thd->time_zone_used= 1;
......
...@@ -614,6 +614,7 @@ class Item_func_sec_to_time :public Item_str_func ...@@ -614,6 +614,7 @@ class Item_func_sec_to_time :public Item_str_func
{ {
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
maybe_null=1; maybe_null=1;
decimals= DATETIME_DEC;
max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
} }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
......
...@@ -424,16 +424,27 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -424,16 +424,27 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
my_error(ER_DB_CREATE_EXISTS, MYF(0), db); my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* do not create database if another thread is holding read lock */ /*
Do not create database if another thread is holding read lock.
Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if (wait_if_global_read_lock(thd, 0, 1)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* Check directory */ /* Check directory */
strxmov(path, mysql_data_home, "/", db, NullS); strxmov(path, mysql_data_home, "/", db, NullS);
path_len= unpack_dirname(path,path); // Convert if not unix path_len= unpack_dirname(path,path); // Convert if not unix
...@@ -537,9 +548,9 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -537,9 +548,9 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
} }
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2: exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -553,12 +564,23 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) ...@@ -553,12 +564,23 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
int error= 0; int error= 0;
DBUG_ENTER("mysql_alter_db"); DBUG_ENTER("mysql_alter_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /*
Do not alter database if another thread is holding read lock.
/* do not alter database if another thread is holding read lock */ Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if ((error=wait_if_global_read_lock(thd,0,1))) if ((error=wait_if_global_read_lock(thd,0,1)))
goto exit2; goto exit2;
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* Check directory */ /* Check directory */
strxmov(path, mysql_data_home, "/", db, "/", MY_DB_OPT_FILE, NullS); strxmov(path, mysql_data_home, "/", db, "/", MY_DB_OPT_FILE, NullS);
fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME)); fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME));
...@@ -596,9 +618,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) ...@@ -596,9 +618,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
send_ok(thd, result); send_ok(thd, result);
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2: exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -630,15 +652,26 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -630,15 +652,26 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
TABLE_LIST* dropped_tables= 0; TABLE_LIST* dropped_tables= 0;
DBUG_ENTER("mysql_rm_db"); DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /*
Do not drop database if another thread is holding read lock.
/* do not drop database if another thread is holding read lock */ Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if (wait_if_global_read_lock(thd, 0, 1)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
(void) sprintf(path,"%s/%s",mysql_data_home,db); (void) sprintf(path,"%s/%s",mysql_data_home,db);
length= unpack_dirname(path,path); // Convert if not unix length= unpack_dirname(path,path); // Convert if not unix
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
...@@ -747,7 +780,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -747,7 +780,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
exit: exit:
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */ (void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
start_waiting_global_read_lock(thd);
/* /*
If this database was the client's selected database, we silently change the If this database was the client's selected database, we silently change the
client's selected database to nothing (to have an empty SELECT DATABASE() client's selected database to nothing (to have an empty SELECT DATABASE()
...@@ -776,9 +808,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -776,9 +808,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
thd->db= 0; thd->db= 0;
thd->db_length= 0; thd->db_length= 0;
} }
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd);
exit2:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -304,18 +304,7 @@ static char *get_text(LEX *lex) ...@@ -304,18 +304,7 @@ static char *get_text(LEX *lex)
found_escape=1; found_escape=1;
if (lex->ptr == lex->end_of_query) if (lex->ptr == lex->end_of_query)
return 0; return 0;
#ifdef USE_MB yySkip();
int l;
if (use_mb(cs) &&
(l = my_ismbchar(cs,
(const char *)lex->ptr,
(const char *)lex->end_of_query))) {
lex->ptr += l;
continue;
}
else
#endif
yySkip();
} }
else if (c == sep) else if (c == sep)
{ {
...@@ -344,9 +333,6 @@ static char *get_text(LEX *lex) ...@@ -344,9 +333,6 @@ static char *get_text(LEX *lex)
{ {
uchar *to; uchar *to;
/* Re-use found_escape for tracking state of escapes */
found_escape= 0;
for (to=start ; str != end ; str++) for (to=start ; str != end ; str++)
{ {
#ifdef USE_MB #ifdef USE_MB
...@@ -360,8 +346,7 @@ static char *get_text(LEX *lex) ...@@ -360,8 +346,7 @@ static char *get_text(LEX *lex)
continue; continue;
} }
#endif #endif
if (!found_escape && if (!(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
!(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
*str == '\\' && str+1 != end) *str == '\\' && str+1 != end)
{ {
switch(*++str) { switch(*++str) {
...@@ -388,20 +373,14 @@ static char *get_text(LEX *lex) ...@@ -388,20 +373,14 @@ static char *get_text(LEX *lex)
*to++= '\\'; // remember prefix for wildcard *to++= '\\'; // remember prefix for wildcard
/* Fall through */ /* Fall through */
default: default:
found_escape= 1; *to++= *str;
str--;
break; break;
} }
} }
else if (!found_escape && *str == sep) else if (*str == sep)
{ *to++= *str++; // Two ' or "
found_escape= 1;
}
else else
{
*to++ = *str; *to++ = *str;
found_escape= 0;
}
} }
*to=0; *to=0;
lex->yytoklen=(uint) (to-start); lex->yytoklen=(uint) (to-start);
......
...@@ -12794,25 +12794,26 @@ from t2);"); ...@@ -12794,25 +12794,26 @@ from t2);");
static void test_bug8378() static void test_bug8378()
{ {
#if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY) #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
MYSQL *lmysql; MYSQL *old_mysql=mysql;
char out[9]; /* strlen(TEST_BUG8378)*2+1 */ char out[9]; /* strlen(TEST_BUG8378)*2+1 */
int len; char buf[256];
int len, rc;
myheader("test_bug8378"); myheader("test_bug8378");
if (!opt_silent) if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ..."); fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL))) if (!(mysql= mysql_init(NULL)))
{ {
myerror("mysql_init() failed"); myerror("mysql_init() failed");
exit(1); exit(1);
} }
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk")) if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "gbk"))
{ {
myerror("mysql_options() failed"); myerror("mysql_options() failed");
exit(1); exit(1);
} }
if (!(mysql_real_connect(lmysql, opt_host, opt_user, if (!(mysql_real_connect(mysql, opt_host, opt_user,
opt_password, current_db, opt_port, opt_password, current_db, opt_port,
opt_unix_socket, 0))) opt_unix_socket, 0)))
{ {
...@@ -12822,12 +12823,18 @@ static void test_bug8378() ...@@ -12822,12 +12823,18 @@ static void test_bug8378()
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, " OK");
len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4); len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
/* No escaping should have actually happened. */ /* No escaping should have actually happened. */
DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0); DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
mysql_close(lmysql); sprintf(buf, "SELECT '%s'", out);
rc=mysql_real_query(mysql, buf, strlen(buf));
myquery(rc);
mysql_close(mysql);
mysql=old_mysql;
#endif #endif
} }
......
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