mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 15:15:34 +02:00
Merge mysql.com:/home/stewart/Documents/MySQL/5.0/merge-queue
into mysql.com:/home/stewart/Documents/MySQL/5.0/main ndb/src/mgmsrv/MgmtSrvr.cpp: Auto merged ndb/src/mgmsrv/MgmtSrvr.hpp: Auto merged ndb/src/mgmsrv/Services.cpp: Auto merged
This commit is contained in:
commit
70cf824053
53 changed files with 974 additions and 209 deletions
|
|
@ -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
|
||||||
# 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
|
||||||
|
|
|
||||||
|
|
@ -880,7 +880,7 @@ int sendData(SSL& ssl, const void* buffer, int sz)
|
||||||
ssl.SetError(no_error);
|
ssl.SetError(no_error);
|
||||||
|
|
||||||
ssl.verfiyHandShakeComplete();
|
ssl.verfiyHandShakeComplete();
|
||||||
if (ssl.GetError()) return 0;
|
if (ssl.GetError()) return -1;
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
@ -891,7 +891,7 @@ int sendData(SSL& ssl, const void* buffer, int sz)
|
||||||
buildMessage(ssl, out, data);
|
buildMessage(ssl, out, data);
|
||||||
ssl.Send(out.get_buffer(), out.get_size());
|
ssl.Send(out.get_buffer(), out.get_size());
|
||||||
|
|
||||||
if (ssl.GetError()) return 0;
|
if (ssl.GetError()) return -1;
|
||||||
sent += len;
|
sent += len;
|
||||||
if (sent == sz) break;
|
if (sent == sz) break;
|
||||||
}
|
}
|
||||||
|
|
@ -918,14 +918,14 @@ int receiveData(SSL& ssl, Data& data)
|
||||||
ssl.SetError(no_error);
|
ssl.SetError(no_error);
|
||||||
|
|
||||||
ssl.verfiyHandShakeComplete();
|
ssl.verfiyHandShakeComplete();
|
||||||
if (ssl.GetError()) return 0;
|
if (ssl.GetError()) return -1;
|
||||||
|
|
||||||
if (!ssl.bufferedData())
|
if (!ssl.bufferedData())
|
||||||
processReply(ssl);
|
processReply(ssl);
|
||||||
ssl.fillData(data);
|
ssl.fillData(data);
|
||||||
ssl.useLog().ShowData(data.get_length());
|
ssl.useLog().ShowData(data.get_length());
|
||||||
|
|
||||||
if (ssl.GetError()) return 0;
|
if (ssl.GetError()) return -1;
|
||||||
|
|
||||||
if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) {
|
if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) {
|
||||||
ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
|
ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,22 @@ uint Socket::get_ready() const
|
||||||
|
|
||||||
uint Socket::send(const byte* buf, unsigned int sz, int flags) const
|
uint Socket::send(const byte* buf, unsigned int sz, int flags) const
|
||||||
{
|
{
|
||||||
|
const byte* pos = buf;
|
||||||
|
const byte* end = pos + sz;
|
||||||
|
|
||||||
assert(socket_ != INVALID_SOCKET);
|
assert(socket_ != INVALID_SOCKET);
|
||||||
int sent = ::send(socket_, reinterpret_cast<const char *>(buf), sz, flags);
|
|
||||||
|
while (pos != end) {
|
||||||
|
int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
|
||||||
|
static_cast<int>(end - pos), flags);
|
||||||
|
|
||||||
if (sent == -1)
|
if (sent == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return sent;
|
pos += sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
/* 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,
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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 () {
|
||||||
{
|
{
|
||||||
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 {
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
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
|
||||||
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")
|
||||||
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')),
|
||||||
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
|
||||||
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");
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -1842,5 +1842,29 @@ a b
|
||||||
select * from t1 where b like 'abc' or b like 'abc';
|
select * from t1 where b like 'abc' or b like 'abc';
|
||||||
a b
|
a b
|
||||||
3 abc
|
3 abc
|
||||||
|
drop table t1;
|
||||||
|
create table t1 ( fname varchar(255), lname varchar(255) )
|
||||||
|
engine=ndbcluster;
|
||||||
|
insert into t1 values ("Young","Foo");
|
||||||
|
set engine_condition_pushdown = 0;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
fname lname
|
||||||
|
Young Foo
|
||||||
|
set engine_condition_pushdown = 1;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
fname lname
|
||||||
|
Young Foo
|
||||||
|
insert into t1 values ("aaa", "aaa");
|
||||||
|
insert into t1 values ("bbb", "bbb");
|
||||||
|
insert into t1 values ("ccc", "ccc");
|
||||||
|
insert into t1 values ("ddd", "ddd");
|
||||||
|
set engine_condition_pushdown = 0;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
fname lname
|
||||||
|
Young Foo
|
||||||
|
set engine_condition_pushdown = 1;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
fname lname
|
||||||
|
Young Foo
|
||||||
set engine_condition_pushdown = @old_ecpd;
|
set engine_condition_pushdown = @old_ecpd;
|
||||||
DROP TABLE t1,t2,t3,t4,t5;
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
|
|
||||||
46
mysql-test/r/ndb_loaddatalocal.result
Normal file
46
mysql-test/r/ndb_loaddatalocal.result
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int) engine=ndb;
|
||||||
|
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
10000
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (2), (2), (3);
|
||||||
|
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
select * from t1 order by a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (1), (2), (3);
|
||||||
|
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
select * from t1 order by a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (2), (3), (3);
|
||||||
|
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
select * from t1 order by a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
drop table t1;
|
||||||
|
|
@ -63,3 +63,83 @@ pk u o
|
||||||
5 5 5
|
5 5 5
|
||||||
insert into t1 values (1,1,1);
|
insert into t1 values (1,1,1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb;
|
||||||
|
insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3);
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
x y z
|
||||||
|
2 two 2
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' or y = 'three' order by x for update;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
3 three 3
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
select * from t1 where z > 1 and z < 3 for update;
|
||||||
|
x y z
|
||||||
|
2 two 2
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 lock in share mode;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 lock in share mode;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
x y z
|
||||||
|
2 two 2
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' or y = 'three' order by x lock in share mode;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
3 three 3
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' lock in share mode;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
select * from t1 where z > 1 and z < 3 lock in share mode;
|
||||||
|
x y z
|
||||||
|
2 two 2
|
||||||
|
begin;
|
||||||
|
select * from t1 where z = 1 lock in share mode;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
x y z
|
||||||
|
1 one 1
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
rollback;
|
||||||
|
commit;
|
||||||
|
drop table t1;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,23 @@
|
||||||
DROP TABLE IF EXISTS t2;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
CREATE TABLE t2 (
|
CREATE TABLE t1 (
|
||||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
a bigint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
b int unsigned not null,
|
b int unsigned not null,
|
||||||
c int unsigned
|
c int unsigned
|
||||||
) engine=ndbcluster;
|
) engine=ndbcluster;
|
||||||
select count(*) from t2;
|
select count(*) from t1;
|
||||||
count(*)
|
count(*)
|
||||||
5000
|
5000
|
||||||
truncate table t2;
|
select * from t1 order by a limit 2;
|
||||||
select count(*) from t2;
|
a b c
|
||||||
|
1 509 2500
|
||||||
|
2 510 7
|
||||||
|
truncate table t1;
|
||||||
|
select count(*) from t1;
|
||||||
count(*)
|
count(*)
|
||||||
0
|
0
|
||||||
drop table t2;
|
insert into t1 values(NULL,1,1),(NULL,2,2);
|
||||||
|
select * from t1 order by a;
|
||||||
|
a b c
|
||||||
|
1 1 1
|
||||||
|
2 2 2
|
||||||
|
drop table t1;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1397,3 +1397,14 @@ c1
|
||||||
9999999999999999999999999999999999999999999999999999999999999999
|
9999999999999999999999999999999999999999999999999999999999999999
|
||||||
9999999999999999999999999999999999999999999999999999999999999999
|
9999999999999999999999999999999999999999999999999999999999999999
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (i int, j int);
|
||||||
|
insert into t1 values (1,1), (1,2), (2,3), (2,4);
|
||||||
|
select i, count(distinct j) from t1 group by i;
|
||||||
|
i count(distinct j)
|
||||||
|
1 2
|
||||||
|
2 2
|
||||||
|
select i+0.0 as i2, count(distinct j) from t1 group by i2;
|
||||||
|
i2 count(distinct j)
|
||||||
|
1.0 2
|
||||||
|
2.0 2
|
||||||
|
drop table t1;
|
||||||
|
|
|
||||||
|
|
@ -618,3 +618,32 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered
|
||||||
DROP VIEW v;
|
DROP VIEW v;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
USE test;
|
USE test;
|
||||||
|
CREATE USER mysqltest_db1@localhost identified by 'PWD';
|
||||||
|
GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION;
|
||||||
|
CREATE SCHEMA mysqltest_db1 ;
|
||||||
|
USE mysqltest_db1 ;
|
||||||
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
|
CREATE VIEW view1 AS
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE VIEW view1;
|
||||||
|
View Create View
|
||||||
|
view1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1`
|
||||||
|
CREATE VIEW view2 AS
|
||||||
|
SELECT * FROM view1;
|
||||||
|
# Here comes a suspicious warning
|
||||||
|
SHOW CREATE VIEW view2;
|
||||||
|
View Create View
|
||||||
|
view2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1`
|
||||||
|
# But the view view2 is usable
|
||||||
|
SELECT * FROM view2;
|
||||||
|
f1
|
||||||
|
CREATE VIEW view3 AS
|
||||||
|
SELECT * FROM view2;
|
||||||
|
SELECT * from view3;
|
||||||
|
f1
|
||||||
|
DROP VIEW mysqltest_db1.view3;
|
||||||
|
DROP VIEW mysqltest_db1.view2;
|
||||||
|
DROP VIEW mysqltest_db1.view1;
|
||||||
|
DROP TABLE mysqltest_db1.t1;
|
||||||
|
DROP SCHEMA mysqltest_db1;
|
||||||
|
DROP USER mysqltest_db1@localhost;
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
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;
|
||||||
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");
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1686,5 +1686,27 @@ select * from t1 where b like 'ab' or b like 'ab';
|
||||||
select * from t1 where b like 'abc';
|
select * from t1 where b like 'abc';
|
||||||
select * from t1 where b like 'abc' or b like 'abc';
|
select * from t1 where b like 'abc' or b like 'abc';
|
||||||
|
|
||||||
|
# bug#20406 (maybe same as bug#17421 -1, not seen on 32-bit x86)
|
||||||
|
drop table t1;
|
||||||
|
create table t1 ( fname varchar(255), lname varchar(255) )
|
||||||
|
engine=ndbcluster;
|
||||||
|
insert into t1 values ("Young","Foo");
|
||||||
|
|
||||||
|
set engine_condition_pushdown = 0;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
set engine_condition_pushdown = 1;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
|
||||||
|
# make sure optimizer does not do some crazy shortcut
|
||||||
|
insert into t1 values ("aaa", "aaa");
|
||||||
|
insert into t1 values ("bbb", "bbb");
|
||||||
|
insert into t1 values ("ccc", "ccc");
|
||||||
|
insert into t1 values ("ddd", "ddd");
|
||||||
|
|
||||||
|
set engine_condition_pushdown = 0;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
set engine_condition_pushdown = 1;
|
||||||
|
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
|
||||||
|
|
||||||
set engine_condition_pushdown = @old_ecpd;
|
set engine_condition_pushdown = @old_ecpd;
|
||||||
DROP TABLE t1,t2,t3,t4,t5;
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
|
|
||||||
70
mysql-test/t/ndb_loaddatalocal.test
Normal file
70
mysql-test/t/ndb_loaddatalocal.test
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
-- source include/have_ndb.inc
|
||||||
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
let $1=10000;
|
||||||
|
disable_query_log;
|
||||||
|
set SQL_LOG_BIN=0;
|
||||||
|
while ($1)
|
||||||
|
{
|
||||||
|
insert into t1 values(1);
|
||||||
|
dec $1;
|
||||||
|
}
|
||||||
|
set SQL_LOG_BIN=1;
|
||||||
|
enable_query_log;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
#This will generate a 20KB file, now test LOAD DATA LOCAL
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int) engine=ndb;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
select count(*) from t1;
|
||||||
|
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile ;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (2), (2), (3);
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
|
||||||
|
select * from t1 order by a;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (1), (2), (3);
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
|
||||||
|
select * from t1 order by a;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int) engine=myisam;
|
||||||
|
insert into t1 values (1), (2), (3), (3);
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1(a int primary key) engine=ndb;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
|
||||||
|
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
|
||||||
|
select * from t1 order by a;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# End of 4.1 tests
|
||||||
|
|
@ -69,4 +69,117 @@ insert into t1 values (1,1,1);
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
# Lock for update
|
||||||
|
|
||||||
|
create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb;
|
||||||
|
|
||||||
|
insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3);
|
||||||
|
|
||||||
|
# PK access
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# table scan
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' or y = 'three' order by x for update;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
# Have to check with pk access here since scans take locks on
|
||||||
|
# all rows and then release them in chunks
|
||||||
|
# Bug #20390 SELECT FOR UPDATE does not release locks of untouched rows in full table scans
|
||||||
|
#select * from t1 where x = 2 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# index scan
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where z > 1 and z < 3 for update;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
# Have to check with pk access here since scans take locks on
|
||||||
|
# all rows and then release them in chunks
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# share locking
|
||||||
|
|
||||||
|
# PK access
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 lock in share mode;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
select * from t1 where x = 1 lock in share mode;
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# table scan
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' or y = 'three' order by x lock in share mode;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
select * from t1 where y = 'one' lock in share mode;
|
||||||
|
# Have to check with pk access here since scans take locks on
|
||||||
|
# all rows and then release them in chunks
|
||||||
|
# Bug #20390 SELECT FOR UPDATE does not release locks of untouched rows in full table scans
|
||||||
|
#select * from t1 where x = 2 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# index scan
|
||||||
|
connection con1;
|
||||||
|
begin;
|
||||||
|
select * from t1 where z > 1 and z < 3 lock in share mode;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
begin;
|
||||||
|
select * from t1 where z = 1 lock in share mode;
|
||||||
|
# Have to check with pk access here since scans take locks on
|
||||||
|
# all rows and then release them in chunks
|
||||||
|
select * from t1 where x = 1 for update;
|
||||||
|
--error 1205
|
||||||
|
select * from t1 where x = 2 for update;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@
|
||||||
-- source include/not_embedded.inc
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t2;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
CREATE TABLE t2 (
|
a bigint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
|
||||||
b int unsigned not null,
|
b int unsigned not null,
|
||||||
c int unsigned
|
c int unsigned
|
||||||
) engine=ndbcluster;
|
) engine=ndbcluster;
|
||||||
|
|
@ -20,17 +19,23 @@ let $1=500;
|
||||||
disable_query_log;
|
disable_query_log;
|
||||||
while ($1)
|
while ($1)
|
||||||
{
|
{
|
||||||
eval insert into t2 values($1*10, $1+9, 5*$1), ($1*10+1, $1+10, 7),($1*10+2, $1+10, 7*$1), ($1*10+3, $1+10, 10+$1), ($1*10+4, $1+10, 70*$1), ($1*10+5, $1+10, 7), ($1*10+6, $1+10, 9), ($1*10+7, $1+299, 899), ($1*10+8, $1+10, 12), ($1*10+9, $1+10, 14*$1);
|
eval insert into t1 values(NULL, $1+9, 5*$1), (NULL, $1+10, 7),(NULL, $1+10, 7*$1), (NULL, $1+10, 10+$1), (NULL, $1+10, 70*$1), (NULL, $1+10, 7), (NULL, $1+10, 9), (NULL, $1+299, 899), (NULL, $1+10, 12), (NULL, $1+10, 14*$1);
|
||||||
dec $1;
|
dec $1;
|
||||||
}
|
}
|
||||||
enable_query_log;
|
enable_query_log;
|
||||||
|
|
||||||
select count(*) from t2;
|
select count(*) from t1;
|
||||||
|
|
||||||
truncate table t2;
|
select * from t1 order by a limit 2;
|
||||||
|
|
||||||
select count(*) from t2;
|
truncate table t1;
|
||||||
|
|
||||||
drop table t2;
|
select count(*) from t1;
|
||||||
|
|
||||||
|
insert into t1 values(NULL,1,1),(NULL,2,2);
|
||||||
|
|
||||||
|
select * from t1 order by a;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
|
||||||
|
|
@ -1095,3 +1095,12 @@ insert into t1 values(
|
||||||
insert into t1 values(1e100);
|
insert into t1 values(1e100);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#19667 group by a decimal expression yields wrong result
|
||||||
|
#
|
||||||
|
create table t1 (i int, j int);
|
||||||
|
insert into t1 values (1,1), (1,2), (2,3), (2,4);
|
||||||
|
select i, count(distinct j) from t1 group by i;
|
||||||
|
select i+0.0 as i2, count(distinct j) from t1 group by i2;
|
||||||
|
drop table t1;
|
||||||
|
|
|
||||||
|
|
@ -807,3 +807,42 @@ SELECT * FROM v;
|
||||||
DROP VIEW v;
|
DROP VIEW v;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
USE test;
|
USE test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#20363: Create view on just created view is now denied
|
||||||
|
#
|
||||||
|
eval CREATE USER mysqltest_db1@localhost identified by 'PWD';
|
||||||
|
eval GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION;
|
||||||
|
|
||||||
|
# The session with the non root user is needed.
|
||||||
|
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||||
|
connect (session1,localhost,mysqltest_db1,PWD,test);
|
||||||
|
|
||||||
|
CREATE SCHEMA mysqltest_db1 ;
|
||||||
|
USE mysqltest_db1 ;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
|
|
||||||
|
CREATE VIEW view1 AS
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE VIEW view1;
|
||||||
|
|
||||||
|
CREATE VIEW view2 AS
|
||||||
|
SELECT * FROM view1;
|
||||||
|
--echo # Here comes a suspicious warning
|
||||||
|
SHOW CREATE VIEW view2;
|
||||||
|
--echo # But the view view2 is usable
|
||||||
|
SELECT * FROM view2;
|
||||||
|
|
||||||
|
CREATE VIEW view3 AS
|
||||||
|
SELECT * FROM view2;
|
||||||
|
|
||||||
|
SELECT * from view3;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
DROP VIEW mysqltest_db1.view3;
|
||||||
|
DROP VIEW mysqltest_db1.view2;
|
||||||
|
DROP VIEW mysqltest_db1.view1;
|
||||||
|
DROP TABLE mysqltest_db1.t1;
|
||||||
|
DROP SCHEMA mysqltest_db1;
|
||||||
|
DROP USER mysqltest_db1@localhost;
|
||||||
|
|
|
||||||
|
|
@ -292,3 +292,18 @@
|
||||||
futex(utime)
|
futex(utime)
|
||||||
fun:__lll_mutex_unlock_wake
|
fun:__lll_mutex_unlock_wake
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#19940: NDB sends uninitialized parts of field buffers across the wire.
|
||||||
|
# This is "works as designed"; the uninitialized part is not used at the
|
||||||
|
# other end (but Valgrind cannot see this).
|
||||||
|
#
|
||||||
|
{
|
||||||
|
bug19940
|
||||||
|
Memcheck:Param
|
||||||
|
socketcall.sendto(msg)
|
||||||
|
fun:send
|
||||||
|
fun:_ZN15TCP_Transporter6doSendEv
|
||||||
|
fun:_ZN19TransporterRegistry11performSendEv
|
||||||
|
fun:_ZN19TransporterRegistry14forceSendCheckEi
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,14 @@ public:
|
||||||
Uint32 parallel,
|
Uint32 parallel,
|
||||||
bool order_by,
|
bool order_by,
|
||||||
bool order_desc = false,
|
bool order_desc = false,
|
||||||
bool read_range_no = false) {
|
bool read_range_no = false,
|
||||||
|
bool keyinfo = false) {
|
||||||
Uint32 scan_flags =
|
Uint32 scan_flags =
|
||||||
(SF_OrderBy & -(Int32)order_by) |
|
(SF_OrderBy & -(Int32)order_by) |
|
||||||
(SF_Descending & -(Int32)order_desc) |
|
(SF_Descending & -(Int32)order_desc) |
|
||||||
(SF_ReadRangeNo & -(Int32)read_range_no);
|
(SF_ReadRangeNo & -(Int32)read_range_no) |
|
||||||
|
(SF_KeyInfo & -(Int32)keyinfo);
|
||||||
|
|
||||||
return readTuples(lock_mode, scan_flags, parallel);
|
return readTuples(lock_mode, scan_flags, parallel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ public:
|
||||||
SF_TupScan = (1 << 16), // scan TUP - only LM_CommittedRead
|
SF_TupScan = (1 << 16), // scan TUP - only LM_CommittedRead
|
||||||
SF_OrderBy = (1 << 24), // index scan in order
|
SF_OrderBy = (1 << 24), // index scan in order
|
||||||
SF_Descending = (2 << 24), // index scan in descending order
|
SF_Descending = (2 << 24), // index scan in descending order
|
||||||
SF_ReadRangeNo = (4 << 24) // enable @ref get_range_no
|
SF_ReadRangeNo = (4 << 24), // enable @ref get_range_no
|
||||||
|
SF_KeyInfo = 1 // request KeyInfo to be sent back
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,15 +62,14 @@ public:
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
||||||
/**
|
/**
|
||||||
* readTuples
|
* readTuples
|
||||||
*
|
|
||||||
* @param lock_mode Lock mode
|
* @param lock_mode Lock mode
|
||||||
* @param batch No of rows to fetch from each fragment at a time
|
* @param batch No of rows to fetch from each fragment at a time
|
||||||
* @param parallel No of fragments to scan in parallell
|
* @param parallel No of fragments to scan in parallell
|
||||||
* @note specifying 0 for batch and parallall means max performance
|
* @note specifying 0 for batch and parallell means max performance
|
||||||
*/
|
*/
|
||||||
#ifdef ndb_readtuples_impossible_overload
|
#ifdef ndb_readtuples_impossible_overload
|
||||||
int readTuples(LockMode lock_mode = LM_Read,
|
int readTuples(LockMode lock_mode = LM_Read,
|
||||||
Uint32 batch = 0, Uint32 parallel = 0);
|
Uint32 batch = 0, Uint32 parallel = 0, bool keyinfo = false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline int readTuples(int parallell){
|
inline int readTuples(int parallell){
|
||||||
|
|
@ -141,6 +141,20 @@ public:
|
||||||
*/
|
*/
|
||||||
void close(bool forceSend = false, bool releaseOp = false);
|
void close(bool forceSend = false, bool releaseOp = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock current tuple
|
||||||
|
*
|
||||||
|
* @return an NdbOperation or NULL.
|
||||||
|
*/
|
||||||
|
NdbOperation* lockCurrentTuple();
|
||||||
|
/**
|
||||||
|
* Lock current tuple
|
||||||
|
*
|
||||||
|
* @param lockTrans Transaction that should perform the lock
|
||||||
|
*
|
||||||
|
* @return an NdbOperation or NULL.
|
||||||
|
*/
|
||||||
|
NdbOperation* lockCurrentTuple(NdbTransaction* lockTrans);
|
||||||
/**
|
/**
|
||||||
* Update current tuple
|
* Update current tuple
|
||||||
*
|
*
|
||||||
|
|
@ -249,6 +263,19 @@ protected:
|
||||||
NdbRecAttr *m_curr_row; // Pointer to last returned row
|
NdbRecAttr *m_curr_row; // Pointer to last returned row
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
NdbOperation*
|
||||||
|
NdbScanOperation::lockCurrentTuple(){
|
||||||
|
return lockCurrentTuple(m_transConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
NdbOperation*
|
||||||
|
NdbScanOperation::lockCurrentTuple(NdbTransaction* takeOverTrans){
|
||||||
|
return takeOverScanOp(NdbOperation::ReadRequest,
|
||||||
|
takeOverTrans);
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
NdbOperation*
|
NdbOperation*
|
||||||
NdbScanOperation::updateCurrentTuple(){
|
NdbScanOperation::updateCurrentTuple(){
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,7 @@ void Cmvmi::execEVENT_REP(Signal* signal)
|
||||||
void
|
void
|
||||||
Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
|
Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
|
||||||
EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0];
|
EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0];
|
||||||
|
Uint32 senderRef = signal->getSendersBlockRef();
|
||||||
SubscriberPtr ptr;
|
SubscriberPtr ptr;
|
||||||
jamEntry();
|
jamEntry();
|
||||||
DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ");
|
DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ");
|
||||||
|
|
@ -251,7 +252,7 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
|
||||||
* Create a new one
|
* Create a new one
|
||||||
*/
|
*/
|
||||||
if(subscribers.seize(ptr) == false){
|
if(subscribers.seize(ptr) == false){
|
||||||
sendSignal(subReq->blockRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB);
|
sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ptr.p->logLevel.clear();
|
ptr.p->logLevel.clear();
|
||||||
|
|
@ -278,7 +279,7 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
|
||||||
}
|
}
|
||||||
|
|
||||||
signal->theData[0] = ptr.i;
|
signal->theData[0] = ptr.i;
|
||||||
sendSignal(ptr.p->blockRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB);
|
sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,41 +119,50 @@ MgmtSrvr::logLevelThreadRun()
|
||||||
/**
|
/**
|
||||||
* Handle started nodes
|
* Handle started nodes
|
||||||
*/
|
*/
|
||||||
EventSubscribeReq req;
|
|
||||||
req = m_event_listner[0].m_logLevel;
|
|
||||||
req.blockRef = _ownReference;
|
|
||||||
|
|
||||||
SetLogLevelOrd ord;
|
|
||||||
|
|
||||||
m_started_nodes.lock();
|
m_started_nodes.lock();
|
||||||
while(m_started_nodes.size() > 0){
|
if (m_started_nodes.size() > 0)
|
||||||
Uint32 node = m_started_nodes[0];
|
{
|
||||||
m_started_nodes.erase(0, false);
|
// calculate max log level
|
||||||
m_started_nodes.unlock();
|
EventSubscribeReq req;
|
||||||
|
{
|
||||||
|
LogLevel tmp;
|
||||||
|
m_event_listner.lock();
|
||||||
|
for(int i = m_event_listner.m_clients.size() - 1; i >= 0; i--)
|
||||||
|
tmp.set_max(m_event_listner[i].m_logLevel);
|
||||||
|
m_event_listner.unlock();
|
||||||
|
req = tmp;
|
||||||
|
}
|
||||||
|
req.blockRef = _ownReference;
|
||||||
|
while (m_started_nodes.size() > 0)
|
||||||
|
{
|
||||||
|
Uint32 node = m_started_nodes[0];
|
||||||
|
m_started_nodes.erase(0, false);
|
||||||
|
m_started_nodes.unlock();
|
||||||
|
|
||||||
setEventReportingLevelImpl(node, req);
|
setEventReportingLevelImpl(node, req);
|
||||||
|
|
||||||
ord = m_nodeLogLevel[node];
|
SetLogLevelOrd ord;
|
||||||
setNodeLogLevelImpl(node, ord);
|
ord = m_nodeLogLevel[node];
|
||||||
|
setNodeLogLevelImpl(node, ord);
|
||||||
m_started_nodes.lock();
|
|
||||||
}
|
m_started_nodes.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
m_started_nodes.unlock();
|
m_started_nodes.unlock();
|
||||||
|
|
||||||
m_log_level_requests.lock();
|
m_log_level_requests.lock();
|
||||||
while(m_log_level_requests.size() > 0){
|
while (m_log_level_requests.size() > 0)
|
||||||
req = m_log_level_requests[0];
|
{
|
||||||
|
EventSubscribeReq req = m_log_level_requests[0];
|
||||||
m_log_level_requests.erase(0, false);
|
m_log_level_requests.erase(0, false);
|
||||||
m_log_level_requests.unlock();
|
m_log_level_requests.unlock();
|
||||||
|
|
||||||
LogLevel tmp;
|
|
||||||
tmp = req;
|
|
||||||
|
|
||||||
if(req.blockRef == 0){
|
if(req.blockRef == 0){
|
||||||
req.blockRef = _ownReference;
|
req.blockRef = _ownReference;
|
||||||
setEventReportingLevelImpl(0, req);
|
setEventReportingLevelImpl(0, req);
|
||||||
} else {
|
} else {
|
||||||
ord = req;
|
SetLogLevelOrd ord;
|
||||||
|
ord = req;
|
||||||
setNodeLogLevelImpl(req.blockRef, ord);
|
setNodeLogLevelImpl(req.blockRef, ord);
|
||||||
}
|
}
|
||||||
m_log_level_requests.lock();
|
m_log_level_requests.lock();
|
||||||
|
|
@ -1538,7 +1547,8 @@ int
|
||||||
MgmtSrvr::setEventReportingLevelImpl(int nodeId,
|
MgmtSrvr::setEventReportingLevelImpl(int nodeId,
|
||||||
const EventSubscribeReq& ll)
|
const EventSubscribeReq& ll)
|
||||||
{
|
{
|
||||||
INIT_SIGNAL_SENDER(ss,nodeId);
|
SignalSender ss(theFacade);
|
||||||
|
ss.lock();
|
||||||
|
|
||||||
SimpleSignal ssig;
|
SimpleSignal ssig;
|
||||||
EventSubscribeReq * dst =
|
EventSubscribeReq * dst =
|
||||||
|
|
@ -1547,41 +1557,54 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
|
||||||
EventSubscribeReq::SignalLength);
|
EventSubscribeReq::SignalLength);
|
||||||
*dst = ll;
|
*dst = ll;
|
||||||
|
|
||||||
send(ss,ssig,nodeId,NODE_TYPE_DB);
|
NodeBitmask nodes;
|
||||||
|
nodes.clear();
|
||||||
|
Uint32 max = (nodeId == 0) ? (nodeId = 1, MAX_NDB_NODES) : nodeId;
|
||||||
|
for(; nodeId <= max; nodeId++)
|
||||||
|
{
|
||||||
|
if (nodeTypes[nodeId] != NODE_TYPE_DB)
|
||||||
|
continue;
|
||||||
|
if (okToSendTo(nodeId, true))
|
||||||
|
continue;
|
||||||
|
if (ss.sendSignal(nodeId, &ssig) == SEND_OK)
|
||||||
|
{
|
||||||
|
nodes.set(nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
int error = 0;
|
||||||
while (1)
|
while (!nodes.isclear())
|
||||||
{
|
{
|
||||||
SimpleSignal *signal = ss.waitFor();
|
SimpleSignal *signal = ss.waitFor();
|
||||||
int gsn = signal->readSignalNumber();
|
int gsn = signal->readSignalNumber();
|
||||||
switch (gsn) {
|
nodeId = refToNode(signal->header.theSendersBlockRef);
|
||||||
|
switch (gsn) {
|
||||||
case GSN_EVENT_SUBSCRIBE_CONF:{
|
case GSN_EVENT_SUBSCRIBE_CONF:{
|
||||||
|
nodes.clear(nodeId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GSN_EVENT_SUBSCRIBE_REF:{
|
case GSN_EVENT_SUBSCRIBE_REF:{
|
||||||
return SEND_OR_RECEIVE_FAILED;
|
nodes.clear(nodeId);
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case GSN_NF_COMPLETEREP:{
|
case GSN_NF_COMPLETEREP:{
|
||||||
const NFCompleteRep * const rep =
|
const NFCompleteRep * const rep =
|
||||||
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
|
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
|
||||||
if (rep->failedNodeId == nodeId)
|
nodes.clear(rep->failedNodeId);
|
||||||
return SEND_OR_RECEIVE_FAILED;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GSN_NODE_FAILREP:{
|
case GSN_NODE_FAILREP:{
|
||||||
const NodeFailRep * const rep =
|
// ignore, NF_COMPLETEREP will arrive later
|
||||||
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
|
|
||||||
if (NodeBitmask::get(rep->theNodes,nodeId))
|
|
||||||
return SEND_OR_RECEIVE_FAILED;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report_unknown_signal(signal);
|
report_unknown_signal(signal);
|
||||||
return SEND_OR_RECEIVE_FAILED;
|
return SEND_OR_RECEIVE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
if (error)
|
||||||
|
return SEND_OR_RECEIVE_FAILED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1601,19 +1624,6 @@ MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
|
||||||
return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
|
return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
|
|
||||||
Uint32 max = (node == 0) ? MAX_NODES : node + 1;
|
|
||||||
|
|
||||||
for(; node < max; node++){
|
|
||||||
while(nodeTypes[node] != (int)node_type && node < max) node++;
|
|
||||||
if(nodeTypes[node] != (int)node_type)
|
|
||||||
break;
|
|
||||||
ss.sendSignal(node, &ssig);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -494,8 +494,6 @@ public:
|
||||||
private:
|
private:
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
|
|
||||||
|
|
||||||
int sendStopMgmd(NodeId nodeId,
|
int sendStopMgmd(NodeId nodeId,
|
||||||
bool abort,
|
bool abort,
|
||||||
bool stop,
|
bool stop,
|
||||||
|
|
|
||||||
|
|
@ -840,9 +840,8 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
|
||||||
m_mgmsrv.m_event_listner.unlock();
|
m_mgmsrv.m_event_listner.unlock();
|
||||||
|
|
||||||
{
|
{
|
||||||
LogLevel ll;
|
LogLevel tmp;
|
||||||
ll.setLogLevel(category,level);
|
m_mgmsrv.m_event_listner.update_max_log_level(tmp);
|
||||||
m_mgmsrv.m_event_listner.update_max_log_level(ll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_output->println(reply);
|
m_output->println(reply);
|
||||||
|
|
@ -1370,21 +1369,23 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId)
|
||||||
void
|
void
|
||||||
Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level)
|
Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level)
|
||||||
{
|
{
|
||||||
LogLevel tmp= m_logLevel;
|
LogLevel tmp = log_level;
|
||||||
tmp.set_max(log_level);
|
m_clients.lock();
|
||||||
|
for(int i = m_clients.size() - 1; i >= 0; i--)
|
||||||
|
tmp.set_max(m_clients[i].m_logLevel);
|
||||||
|
m_clients.unlock();
|
||||||
update_log_level(tmp);
|
update_log_level(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp)
|
Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp)
|
||||||
{
|
{
|
||||||
if(!(tmp == m_logLevel)){
|
m_logLevel = tmp;
|
||||||
m_logLevel = tmp;
|
EventSubscribeReq req;
|
||||||
EventSubscribeReq req;
|
req = tmp;
|
||||||
req = tmp;
|
// send update to all nodes
|
||||||
req.blockRef = 0;
|
req.blockRef = 0;
|
||||||
m_mgmsrv->m_log_level_requests.push_back(req);
|
m_mgmsrv->m_log_level_requests.push_back(req);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ NdbScanOperation::readTuples(NdbScanOperation::LockMode lm,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_keyInfo = lockExcl ? 1 : 0;
|
m_keyInfo = ((scan_flags & SF_KeyInfo) || lockExcl) ? 1 : 0;
|
||||||
|
|
||||||
bool rangeScan = false;
|
bool rangeScan = false;
|
||||||
if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex)
|
if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex)
|
||||||
|
|
@ -924,18 +924,28 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans)
|
||||||
if (newOp == NULL){
|
if (newOp == NULL){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (!m_keyInfo)
|
||||||
|
{
|
||||||
|
// Cannot take over lock if no keyinfo was requested
|
||||||
|
setErrorCodeAbort(4604);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
pTrans->theSimpleState = 0;
|
pTrans->theSimpleState = 0;
|
||||||
|
|
||||||
const Uint32 len = (tRecAttr->attrSize() * tRecAttr->arraySize() + 3)/4-1;
|
const Uint32 len = (tRecAttr->attrSize() * tRecAttr->arraySize() + 3)/4-1;
|
||||||
|
|
||||||
newOp->theTupKeyLen = len;
|
newOp->theTupKeyLen = len;
|
||||||
newOp->theOperationType = opType;
|
newOp->theOperationType = opType;
|
||||||
if (opType == DeleteRequest) {
|
switch (opType) {
|
||||||
newOp->theStatus = GetValue;
|
case (ReadRequest):
|
||||||
} else {
|
newOp->theLockMode = theLockMode;
|
||||||
newOp->theStatus = SetValue;
|
// Fall through
|
||||||
|
case (DeleteRequest):
|
||||||
|
newOp->theStatus = GetValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newOp->theStatus = SetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Uint32 * src = (Uint32*)tRecAttr->aRef();
|
const Uint32 * src = (Uint32*)tRecAttr->aRef();
|
||||||
const Uint32 tScanInfo = src[len] & 0x3FFFF;
|
const Uint32 tScanInfo = src[len] & 0x3FFFF;
|
||||||
const Uint32 tTakeOverFragment = src[len] >> 20;
|
const Uint32 tTakeOverFragment = src[len] >> 20;
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ ErrorBundle ErrorCodes[] = {
|
||||||
{ 4601, AE, "Transaction is not started"},
|
{ 4601, AE, "Transaction is not started"},
|
||||||
{ 4602, AE, "You must call getNdbOperation before executeScan" },
|
{ 4602, AE, "You must call getNdbOperation before executeScan" },
|
||||||
{ 4603, AE, "There can only be ONE operation in a scan transaction" },
|
{ 4603, AE, "There can only be ONE operation in a scan transaction" },
|
||||||
{ 4604, AE, "takeOverScanOp, opType must be UpdateRequest or DeleteRequest" },
|
{ 4604, AE, "takeOverScanOp, to take over a scanned row one must explicitly request keyinfo in readTuples call" },
|
||||||
{ 4605, AE, "You may only call openScanRead or openScanExclusive once for each operation"},
|
{ 4605, AE, "You may only call openScanRead or openScanExclusive once for each operation"},
|
||||||
{ 4607, AE, "There may only be one operation in a scan transaction"},
|
{ 4607, AE, "There may only be one operation in a scan transaction"},
|
||||||
{ 4608, AE, "You can not takeOverScan unless you have used openScanExclusive"},
|
{ 4608, AE, "You can not takeOverScan unless you have used openScanExclusive"},
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ handlerton ndbcluster_hton = {
|
||||||
NULL, /* create_cursor_read_view */
|
NULL, /* create_cursor_read_view */
|
||||||
NULL, /* set_cursor_read_view */
|
NULL, /* set_cursor_read_view */
|
||||||
NULL, /* close_cursor_read_view */
|
NULL, /* close_cursor_read_view */
|
||||||
HTON_NO_FLAGS
|
HTON_CAN_RECREATE
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NDB_AUTO_INCREMENT_RETRIES 10
|
#define NDB_AUTO_INCREMENT_RETRIES 10
|
||||||
|
|
@ -1174,12 +1174,23 @@ void ha_ndbcluster::release_metadata()
|
||||||
|
|
||||||
int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type)
|
int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("ha_ndbcluster::get_ndb_lock_type");
|
||||||
if (type >= TL_WRITE_ALLOW_WRITE)
|
if (type >= TL_WRITE_ALLOW_WRITE)
|
||||||
return NdbOperation::LM_Exclusive;
|
{
|
||||||
else if (uses_blob_value(m_retrieve_all_fields))
|
DBUG_PRINT("info", ("Using exclusive lock"));
|
||||||
return NdbOperation::LM_Read;
|
DBUG_RETURN(NdbOperation::LM_Exclusive);
|
||||||
|
}
|
||||||
|
else if (type == TL_READ_WITH_SHARED_LOCKS ||
|
||||||
|
uses_blob_value(m_retrieve_all_fields))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("Using read lock"));
|
||||||
|
DBUG_RETURN(NdbOperation::LM_Read);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NdbOperation::LM_CommittedRead;
|
{
|
||||||
|
DBUG_PRINT("info", ("Using committed read"));
|
||||||
|
DBUG_RETURN(NdbOperation::LM_CommittedRead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ulong index_type_flags[]=
|
static const ulong index_type_flags[]=
|
||||||
|
|
@ -1679,7 +1690,30 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
|
||||||
int check;
|
int check;
|
||||||
NdbTransaction *trans= m_active_trans;
|
NdbTransaction *trans= m_active_trans;
|
||||||
|
|
||||||
bool contact_ndb= m_lock.type < TL_WRITE_ALLOW_WRITE;
|
if (m_lock_tuple)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Lock level m_lock.type either TL_WRITE_ALLOW_WRITE
|
||||||
|
(SELECT FOR UPDATE) or TL_READ_WITH_SHARED_LOCKS (SELECT
|
||||||
|
LOCK WITH SHARE MODE) and row was not explictly unlocked
|
||||||
|
with unlock_row() call
|
||||||
|
*/
|
||||||
|
NdbConnection *trans= m_active_trans;
|
||||||
|
NdbOperation *op;
|
||||||
|
// Lock row
|
||||||
|
DBUG_PRINT("info", ("Keeping lock on scanned row"));
|
||||||
|
|
||||||
|
if (!(op= m_active_cursor->lockCurrentTuple()))
|
||||||
|
{
|
||||||
|
m_lock_tuple= false;
|
||||||
|
ERR_RETURN(trans->getNdbError());
|
||||||
|
}
|
||||||
|
m_ops_pending++;
|
||||||
|
}
|
||||||
|
m_lock_tuple= false;
|
||||||
|
|
||||||
|
bool contact_ndb= m_lock.type < TL_WRITE_ALLOW_WRITE &&
|
||||||
|
m_lock.type != TL_READ_WITH_SHARED_LOCKS;
|
||||||
do {
|
do {
|
||||||
DBUG_PRINT("info", ("Call nextResult, contact_ndb: %d", contact_ndb));
|
DBUG_PRINT("info", ("Call nextResult, contact_ndb: %d", contact_ndb));
|
||||||
/*
|
/*
|
||||||
|
|
@ -1695,6 +1729,13 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
|
||||||
|
|
||||||
if ((check= cursor->nextResult(contact_ndb, m_force_send)) == 0)
|
if ((check= cursor->nextResult(contact_ndb, m_force_send)) == 0)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Explicitly lock tuple if "select for update" or
|
||||||
|
"select lock in share mode"
|
||||||
|
*/
|
||||||
|
m_lock_tuple= (m_lock.type == TL_WRITE_ALLOW_WRITE
|
||||||
|
||
|
||||||
|
m_lock.type == TL_READ_WITH_SHARED_LOCKS);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
else if (check == 1 || check == 2)
|
else if (check == 1 || check == 2)
|
||||||
|
|
@ -1983,10 +2024,11 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
|
||||||
restart= FALSE;
|
restart= FALSE;
|
||||||
NdbOperation::LockMode lm=
|
NdbOperation::LockMode lm=
|
||||||
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
||||||
|
bool need_pk = (lm == NdbOperation::LM_Read);
|
||||||
if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *)
|
if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *)
|
||||||
m_index[active_index].index,
|
m_index[active_index].index,
|
||||||
(const NDBTAB *) m_table)) ||
|
(const NDBTAB *) m_table)) ||
|
||||||
op->readTuples(lm, 0, parallelism, sorted, descending))
|
op->readTuples(lm, 0, parallelism, sorted, descending, false, need_pk))
|
||||||
ERR_RETURN(trans->getNdbError());
|
ERR_RETURN(trans->getNdbError());
|
||||||
m_active_cursor= op;
|
m_active_cursor= op;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2036,8 +2078,11 @@ int ha_ndbcluster::full_table_scan(byte *buf)
|
||||||
|
|
||||||
NdbOperation::LockMode lm=
|
NdbOperation::LockMode lm=
|
||||||
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
||||||
|
bool need_pk = (lm == NdbOperation::LM_Read);
|
||||||
if (!(op=trans->getNdbScanOperation((const NDBTAB *) m_table)) ||
|
if (!(op=trans->getNdbScanOperation((const NDBTAB *) m_table)) ||
|
||||||
op->readTuples(lm, 0, parallelism))
|
op->readTuples(lm,
|
||||||
|
(need_pk)?NdbScanOperation::SF_KeyInfo:0,
|
||||||
|
parallelism))
|
||||||
ERR_RETURN(trans->getNdbError());
|
ERR_RETURN(trans->getNdbError());
|
||||||
m_active_cursor= op;
|
m_active_cursor= op;
|
||||||
if (generate_scan_filter(m_cond_stack, op))
|
if (generate_scan_filter(m_cond_stack, op))
|
||||||
|
|
@ -2088,6 +2133,11 @@ int ha_ndbcluster::write_row(byte *record)
|
||||||
*/
|
*/
|
||||||
if (!m_use_write && m_ignore_dup_key)
|
if (!m_use_write && m_ignore_dup_key)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
compare if expression with that in start_bulk_insert()
|
||||||
|
start_bulk_insert will set parameters to ensure that each
|
||||||
|
write_row is committed individually
|
||||||
|
*/
|
||||||
int peek_res= peek_indexed_rows(record);
|
int peek_res= peek_indexed_rows(record);
|
||||||
|
|
||||||
if (!peek_res)
|
if (!peek_res)
|
||||||
|
|
@ -2327,6 +2377,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
|
||||||
DBUG_PRINT("info", ("Calling updateTuple on cursor"));
|
DBUG_PRINT("info", ("Calling updateTuple on cursor"));
|
||||||
if (!(op= cursor->updateCurrentTuple()))
|
if (!(op= cursor->updateCurrentTuple()))
|
||||||
ERR_RETURN(trans->getNdbError());
|
ERR_RETURN(trans->getNdbError());
|
||||||
|
m_lock_tuple= false;
|
||||||
m_ops_pending++;
|
m_ops_pending++;
|
||||||
if (uses_blob_value(FALSE))
|
if (uses_blob_value(FALSE))
|
||||||
m_blobs_pending= TRUE;
|
m_blobs_pending= TRUE;
|
||||||
|
|
@ -2406,6 +2457,7 @@ int ha_ndbcluster::delete_row(const byte *record)
|
||||||
DBUG_PRINT("info", ("Calling deleteTuple on cursor"));
|
DBUG_PRINT("info", ("Calling deleteTuple on cursor"));
|
||||||
if (cursor->deleteCurrentTuple() != 0)
|
if (cursor->deleteCurrentTuple() != 0)
|
||||||
ERR_RETURN(trans->getNdbError());
|
ERR_RETURN(trans->getNdbError());
|
||||||
|
m_lock_tuple= false;
|
||||||
m_ops_pending++;
|
m_ops_pending++;
|
||||||
|
|
||||||
no_uncommitted_rows_update(-1);
|
no_uncommitted_rows_update(-1);
|
||||||
|
|
@ -2529,9 +2581,9 @@ void ha_ndbcluster::unpack_record(byte* buf)
|
||||||
const NdbRecAttr* rec= m_value[hidden_no].rec;
|
const NdbRecAttr* rec= m_value[hidden_no].rec;
|
||||||
DBUG_ASSERT(rec);
|
DBUG_ASSERT(rec);
|
||||||
DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no,
|
DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no,
|
||||||
hidden_col->getName(), rec->u_64_value()));
|
hidden_col->getName(), rec->u_64_value()));
|
||||||
}
|
}
|
||||||
//print_results();
|
print_results();
|
||||||
#endif
|
#endif
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
@ -2605,6 +2657,12 @@ int ha_ndbcluster::index_init(uint index)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_ndbcluster::index_init");
|
DBUG_ENTER("ha_ndbcluster::index_init");
|
||||||
DBUG_PRINT("enter", ("index: %u", index));
|
DBUG_PRINT("enter", ("index: %u", index));
|
||||||
|
/*
|
||||||
|
Locks are are explicitly released in scan
|
||||||
|
unless m_lock.type == TL_READ_HIGH_PRIORITY
|
||||||
|
and no sub-sequent call to unlock_row()
|
||||||
|
*/
|
||||||
|
m_lock_tuple= false;
|
||||||
DBUG_RETURN(handler::index_init(index));
|
DBUG_RETURN(handler::index_init(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3217,6 +3275,19 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows)
|
||||||
DBUG_PRINT("enter", ("rows: %d", (int)rows));
|
DBUG_PRINT("enter", ("rows: %d", (int)rows));
|
||||||
|
|
||||||
m_rows_inserted= (ha_rows) 0;
|
m_rows_inserted= (ha_rows) 0;
|
||||||
|
if (!m_use_write && m_ignore_dup_key)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
compare if expression with that in write_row
|
||||||
|
we have a situation where peek_indexed_rows() will be called
|
||||||
|
so we cannot batch
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("info", ("Batching turned off as duplicate key is "
|
||||||
|
"ignored by using peek_row"));
|
||||||
|
m_rows_to_insert= 1;
|
||||||
|
m_bulk_insert_rows= 1;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
if (rows == (ha_rows) 0)
|
if (rows == (ha_rows) 0)
|
||||||
{
|
{
|
||||||
/* We don't know how many will be inserted, guess */
|
/* We don't know how many will be inserted, guess */
|
||||||
|
|
@ -3613,6 +3684,22 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unlock the last row read in an open scan.
|
||||||
|
Rows are unlocked by default in ndb, but
|
||||||
|
for SELECT FOR UPDATE and SELECT LOCK WIT SHARE MODE
|
||||||
|
locks are kept if unlock_row() is not called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ha_ndbcluster::unlock_row()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("unlock_row");
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("Unlocking row"));
|
||||||
|
m_lock_tuple= false;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start a transaction for running a statement if one is not
|
Start a transaction for running a statement if one is not
|
||||||
already running in a transaction. This will be the case in
|
already running in a transaction. This will be the case in
|
||||||
|
|
@ -4085,6 +4172,12 @@ int ha_ndbcluster::create(const char *name,
|
||||||
set_dbname(name2);
|
set_dbname(name2);
|
||||||
set_tabname(name2);
|
set_tabname(name2);
|
||||||
|
|
||||||
|
if (current_thd->lex->sql_command == SQLCOM_TRUNCATE)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("Dropping and re-creating table for TRUNCATE"));
|
||||||
|
if ((my_errno= delete_table(name)))
|
||||||
|
DBUG_RETURN(my_errno);
|
||||||
|
}
|
||||||
if (create_from_engine)
|
if (create_from_engine)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -4392,15 +4485,29 @@ int ha_ndbcluster::delete_table(const char *name)
|
||||||
|
|
||||||
int ha_ndbcluster::drop_table()
|
int ha_ndbcluster::drop_table()
|
||||||
{
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
Ndb *ndb= get_ndb();
|
Ndb *ndb= get_ndb();
|
||||||
NdbDictionary::Dictionary *dict= ndb->getDictionary();
|
NdbDictionary::Dictionary *dict= ndb->getDictionary();
|
||||||
|
|
||||||
DBUG_ENTER("drop_table");
|
DBUG_ENTER("drop_table");
|
||||||
DBUG_PRINT("enter", ("Deleting %s", m_tabname));
|
DBUG_PRINT("enter", ("Deleting %s", m_tabname));
|
||||||
|
|
||||||
release_metadata();
|
release_metadata();
|
||||||
if (dict->dropTable(m_tabname))
|
while (dict->dropTable(m_tabname))
|
||||||
|
{
|
||||||
|
const NdbError err= dict->getNdbError();
|
||||||
|
switch (err.status)
|
||||||
|
{
|
||||||
|
case NdbError::TemporaryError:
|
||||||
|
if (!thd->killed)
|
||||||
|
continue; // retry indefinitly
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
ERR_RETURN(dict->getNdbError());
|
ERR_RETURN(dict->getNdbError());
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4809,14 +4916,24 @@ int ndbcluster_drop_database(const char *path)
|
||||||
List_iterator_fast<char> it(drop_list);
|
List_iterator_fast<char> it(drop_list);
|
||||||
while ((tabname=it++))
|
while ((tabname=it++))
|
||||||
{
|
{
|
||||||
if (dict->dropTable(tabname))
|
while (dict->dropTable(tabname))
|
||||||
{
|
{
|
||||||
const NdbError err= dict->getNdbError();
|
const NdbError err= dict->getNdbError();
|
||||||
if (err.code != 709)
|
switch (err.status)
|
||||||
|
{
|
||||||
|
case NdbError::TemporaryError:
|
||||||
|
if (!thd->killed)
|
||||||
|
continue; // retry indefinitly
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (err.code != 709) // 709: No such table existed
|
||||||
{
|
{
|
||||||
ERR_PRINT(err);
|
ERR_PRINT(err);
|
||||||
ret= ndb_to_mysql_error(&err);
|
ret= ndb_to_mysql_error(&err);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
|
|
@ -5891,6 +6008,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||||
byte *end_of_buffer= (byte*)buffer->buffer_end;
|
byte *end_of_buffer= (byte*)buffer->buffer_end;
|
||||||
NdbOperation::LockMode lm=
|
NdbOperation::LockMode lm=
|
||||||
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
|
||||||
|
bool need_pk = (lm == NdbOperation::LM_Read);
|
||||||
const NDBTAB *tab= (const NDBTAB *) m_table;
|
const NDBTAB *tab= (const NDBTAB *) m_table;
|
||||||
const NDBINDEX *unique_idx= (NDBINDEX *) m_index[active_index].unique_index;
|
const NDBINDEX *unique_idx= (NDBINDEX *) m_index[active_index].unique_index;
|
||||||
const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index;
|
const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index;
|
||||||
|
|
@ -5957,7 +6075,8 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||||
end_of_buffer -= reclength;
|
end_of_buffer -= reclength;
|
||||||
}
|
}
|
||||||
else if ((scanOp= m_active_trans->getNdbIndexScanOperation(idx, tab))
|
else if ((scanOp= m_active_trans->getNdbIndexScanOperation(idx, tab))
|
||||||
&&!scanOp->readTuples(lm, 0, parallelism, sorted, FALSE, TRUE)
|
&&!scanOp->readTuples(lm, 0, parallelism, sorted,
|
||||||
|
FALSE, TRUE, need_pk)
|
||||||
&&!generate_scan_filter(m_cond_stack, scanOp)
|
&&!generate_scan_filter(m_cond_stack, scanOp)
|
||||||
&&!define_read_attrs(end_of_buffer-reclength, scanOp))
|
&&!define_read_attrs(end_of_buffer-reclength, scanOp))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,7 @@ class ha_ndbcluster: public handler
|
||||||
int extra(enum ha_extra_function operation);
|
int extra(enum ha_extra_function operation);
|
||||||
int extra_opt(enum ha_extra_function operation, ulong cache_size);
|
int extra_opt(enum ha_extra_function operation, ulong cache_size);
|
||||||
int external_lock(THD *thd, int lock_type);
|
int external_lock(THD *thd, int lock_type);
|
||||||
|
void unlock_row();
|
||||||
int start_stmt(THD *thd, thr_lock_type lock_type);
|
int start_stmt(THD *thd, thr_lock_type lock_type);
|
||||||
const char * table_type() const;
|
const char * table_type() const;
|
||||||
const char ** bas_ext() const;
|
const char ** bas_ext() const;
|
||||||
|
|
@ -684,6 +685,7 @@ private:
|
||||||
char m_tabname[FN_HEADLEN];
|
char m_tabname[FN_HEADLEN];
|
||||||
ulong m_table_flags;
|
ulong m_table_flags;
|
||||||
THR_LOCK_DATA m_lock;
|
THR_LOCK_DATA m_lock;
|
||||||
|
bool m_lock_tuple;
|
||||||
NDB_SHARE *m_share;
|
NDB_SHARE *m_share;
|
||||||
NDB_INDEX_DATA m_index[MAX_KEY];
|
NDB_INDEX_DATA m_index[MAX_KEY];
|
||||||
// NdbRecAttr has no reference to blob
|
// NdbRecAttr has no reference to blob
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ bool Cached_item_decimal::cmp()
|
||||||
{
|
{
|
||||||
my_decimal tmp;
|
my_decimal tmp;
|
||||||
my_decimal *ptmp= item->val_decimal(&tmp);
|
my_decimal *ptmp= item->val_decimal(&tmp);
|
||||||
if (null_value != item->null_value || my_decimal_cmp(&value, ptmp) == 0)
|
if (null_value != item->null_value || my_decimal_cmp(&value, ptmp))
|
||||||
{
|
{
|
||||||
null_value= item->null_value;
|
null_value= item->null_value;
|
||||||
my_decimal2decimal(ptmp, &value);
|
my_decimal2decimal(ptmp, &value);
|
||||||
|
|
|
||||||
|
|
@ -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(<ime);
|
store_now_in_TIME(<ime);
|
||||||
value= TIME_to_ulonglong_time(<ime);
|
value= TIME_to_ulonglong_time(<ime);
|
||||||
|
|
@ -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(<ime);
|
store_now_in_TIME(<ime);
|
||||||
|
|
@ -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 @@ public:
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@ exit:
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
*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);
|
||||||
|
|
|
||||||
|
|
@ -5004,7 +5004,14 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
|
||||||
if (all_tables->security_ctx)
|
if (all_tables->security_ctx)
|
||||||
thd->security_ctx= all_tables->security_ctx;
|
thd->security_ctx= all_tables->security_ctx;
|
||||||
|
|
||||||
if (check_access(thd, privilege, all_tables->db,
|
const char *db_name;
|
||||||
|
if ((all_tables->view || all_tables->field_translation) &&
|
||||||
|
!all_tables->schema_table)
|
||||||
|
db_name= all_tables->view_db.str;
|
||||||
|
else
|
||||||
|
db_name= all_tables->db;
|
||||||
|
|
||||||
|
if (check_access(thd, privilege, db_name,
|
||||||
&all_tables->grant.privilege, 0, 0,
|
&all_tables->grant.privilege, 0, 0,
|
||||||
test(all_tables->schema_table)))
|
test(all_tables->schema_table)))
|
||||||
goto deny;
|
goto deny;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
### BEGIN INIT INFO
|
### BEGIN INIT INFO
|
||||||
# Provides: mysql
|
# Provides: mysql
|
||||||
# Required-Start: $local_fs $network $remote_fs
|
# Required-Start: $local_fs $network $remote_fs
|
||||||
|
# Should-Start: ypbind nscd ldap ntpd xntpd
|
||||||
# Required-Stop: $local_fs $network $remote_fs
|
# Required-Stop: $local_fs $network $remote_fs
|
||||||
# Default-Start: 2 3 4 5
|
# Default-Start: 2 3 4 5
|
||||||
# Default-Stop: 0 1 6
|
# Default-Stop: 0 1 6
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue