Reviewing new pushed code
- CHAR() now returns binary string as default - CHAR(X*65536+Y*256+Z) is now equal to CHAR(X,Y,Z) independent of the character set for CHAR() - Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() (Some old systems returns ETIME and it's safer to test for both values than to try to write a wrapper for each old system) - Fixed new introduced bug in NOT BETWEEN X and X - Ensure we call commit_by_xid or rollback_by_xid for all engines, even if one engine has failed - Use octet2hex() for all conversion of string to hex - Simplify and optimize code client/mysqldump.c: Simple optimizations of new code Indentation fixes client/mysqltest.c: Removed not needed variable include/mysql_com.h: Made octec2hex() more usable mysql-test/r/ctype_utf8.result: CHAR() now returns binary string as default mysql-test/r/func_str.result: CHAR() now returns binary string as default mysql-test/r/range.result: Added test to verify new introduced bug in NOT BETWEEN X and X mysql-test/r/user_var-binlog.result: CHAR() now returns binary string as default mysql-test/r/view.result: More tests of view rename mysql-test/t/ctype_utf8.test: CHAR() now returns binary string as default mysql-test/t/func_str.test: CHAR() now returns binary string as default mysql-test/t/range.test: Added test to verify new introduced bug in NOT BETWEEN X and X mysql-test/t/view.test: More tests of view rename mysys/mf_keycache.c: Indentation changes Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() mysys/my_os2cond.c: Fix to MySQL coding style Optimized functions mysys/thr_lock.c: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() mysys/thr_mutex.c: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() server-tools/instance-manager/instance.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() server-tools/instance-manager/thread_registry.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() sql/ha_federated.cc: Use octet2hex() sql/ha_ndbcluster.cc: Removed not used variable sql/handler.cc: Simplify code Use *NONE* instead of 'none' for not existing storage engine Ensure we call commit_by_xid or rollback_by_xid for all engines, even if one engine has failed sql/item.h: Remove not needed test for *ref. (If ref is set, it should never point at 0) sql/item_func.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() Simplify code More comments Require that last argument to find_and_check_access() is given (Made code shorter and faster) sql/item_strfunc.cc: Changed CHAR() to return result in binary collation CHAR(X*65536+Y*256+Z) is now equal to CHAR(X,Y,Z) independent of the character set for CHAR() Bar will shortly add the following syntax: CHAR(.... USING character_set) and ensure that CONVERT(CHAR(....) USING utf8) cuts not legal utf8 strings Use ocet2hex() sql/item_strfunc.h: CHAR() now returns a binary string sql/log_event.cc: Use octet2hex() Simplify code sql/parse_file.cc: Indentation fixes Use for() instead of while() sql/password.c: Make octet2hex() more generally usable by returning pointer to end 0 sql/slave.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() sql/sql_base.cc: Indentation fixes sql/sql_insert.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() sql/sql_manager.cc: Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() sql/sql_parse.cc: Don't check thd->db when checking for function privileges sql/sql_prepare.cc: Fixed wrong merge sql/sql_select.cc: Fixed new bug for NOT BETWEEN X and X sql/sql_show.cc: Removed not used variable sql/sql_table.cc: Indentation fixed Removed DBUG_PRINT that is obvious from context sql/sql_view.cc: Simplify code sql/unireg.cc: Use octet2hex()
This commit is contained in:
parent
c2621f3dcb
commit
0ce12f70ed
@ -30,7 +30,7 @@
|
||||
** master/autocommit code by Brian Aker <brian@tangent.org>
|
||||
** SSL by
|
||||
** Andrei Errapart <andreie@no.spam.ee>
|
||||
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
|
||||
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
|
||||
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
|
||||
** and adapted to mysqldump 05/11/01 by Jani Tolonen
|
||||
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
|
||||
@ -1287,7 +1287,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
{
|
||||
MYSQL_RES *tableRes;
|
||||
MYSQL_ROW row;
|
||||
my_bool init=0;
|
||||
my_bool init=0, delayed, write_data, complete_insert;
|
||||
uint num_fields;
|
||||
char *result_table, *opt_quoted_table;
|
||||
const char *insert_option;
|
||||
@ -1296,31 +1296,33 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
char query_buff[512];
|
||||
FILE *sql_file = md_result_file;
|
||||
int len;
|
||||
|
||||
DBUG_ENTER("get_table_structure");
|
||||
DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
|
||||
DBUG_PRINT("enter", ("db: %s table: %s", db, table));
|
||||
|
||||
*ignore_flag= check_if_ignore_table(table, table_type);
|
||||
|
||||
if (opt_delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
|
||||
delayed= opt_delayed;
|
||||
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
|
||||
{
|
||||
delayed= 0;
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"-- Unable to use delayed inserts for table '%s' because it's of\
|
||||
type %s\n", table, table_type);
|
||||
"-- Warning: Unable to use delayed inserts for table '%s' "
|
||||
"because it's of type %s\n", table, table_type);
|
||||
}
|
||||
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
complete_insert= 0;
|
||||
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
|
||||
{
|
||||
complete_insert= opt_complete_insert;
|
||||
if (!insert_pat_inited)
|
||||
insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
|
||||
else
|
||||
dynstr_set(&insert_pat, "");
|
||||
}
|
||||
|
||||
insert_option= ((opt_delayed && opt_ignore &&
|
||||
!(*ignore_flag & IGNORE_INSERT_DELAYED)) ?
|
||||
" DELAYED IGNORE " :
|
||||
opt_delayed && !(*ignore_flag & IGNORE_INSERT_DELAYED) ? " DELAYED " :
|
||||
opt_ignore ? " IGNORE " : "");
|
||||
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
|
||||
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
|
||||
@ -1452,17 +1454,18 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
}
|
||||
|
||||
/*
|
||||
if *ignore_flag & IGNORE_DATA is true, then we don't build up insert statements
|
||||
for the table's data. Note: in subsequent lines of code, this test will
|
||||
have to be performed each time we are appending to insert_pat.
|
||||
If write_data is true, then we build up insert statements for
|
||||
the table's data. Note: in subsequent lines of code, this test
|
||||
will have to be performed each time we are appending to
|
||||
insert_pat.
|
||||
*/
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
if (write_data)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, "INSERT ", 7);
|
||||
dynstr_append(&insert_pat, insert_option);
|
||||
dynstr_append_mem(&insert_pat, "INTO ", 5);
|
||||
dynstr_append(&insert_pat, opt_quoted_table);
|
||||
if (opt_complete_insert)
|
||||
if (complete_insert)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, " (", 2);
|
||||
}
|
||||
@ -1476,15 +1479,16 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
|
||||
while ((row=mysql_fetch_row(tableRes)))
|
||||
{
|
||||
if (init)
|
||||
if (complete_insert)
|
||||
{
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (init)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, ", ", 2);
|
||||
}
|
||||
init=1;
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
}
|
||||
init=1;
|
||||
dynstr_append(&insert_pat,
|
||||
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
||||
}
|
||||
}
|
||||
num_fields= (uint) mysql_num_rows(tableRes);
|
||||
mysql_free_result(tableRes);
|
||||
@ -1532,7 +1536,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
check_io(sql_file);
|
||||
}
|
||||
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
if (write_data)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, "INSERT ", 7);
|
||||
dynstr_append(&insert_pat, insert_option);
|
||||
@ -1558,11 +1562,11 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
fputs(",\n",sql_file);
|
||||
check_io(sql_file);
|
||||
}
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (complete_insert)
|
||||
dynstr_append_mem(&insert_pat, ", ", 2);
|
||||
}
|
||||
init=1;
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (opt_complete_insert)
|
||||
dynstr_append(&insert_pat,
|
||||
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
||||
if (!tFlag)
|
||||
@ -1723,7 +1727,7 @@ continue_xml:
|
||||
check_io(sql_file);
|
||||
}
|
||||
}
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (opt_complete_insert)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, ") VALUES ", 9);
|
||||
if (!extended_insert)
|
||||
@ -1877,7 +1881,7 @@ static void dump_table(char *table, char *db)
|
||||
{
|
||||
char ignore_flag;
|
||||
char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
|
||||
char table_type[NAME_LEN];
|
||||
char table_type[NAME_LEN];
|
||||
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
|
||||
char *query= query_buf;
|
||||
int error= 0;
|
||||
@ -1892,7 +1896,7 @@ static void dump_table(char *table, char *db)
|
||||
Make sure you get the create table info before the following check for
|
||||
--no-data flag below. Otherwise, the create table info won't be printed.
|
||||
*/
|
||||
num_fields= get_table_structure(table, db, (char *)&table_type, &ignore_flag);
|
||||
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
|
||||
|
||||
/* Check --no-data flag */
|
||||
if (dFlag)
|
||||
@ -1904,7 +1908,9 @@ static void dump_table(char *table, char *db)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("ignore_flag %x num_fields %d", ignore_flag, num_fields));
|
||||
DBUG_PRINT("info",
|
||||
("ignore_flag: %x num_fields: %d", (int) ignore_flag,
|
||||
num_fields));
|
||||
/*
|
||||
If the table type is a merge table or any type that has to be
|
||||
_completely_ ignored and no data dumped
|
||||
@ -1913,7 +1919,7 @@ static void dump_table(char *table, char *db)
|
||||
{
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"-- Skipping data for table '%s' because it's of type %s\n",
|
||||
"-- Warning: Skipping data for table '%s' because it's of type %s\n",
|
||||
table, table_type);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -1930,7 +1936,6 @@ static void dump_table(char *table, char *db)
|
||||
result_table= quote_name(table,table_buff, 1);
|
||||
opt_quoted_table= quote_name(table, table_buff2, 0);
|
||||
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "-- Sending SELECT query...\n");
|
||||
if (path)
|
||||
@ -2992,7 +2997,7 @@ char check_if_ignore_table(const char *table_name, char *table_type)
|
||||
DBUG_RETURN(result); /* assume table is ok */
|
||||
}
|
||||
if (!(row[1]))
|
||||
strmake(table_type,"VIEW", NAME_LEN-1);
|
||||
strmake(table_type, "VIEW", NAME_LEN-1);
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
@ -737,9 +737,7 @@ err:
|
||||
static int check_result(DYNAMIC_STRING* ds, const char *fname,
|
||||
my_bool require_option)
|
||||
{
|
||||
int error= RESULT_OK;
|
||||
int res= dyn_string_cmp(ds, fname);
|
||||
|
||||
DBUG_ENTER("check_result");
|
||||
|
||||
if (res && require_option)
|
||||
@ -749,18 +747,16 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname,
|
||||
break; /* ok */
|
||||
case RESULT_LENGTH_MISMATCH:
|
||||
verbose_msg("Result length mismatch");
|
||||
error= RESULT_LENGTH_MISMATCH;
|
||||
break;
|
||||
case RESULT_CONTENT_MISMATCH:
|
||||
verbose_msg("Result content mismatch");
|
||||
error= RESULT_CONTENT_MISMATCH;
|
||||
break;
|
||||
default: /* impossible */
|
||||
die("Unknown error code from dyn_string_cmp()");
|
||||
}
|
||||
if (error)
|
||||
if (res != RESULT_OK)
|
||||
reject_dump(fname, ds->str, ds->length);
|
||||
DBUG_RETURN(error);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,7 +409,7 @@ my_bool check_scramble(const char *reply, const char *message,
|
||||
const unsigned char *hash_stage2);
|
||||
void get_salt_from_password(unsigned char *res, const char *password);
|
||||
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
|
||||
void octet2hex(char *to, const unsigned char *str, unsigned int len);
|
||||
char *octet2hex(char *to, const char *str, unsigned int len);
|
||||
|
||||
/* end of password.c */
|
||||
|
||||
|
@ -1079,29 +1079,31 @@ char(53647)
|
||||
select char(0xff,0x8f);
|
||||
char(0xff,0x8f)
|
||||
ÿ<EFBFBD>
|
||||
Warnings:
|
||||
Warning 1300 Invalid utf8 character string: 'FF8F'
|
||||
set sql_mode=traditional;
|
||||
select char(0xff,0x8f);
|
||||
char(0xff,0x8f)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'FF8F'
|
||||
ÿ<EFBFBD>
|
||||
select convert(char(0xff,0x8f) using utf8);
|
||||
convert(char(0xff,0x8f) using utf8)
|
||||
ÿ<EFBFBD>
|
||||
select char(195);
|
||||
char(195)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'C3'
|
||||
Ã
|
||||
select convert(char(195) using utf8);
|
||||
convert(char(195) using utf8)
|
||||
Ã
|
||||
select char(196);
|
||||
char(196)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'C4'
|
||||
select char(2557);
|
||||
char(2557)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'FD'
|
||||
Ä
|
||||
select convert(char(196) using utf8);
|
||||
convert(char(196) using utf8)
|
||||
Ä
|
||||
select hex(char(2557));
|
||||
hex(char(2557))
|
||||
09FD
|
||||
select hex(convert(char(2557) using utf8));
|
||||
hex(convert(char(2557) using utf8))
|
||||
09FD
|
||||
set names utf8;
|
||||
create table t1 (a char(1)) default character set utf8;
|
||||
create table t2 (a char(1)) default character set utf8;
|
||||
|
@ -21,6 +21,9 @@ length(_latin1'\n\t\n\b\0\\_\\%\\')
|
||||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h');
|
||||
concat('monty',' was here ','again') length('hello') char(ascii('h')) ord('h')
|
||||
monty was here again 5 h 104
|
||||
select hex(char(256));
|
||||
hex(char(256))
|
||||
0100
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
|
||||
1 0 4
|
||||
@ -598,7 +601,7 @@ collation(hex(130)) coercibility(hex(130))
|
||||
latin1_swedish_ci 4
|
||||
select collation(char(130)), coercibility(hex(130));
|
||||
collation(char(130)) coercibility(hex(130))
|
||||
latin1_swedish_ci 4
|
||||
binary 4
|
||||
select collation(format(130,10)), coercibility(format(130,10));
|
||||
collation(format(130,10)) coercibility(format(130,10))
|
||||
latin1_swedish_ci 4
|
||||
@ -720,7 +723,7 @@ t1 CREATE TABLE `t1` (
|
||||
`oct(130)` varchar(64) NOT NULL default '',
|
||||
`conv(130,16,10)` varchar(64) NOT NULL default '',
|
||||
`hex(130)` varchar(6) NOT NULL default '',
|
||||
`char(130)` varchar(1) NOT NULL default '',
|
||||
`char(130)` varbinary(1) NOT NULL default '',
|
||||
`format(130,10)` varchar(4) NOT NULL default '',
|
||||
`left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||
`right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||
|
@ -809,4 +809,11 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
explain select * from t2 where a = 'a' or a='a ';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref a a 13 const # Using where
|
||||
update t1 set a='b' where a<>'a';
|
||||
explain select * from t1 where a not between 'b' and 'b';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 13 NULL # Using where
|
||||
select * from t1 where a not between 'b' and 'b';
|
||||
a filler
|
||||
a
|
||||
drop table t1,t2,t3;
|
||||
|
@ -11,7 +11,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 User var 1 139 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
|
||||
master-bin.000001 139 Query 1 231 use `test`; INSERT INTO t1 VALUES(@`a b`)
|
||||
master-bin.000001 231 User var 1 273 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
|
||||
master-bin.000001 273 User var 1 311 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci
|
||||
master-bin.000001 273 User var 1 311 @`var2`=_binary 0x61 COLLATE binary
|
||||
master-bin.000001 311 Query 1 411 use `test`; insert into t1 values (@var1),(@var2)
|
||||
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||
@ -24,7 +24,7 @@ SET @@session.sql_mode=0;
|
||||
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
|
||||
INSERT INTO t1 VALUES(@`a b`);
|
||||
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`;
|
||||
SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`;
|
||||
SET @`var2`:=_binary 0x61 COLLATE `binary`;
|
||||
SET TIMESTAMP=10000;
|
||||
insert into t1 values (@var1),(@var2);
|
||||
# End of log file
|
||||
|
@ -847,13 +847,16 @@ cast(1 as char(3))
|
||||
drop view v1;
|
||||
create table t1 (a int);
|
||||
create view v1 as select a from t1;
|
||||
create database seconddb;
|
||||
rename table v1 to seconddb.v1;
|
||||
ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed.
|
||||
create view v3 as select a from t1;
|
||||
create database mysqltest;
|
||||
rename table v1 to mysqltest.v1;
|
||||
ERROR HY000: Changing schema from 'test' to 'mysqltest' is not allowed.
|
||||
rename table v1 to v2;
|
||||
rename table v3 to v1, v2 to t1;
|
||||
ERROR 42S01: Table 't1' already exists
|
||||
drop table t1;
|
||||
drop view v2;
|
||||
drop database seconddb;
|
||||
drop view v2,v3;
|
||||
drop database mysqltest;
|
||||
create view v1 as select 'a',1;
|
||||
create view v2 as select * from v1 union all select * from v1;
|
||||
create view v3 as select * from v2 where 1 = (select `1` from v2);
|
||||
|
@ -880,9 +880,13 @@ select char(0xff,0x8f);
|
||||
# incorrect value in strict mode: return NULL with "Error" level warning
|
||||
set sql_mode=traditional;
|
||||
select char(0xff,0x8f);
|
||||
select convert(char(0xff,0x8f) using utf8);
|
||||
select char(195);
|
||||
select convert(char(195) using utf8);
|
||||
select char(196);
|
||||
select char(2557);
|
||||
select convert(char(196) using utf8);
|
||||
select hex(char(2557));
|
||||
select hex(convert(char(2557) using utf8));
|
||||
|
||||
#
|
||||
# Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters
|
||||
|
@ -15,6 +15,7 @@ select bit_length('\n\t\r\b\0\_\%\\');
|
||||
select char_length('\n\t\r\b\0\_\%\\');
|
||||
select length(_latin1'\n\t\n\b\0\\_\\%\\');
|
||||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h');
|
||||
select hex(char(256));
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
|
||||
select position(binary 'll' in 'hello'),position('a' in binary 'hello');
|
||||
|
@ -625,4 +625,9 @@ explain select * from t2 where a between 'a' and 'a ';
|
||||
--replace_column 9 #
|
||||
explain select * from t2 where a = 'a' or a='a ';
|
||||
|
||||
update t1 set a='b' where a<>'a';
|
||||
--replace_column 9 #
|
||||
explain select * from t1 where a not between 'b' and 'b';
|
||||
select * from t1 where a not between 'b' and 'b';
|
||||
|
||||
drop table t1,t2,t3;
|
||||
|
@ -790,13 +790,16 @@ drop view v1;
|
||||
#
|
||||
create table t1 (a int);
|
||||
create view v1 as select a from t1;
|
||||
create database seconddb;
|
||||
create view v3 as select a from t1;
|
||||
create database mysqltest;
|
||||
-- error 1450
|
||||
rename table v1 to seconddb.v1;
|
||||
rename table v1 to mysqltest.v1;
|
||||
rename table v1 to v2;
|
||||
--error 1050
|
||||
rename table v3 to v1, v2 to t1;
|
||||
drop table t1;
|
||||
drop view v2;
|
||||
drop database seconddb;
|
||||
drop view v2,v3;
|
||||
drop database mysqltest;
|
||||
|
||||
#
|
||||
# bug handling from VIEWs
|
||||
|
@ -2750,9 +2750,12 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
|
||||
gettimeofday(&now, &tz);
|
||||
/* Prepare timeout value */
|
||||
timeout.tv_sec= now.tv_sec + KEYCACHE_TIMEOUT;
|
||||
timeout.tv_nsec= now.tv_usec * 1000; /* timeval uses microseconds. */
|
||||
/* timespec uses nanoseconds. */
|
||||
/* 1 nanosecond = 1000 micro seconds. */
|
||||
/*
|
||||
timeval uses microseconds.
|
||||
timespec uses nanoseconds.
|
||||
1 nanosecond = 1000 micro seconds
|
||||
*/
|
||||
timeout.tv_nsec= now.tv_usec * 1000;
|
||||
KEYCACHE_THREAD_TRACE_END("started waiting");
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
cnt++;
|
||||
@ -2762,17 +2765,15 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
|
||||
#endif
|
||||
rc= pthread_cond_timedwait(cond, mutex, &timeout);
|
||||
KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
if (rc == ETIMEDOUT)
|
||||
if (rc == ETIMEDOUT || rc == ETIME)
|
||||
{
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
fprintf(keycache_debug_log,"aborted by keycache timeout\n");
|
||||
fclose(keycache_debug_log);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc == ETIMEDOUT)
|
||||
keycache_dump();
|
||||
}
|
||||
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
KEYCACHE_DBUG_ASSERT(rc != ETIMEDOUT);
|
||||
|
@ -22,7 +22,7 @@
|
||||
** The following is a simple implementation of posix conditions
|
||||
*****************************************************************************/
|
||||
|
||||
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
|
||||
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
|
||||
#include "mysys_priv.h"
|
||||
#if defined(THREAD) && defined(OS2)
|
||||
#include <m_string.h>
|
||||
@ -31,134 +31,109 @@
|
||||
|
||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||
{
|
||||
APIRET rc = 0;
|
||||
HEV event;
|
||||
cond->waiting=0;
|
||||
/* Warp3 FP29 or Warp4 FP4 or better required */
|
||||
rc = DosCreateEventSem( NULL, &cond->semaphore, 0x0800, 0);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
|
||||
cond->waiting= 0;
|
||||
/* Warp3 FP29 or Warp4 FP4 or better required */
|
||||
if (DosCreateEventSem(NULL, &cond->semaphore, 0x0800, 0))
|
||||
return ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
APIRET rc;
|
||||
|
||||
do {
|
||||
rc = DosCloseEventSem(cond->semaphore);
|
||||
if (rc == 301) DosPostEventSem(cond->semaphore);
|
||||
} while (rc == 301);
|
||||
if (rc)
|
||||
return EINVAL;
|
||||
|
||||
return 0;
|
||||
for (;;)
|
||||
{
|
||||
APIRET rc;
|
||||
if ((rc= DosCloseEventSem(cond->semaphore)) != 301)
|
||||
return rc ? EINVAL : 0;
|
||||
DosPostEventSem(cond->semaphore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
APIRET rc;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
cond->waiting++;
|
||||
|
||||
if (mutex) pthread_mutex_unlock(mutex);
|
||||
|
||||
rc = DosWaitEventSem(cond->semaphore,SEM_INDEFINITE_WAIT);
|
||||
if (rc != 0)
|
||||
rval = EINVAL;
|
||||
|
||||
if (mutex) pthread_mutex_lock(mutex);
|
||||
|
||||
cond->waiting--;
|
||||
|
||||
return rval;
|
||||
int rval= 0;
|
||||
cond->waiting++;
|
||||
if (mutex)
|
||||
pthread_mutex_unlock(mutex);
|
||||
if (DosWaitEventSem(cond->semaphore, SEM_INDEFINITE_WAIT))
|
||||
rval= EINVAL;
|
||||
if (mutex)
|
||||
pthread_mutex_lock(mutex);
|
||||
cond->waiting--;
|
||||
return rval;
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
struct timespec *abstime)
|
||||
{
|
||||
struct timeb curtime;
|
||||
int result;
|
||||
long timeout;
|
||||
APIRET rc;
|
||||
int rval;
|
||||
int rval= 0;
|
||||
|
||||
_ftime(&curtime);
|
||||
timeout= ((long) (abstime->ts_sec - curtime.time)*1000L +
|
||||
(long)((abstime->ts_nsec/1000) - curtime.millitm)/1000L);
|
||||
if (timeout < 0) /* Some safety */
|
||||
timeout = 0L;
|
||||
_ftime(&curtime);
|
||||
timeout= ((long) (abstime->ts_sec - curtime.time) * 1000L +
|
||||
(long) ((abstime->ts_nsec / 1000) - curtime.millitm) / 1000L);
|
||||
if (timeout < 0) /* Some safety */
|
||||
timeout= 0L;
|
||||
|
||||
rval = 0;
|
||||
cond->waiting++;
|
||||
cond->waiting++;
|
||||
|
||||
if (mutex) pthread_mutex_unlock(mutex);
|
||||
if (mutex)
|
||||
pthread_mutex_unlock(mutex);
|
||||
if (DosWaitEventSem(cond->semaphore, timeout) != 0)
|
||||
rval= ETIMEDOUT;
|
||||
if (mutex)
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
rc = DosWaitEventSem(cond->semaphore, timeout);
|
||||
if (rc != 0)
|
||||
rval= ETIMEDOUT;
|
||||
cond->waiting--;
|
||||
|
||||
if (mutex) pthread_mutex_lock(mutex);
|
||||
|
||||
cond->waiting--;
|
||||
|
||||
return rval;
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
APIRET rc;
|
||||
|
||||
/* Bring the next thread off the condition queue: */
|
||||
rc = DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
/* Bring the next thread off the condition queue: */
|
||||
DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
int i;
|
||||
APIRET rc;
|
||||
|
||||
/*
|
||||
* Enter a loop to bring all threads off the
|
||||
* condition queue:
|
||||
*/
|
||||
i = cond->waiting;
|
||||
while (i--) rc = DosPostEventSem(cond->semaphore);
|
||||
|
||||
return 0 ;
|
||||
int i;
|
||||
/* Enter a loop to bring all threads off the condition queue */
|
||||
for (i= cond->waiting; i--;)
|
||||
DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pthread_attr_init(pthread_attr_t *connect_att)
|
||||
{
|
||||
connect_att->dwStackSize = 0;
|
||||
connect_att->dwCreatingFlag = 0;
|
||||
connect_att->priority = 0;
|
||||
connect_att->dwStackSize= 0;
|
||||
connect_att->dwCreatingFlag= 0;
|
||||
connect_att->priority= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
|
||||
int pthread_attr_setstacksize(pthread_attr_t *connect_att, DWORD stack)
|
||||
{
|
||||
connect_att->dwStackSize=stack;
|
||||
connect_att->dwStackSize= stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority)
|
||||
int pthread_attr_setprio(pthread_attr_t *connect_att, int priority)
|
||||
{
|
||||
connect_att->priority=priority;
|
||||
connect_att->priority= priority;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_destroy(pthread_attr_t *connect_att)
|
||||
{
|
||||
bzero((gptr) connect_att,sizeof(*connect_att));
|
||||
bzero((gptr) connect_att, sizeof(*connect_att));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -166,22 +141,22 @@ int pthread_attr_destroy(pthread_attr_t *connect_att)
|
||||
** Fix localtime_r() to be a bit safer
|
||||
****************************************************************************/
|
||||
|
||||
struct tm *localtime_r(const time_t *timep,struct tm *tmp)
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *tmp)
|
||||
{
|
||||
if (*timep == (time_t) -1) /* This will crash win32 */
|
||||
if (*timep == (time_t) - 1) /* This will crash win32 */
|
||||
{
|
||||
bzero(tmp,sizeof(*tmp));
|
||||
bzero(tmp, sizeof(*tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tm *res=localtime(timep);
|
||||
if (!res) /* Wrong date */
|
||||
struct tm *res= localtime(timep);
|
||||
if (!res) /* Wrong date */
|
||||
{
|
||||
bzero(tmp,sizeof(*tmp)); /* Keep things safe */
|
||||
bzero(tmp, sizeof(*tmp)); /* Keep things safe */
|
||||
return 0;
|
||||
}
|
||||
*tmp= *res;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
#endif /* __WIN__ */
|
||||
#endif /* __WIN__ */
|
||||
|
@ -408,9 +408,10 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
||||
set_timespec(wait_timeout, table_lock_wait_timeout);
|
||||
while (!thread_var->abort || in_wait_list)
|
||||
{
|
||||
int rc= can_deadlock ? pthread_cond_timedwait(cond, &data->lock->mutex,
|
||||
&wait_timeout) :
|
||||
pthread_cond_wait(cond, &data->lock->mutex);
|
||||
int rc= (can_deadlock ?
|
||||
pthread_cond_timedwait(cond, &data->lock->mutex,
|
||||
&wait_timeout) :
|
||||
pthread_cond_wait(cond, &data->lock->mutex));
|
||||
/*
|
||||
We must break the wait if one of the following occurs:
|
||||
- the connection has been aborted (!thread_var->abort), but
|
||||
@ -426,7 +427,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
||||
*/
|
||||
if (data->cond == 0)
|
||||
break;
|
||||
if (rc == ETIMEDOUT)
|
||||
if (rc == ETIMEDOUT || rc == ETIME)
|
||||
{
|
||||
result= THR_LOCK_WAIT_TIMEOUT;
|
||||
break;
|
||||
|
@ -239,7 +239,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_cond_timedwait(cond,&mp->mutex,abstime);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (error && (error != EINTR && error != ETIMEDOUT))
|
||||
if (error && (error != EINTR && error != ETIMEDOUT && error != ETIME))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line);
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ int Instance::stop()
|
||||
status= pthread_cond_timedwait(&COND_instance_stopped,
|
||||
&LOCK_instance,
|
||||
&timeout);
|
||||
if (status == ETIMEDOUT)
|
||||
if (status == ETIMEDOUT || status == ETIME)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
struct timespec *wait_time)
|
||||
{
|
||||
int rc;
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
if (shutdown_in_progress)
|
||||
{
|
||||
@ -154,7 +155,8 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
||||
info->current_cond= cond;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
/* sic: race condition here, cond can be signaled in deliver_shutdown */
|
||||
int rc= pthread_cond_timedwait(cond, mutex, wait_time);
|
||||
if ((rc= pthread_cond_timedwait(cond, mutex, wait_time)) == ETIME)
|
||||
rc= ETIMEDOUT; // For easier usage
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
info->current_cond= 0;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
@ -172,6 +174,7 @@ void Thread_registry::deliver_shutdown()
|
||||
{
|
||||
Thread_info *info;
|
||||
struct timespec shutdown_time;
|
||||
int error;
|
||||
set_timespec(shutdown_time, 1);
|
||||
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
@ -204,11 +207,13 @@ void Thread_registry::deliver_shutdown()
|
||||
released - the only case when the predicate is false is when no other
|
||||
threads exist.
|
||||
*/
|
||||
while (pthread_cond_timedwait(&COND_thread_registry_is_empty,
|
||||
&LOCK_thread_registry,
|
||||
&shutdown_time) != ETIMEDOUT &&
|
||||
while (((error= pthread_cond_timedwait(&COND_thread_registry_is_empty,
|
||||
&LOCK_thread_registry,
|
||||
&shutdown_time)) != ETIMEDOUT &&
|
||||
error != ETIME) &&
|
||||
head.next != &head)
|
||||
;
|
||||
|
||||
/*
|
||||
If previous signals did not reach some threads, they must be sleeping
|
||||
in pthread_cond_wait or in a blocking syscall. Wake them up:
|
||||
|
@ -821,13 +821,8 @@ static bool emit_key_part_element(String *to, KEY_PART_INFO *part,
|
||||
|
||||
*buf++= '0';
|
||||
*buf++= 'x';
|
||||
for (; len; ptr++,len--)
|
||||
{
|
||||
uint tmp= (uint)(uchar) *ptr;
|
||||
*buf++= _dig_vec_upper[tmp >> 4];
|
||||
*buf++= _dig_vec_upper[tmp & 15];
|
||||
}
|
||||
if (to->append(buff, (uint)(buf - buff)))
|
||||
buf= octet2hex(buf, (char*) ptr, len);
|
||||
if (to->append((char*) buff, (uint)(buf - buff)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else if (part->key_part_flag & HA_BLOB_PART)
|
||||
|
@ -5931,7 +5931,6 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
|
||||
{
|
||||
THD *thd; /* needs to be first for thread_stack */
|
||||
Ndb* ndb;
|
||||
int error= 0;
|
||||
struct timespec abstime;
|
||||
|
||||
my_thread_init();
|
||||
@ -5960,9 +5959,9 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&LOCK_ndb_util_thread);
|
||||
error= pthread_cond_timedwait(&COND_ndb_util_thread,
|
||||
&LOCK_ndb_util_thread,
|
||||
&abstime);
|
||||
pthread_cond_timedwait(&COND_ndb_util_thread,
|
||||
&LOCK_ndb_util_thread,
|
||||
&abstime);
|
||||
pthread_mutex_unlock(&LOCK_ndb_util_thread);
|
||||
|
||||
DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %d",
|
||||
|
@ -209,6 +209,8 @@ retest:
|
||||
|
||||
return DB_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
const char *ha_get_storage_engine(enum db_type db_type)
|
||||
{
|
||||
handlerton **types;
|
||||
@ -217,25 +219,19 @@ const char *ha_get_storage_engine(enum db_type db_type)
|
||||
if (db_type == (*types)->db_type)
|
||||
return (*types)->name;
|
||||
}
|
||||
|
||||
return "none";
|
||||
return "*NONE*";
|
||||
}
|
||||
|
||||
|
||||
bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
|
||||
{
|
||||
handlerton **types;
|
||||
for (types= sys_table_types; *types; types++)
|
||||
{
|
||||
if (db_type == (*types)->db_type)
|
||||
{
|
||||
if ((*types)->flags & flag)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
return test((*types)->flags & flag);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE; // No matching engine
|
||||
}
|
||||
|
||||
|
||||
@ -850,18 +846,25 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
|
||||
{
|
||||
handlerton **types;
|
||||
int res= 1;
|
||||
|
||||
for (types= sys_table_types; *types; types++)
|
||||
{
|
||||
if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
|
||||
res= res &&
|
||||
(*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid);
|
||||
{
|
||||
if ((*(commit ? (*types)->commit_by_xid :
|
||||
(*types)->rollback_by_xid))(xid));
|
||||
res= 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/* this does not need to be multi-byte safe or anything */
|
||||
static char* xid_to_str(char *buf, XID *xid)
|
||||
|
@ -1616,7 +1616,7 @@ public:
|
||||
}
|
||||
Item *real_item()
|
||||
{
|
||||
return (ref && *ref) ? (*ref)->real_item() : this;
|
||||
return ref ? (*ref)->real_item() : this;
|
||||
}
|
||||
bool walk(Item_processor processor, byte *arg)
|
||||
{ return (*ref)->walk(processor, arg); }
|
||||
|
103
sql/item_func.cc
103
sql/item_func.cc
@ -32,6 +32,11 @@
|
||||
#include "sp_rcontext.h"
|
||||
#include "sp.h"
|
||||
|
||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||
#define sp_restore_security_context(A,B) while (0) {}
|
||||
#endif
|
||||
|
||||
|
||||
bool check_reserved_words(LEX_STRING *name)
|
||||
{
|
||||
if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
|
||||
@ -3028,9 +3033,13 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
||||
thd->mysys_var->current_cond= &ull->cond;
|
||||
|
||||
set_timespec(abstime,lock_timeout);
|
||||
while (!thd->killed &&
|
||||
pthread_cond_timedwait(&ull->cond, &LOCK_user_locks,
|
||||
&abstime) != ETIMEDOUT && ull->locked) ;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ull->locked)
|
||||
{
|
||||
if (!--ull->count)
|
||||
@ -3074,7 +3083,7 @@ longlong Item_func_get_lock::val_int()
|
||||
struct timespec abstime;
|
||||
THD *thd=current_thd;
|
||||
User_level_lock *ull;
|
||||
int error=0;
|
||||
int error;
|
||||
|
||||
/*
|
||||
In slave thread no need to get locks, everything is serialized. Anyway
|
||||
@ -3130,22 +3139,29 @@ longlong Item_func_get_lock::val_int()
|
||||
thd->mysys_var->current_cond= &ull->cond;
|
||||
|
||||
set_timespec(abstime,timeout);
|
||||
while (!thd->killed &&
|
||||
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
|
||||
!= ETIMEDOUT && error != EINVAL && ull->locked) ;
|
||||
if (thd->killed)
|
||||
error=EINTR; // Return NULL
|
||||
error= 0;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
error= 0;
|
||||
}
|
||||
|
||||
if (ull->locked)
|
||||
{
|
||||
if (!--ull->count)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
delete ull; // Should never happen
|
||||
if (error != ETIMEDOUT)
|
||||
}
|
||||
if (!error) // Killed (thd->killed != 0)
|
||||
{
|
||||
error=1;
|
||||
null_value=1; // Return NULL
|
||||
}
|
||||
}
|
||||
else
|
||||
else // We got the lock
|
||||
{
|
||||
ull->locked=1;
|
||||
ull->thread=thd->real_id;
|
||||
@ -3267,6 +3283,7 @@ void Item_func_benchmark::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
||||
/* This function is just used to create tests with time gaps */
|
||||
|
||||
longlong Item_func_sleep::val_int()
|
||||
@ -3287,10 +3304,14 @@ longlong Item_func_sleep::val_int()
|
||||
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
||||
thd->mysys_var->current_cond= &cond;
|
||||
|
||||
while (!thd->killed &&
|
||||
(error= pthread_cond_timedwait(&cond, &LOCK_user_locks,
|
||||
&abstime)) != ETIMEDOUT &&
|
||||
error != EINVAL) ;
|
||||
error= 0;
|
||||
while (!thd->killed)
|
||||
{
|
||||
error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
error= 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex= 0;
|
||||
@ -3300,7 +3321,7 @@ longlong Item_func_sleep::val_int()
|
||||
pthread_mutex_unlock(&LOCK_user_locks);
|
||||
pthread_cond_destroy(&cond);
|
||||
|
||||
return (error == ETIMEDOUT) ? 0 : 1;
|
||||
return test(!error); // Return 1 killed
|
||||
}
|
||||
|
||||
|
||||
@ -4729,10 +4750,7 @@ Item_func_sp::execute(Item **itp)
|
||||
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif
|
||||
|
||||
error:
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
@ -4846,11 +4864,12 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
||||
find_and_check_access()
|
||||
thd thread handler
|
||||
want_access requested access
|
||||
backup backup of security context or 0
|
||||
save backup of security context
|
||||
|
||||
RETURN
|
||||
FALSE Access granted
|
||||
TRUE Requested access can't be granted or function doesn't exists
|
||||
In this case security context is not changed and *save = 0
|
||||
|
||||
NOTES
|
||||
Checks if requested access to function can be granted to user.
|
||||
@ -4865,12 +4884,11 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
||||
|
||||
bool
|
||||
Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
|
||||
Security_context **backup)
|
||||
Security_context **save)
|
||||
{
|
||||
bool res;
|
||||
Security_context *local_save,
|
||||
**save= (backup ? backup : &local_save);
|
||||
res= TRUE;
|
||||
bool res= TRUE;
|
||||
|
||||
*save= 0; // Safety if error
|
||||
if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
|
||||
{
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
|
||||
@ -4880,26 +4898,31 @@ Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_routine_access(thd, want_access,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
sp_change_security_context(thd, m_sp, save);
|
||||
/*
|
||||
If we changed context to run as another user, we need to check the
|
||||
access right for the new context again as someone may have deleted
|
||||
this person the right to use the procedure
|
||||
|
||||
TODO:
|
||||
Cache if the definer has the right to use the object on the first
|
||||
usage and only reset the cache if someone does a GRANT statement
|
||||
that 'may' affect this.
|
||||
*/
|
||||
if (*save &&
|
||||
check_routine_access(thd, want_access,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
{
|
||||
goto error_check_ctx;
|
||||
sp_restore_security_context(thd, *save);
|
||||
*save= 0; // Safety
|
||||
goto error;
|
||||
}
|
||||
res= FALSE;
|
||||
error_check_ctx:
|
||||
if (*save && (res || !backup))
|
||||
sp_restore_security_context(thd, local_save);
|
||||
error:
|
||||
#else
|
||||
res= 0;
|
||||
error:
|
||||
#endif
|
||||
res= FALSE; // no error
|
||||
|
||||
error:
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -4909,7 +4932,11 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||
bool res;
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
res= Item_func::fix_fields(thd, ref);
|
||||
if (!res && find_and_check_access(thd, EXECUTE_ACL, NULL))
|
||||
res= 1;
|
||||
if (!res)
|
||||
{
|
||||
Security_context *save_ctx;
|
||||
if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx)))
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1964,21 +1964,16 @@ String *Item_func_char::val_str(String *str)
|
||||
int32 num=(int32) args[i]->val_int();
|
||||
if (!args[i]->null_value)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(collation.collation))
|
||||
{
|
||||
if (num&0xFF000000L) {
|
||||
str->append((char)(num>>24));
|
||||
goto b2;
|
||||
} else if (num&0xFF0000L) {
|
||||
b2: str->append((char)(num>>16));
|
||||
goto b1;
|
||||
} else if (num&0xFF00L) {
|
||||
b1: str->append((char)(num>>8));
|
||||
}
|
||||
if (num&0xFF000000L) {
|
||||
str->append((char)(num>>24));
|
||||
goto b2;
|
||||
} else if (num&0xFF0000L) {
|
||||
b2: str->append((char)(num>>16));
|
||||
goto b1;
|
||||
} else if (num&0xFF00L) {
|
||||
b1: str->append((char)(num>>8));
|
||||
}
|
||||
#endif
|
||||
str->append((char)num);
|
||||
str->append((char) num);
|
||||
}
|
||||
}
|
||||
str->set_charset(collation.collation);
|
||||
@ -1997,7 +1992,7 @@ b1: str->append((char)(num>>8));
|
||||
enum MYSQL_ERROR::enum_warning_level level;
|
||||
uint diff= str->length() - wlen;
|
||||
set_if_smaller(diff, 3);
|
||||
octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff);
|
||||
octet2hex(hexbuf, str->ptr() + wlen, diff);
|
||||
if (thd->variables.sql_mode &
|
||||
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
|
||||
{
|
||||
@ -2436,6 +2431,7 @@ String *Item_func_collation::val_str(String *str)
|
||||
|
||||
String *Item_func_hex::val_str(String *str)
|
||||
{
|
||||
String *res;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (args[0]->result_type() != STRING_RESULT)
|
||||
{
|
||||
@ -2464,24 +2460,16 @@ String *Item_func_hex::val_str(String *str)
|
||||
}
|
||||
|
||||
/* Convert given string to a hex string, character by character */
|
||||
String *res= args[0]->val_str(str);
|
||||
const char *from, *end;
|
||||
char *to;
|
||||
if (!res || tmp_value.alloc(res->length()*2))
|
||||
res= args[0]->val_str(str);
|
||||
if (!res || tmp_value.alloc(res->length()*2+1))
|
||||
{
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
null_value=0;
|
||||
tmp_value.length(res->length()*2);
|
||||
for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr();
|
||||
from < end ;
|
||||
from++, to+=2)
|
||||
{
|
||||
uint tmp=(uint) (uchar) *from;
|
||||
to[0]=_dig_vec_upper[tmp >> 4];
|
||||
to[1]=_dig_vec_upper[tmp & 15];
|
||||
}
|
||||
|
||||
octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
|
||||
return &tmp_value;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ public:
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
collation.set(default_charset());
|
||||
collation.set(&my_charset_bin);
|
||||
maybe_null=0; max_length=arg_count;
|
||||
}
|
||||
const char *func_name() const { return "char"; }
|
||||
|
@ -212,24 +212,18 @@ static inline int read_str(char **buf, char *buf_end, char **str,
|
||||
/*
|
||||
Transforms a string into "" or its expression in 0x... form.
|
||||
*/
|
||||
|
||||
char *str_to_hex(char *to, const char *from, uint len)
|
||||
{
|
||||
char *p= to;
|
||||
if (len)
|
||||
{
|
||||
p= strmov(p, "0x");
|
||||
for (uint i= 0; i < len; i++, p+= 2)
|
||||
{
|
||||
/* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */
|
||||
uint tmp= (uint) (uchar) from[i];
|
||||
p[0]= _dig_vec_upper[tmp >> 4];
|
||||
p[1]= _dig_vec_upper[tmp & 15];
|
||||
}
|
||||
*p= 0;
|
||||
*to++= '0';
|
||||
*to++= 'x';
|
||||
to= octet2hex(to, from, len);
|
||||
}
|
||||
else
|
||||
p= strmov(p, "\"\"");
|
||||
return p; // pointer to end 0 of 'to'
|
||||
to= strmov(to, "\"\"");
|
||||
return to; // pointer to end 0 of 'to'
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -372,8 +372,10 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
||||
|
||||
if (revision > 0 && !access(arc_path, F_OK))
|
||||
{
|
||||
ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0;
|
||||
while (revision > limit) {
|
||||
ulonglong limit= ((revision > num_view_backups) ?
|
||||
revision - num_view_backups : 0);
|
||||
for (; revision > limit ; revision--)
|
||||
{
|
||||
my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
|
||||
arc_path, old_name, reg_ext, (ulong)revision);
|
||||
(void) unpack_filename(old_path, old_path);
|
||||
@ -381,7 +383,6 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
||||
arc_path, new_name, reg_ext, (ulong)revision);
|
||||
(void) unpack_filename(new_path, new_path);
|
||||
my_rename(old_path, new_path, MYF(0));
|
||||
revision--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -316,18 +316,21 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st)
|
||||
octet2hex()
|
||||
buf OUT output buffer. Must be at least 2*len+1 bytes
|
||||
str, len IN the beginning and the length of the input string
|
||||
|
||||
RETURN
|
||||
buf+len*2
|
||||
*/
|
||||
|
||||
void
|
||||
octet2hex(char *to, const unsigned char *str, uint len)
|
||||
char *octet2hex(char *to, const char *str, uint len)
|
||||
{
|
||||
const uint8 *str_end= str + len;
|
||||
const byte *str_end= str + len;
|
||||
for (; str != str_end; ++str)
|
||||
{
|
||||
*to++= _dig_vec_upper[(*str & 0xF0) >> 4];
|
||||
*to++= _dig_vec_upper[*str & 0x0F];
|
||||
*to++= _dig_vec_upper[((uchar) *str) >> 4];
|
||||
*to++= _dig_vec_upper[((uchar) *str) & 0x0F];
|
||||
}
|
||||
*to= '\0';
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2747,7 +2747,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
|
||||
else
|
||||
pthread_cond_wait(&data_cond, &data_lock);
|
||||
DBUG_PRINT("info",("Got signal of master update or timed out"));
|
||||
if (error == ETIMEDOUT)
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
error= -1;
|
||||
break;
|
||||
|
@ -2784,7 +2784,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
Natural_join_column *nj_col;
|
||||
Field *found_field;
|
||||
Query_arena *arena, backup;
|
||||
|
||||
DBUG_ENTER("find_field_in_natural_join");
|
||||
DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx",
|
||||
name, (ulong) ref));
|
||||
@ -2809,6 +2808,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
|
||||
if (nj_col->view_field)
|
||||
{
|
||||
Item *item;
|
||||
/*
|
||||
The found field is a view field, we do as in find_field_in_view()
|
||||
and return a pointer to pointer to the Item of that field.
|
||||
@ -2816,7 +2816,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
if (register_tree_change)
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
|
||||
Item *item= nj_col->create_item(thd);
|
||||
item= nj_col->create_item(thd);
|
||||
|
||||
if (register_tree_change && arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
|
@ -1809,7 +1809,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
|
||||
#endif
|
||||
if (thd->killed || di->status)
|
||||
break;
|
||||
if (error == ETIMEDOUT)
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
thd->killed= THD::KILL_CONNECTION;
|
||||
break;
|
||||
|
@ -58,12 +58,14 @@ extern "C" pthread_handler_decl(handle_manager,arg __attribute__((unused)))
|
||||
set_timespec(abstime, flush_time);
|
||||
reset_flush_time = FALSE;
|
||||
}
|
||||
while (!manager_status && !error && !abort_loop)
|
||||
error = pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
|
||||
while (!manager_status && (!error || error == EINTR) && !abort_loop)
|
||||
error= pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
|
||||
}
|
||||
else
|
||||
while (!manager_status && !error && !abort_loop)
|
||||
error = pthread_cond_wait(&COND_manager, &LOCK_manager);
|
||||
{
|
||||
while (!manager_status && (!error || error == EINTR) && !abort_loop)
|
||||
error= pthread_cond_wait(&COND_manager, &LOCK_manager);
|
||||
}
|
||||
status = manager_status;
|
||||
manager_status = 0;
|
||||
pthread_mutex_unlock(&LOCK_manager);
|
||||
@ -71,7 +73,7 @@ extern "C" pthread_handler_decl(handle_manager,arg __attribute__((unused)))
|
||||
if (abort_loop)
|
||||
break;
|
||||
|
||||
if (error) /* == ETIMEDOUT */
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
flush_tables();
|
||||
error = 0;
|
||||
|
@ -5054,11 +5054,16 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
|
||||
tables->db= db;
|
||||
tables->table_name= tables->alias= name;
|
||||
|
||||
if ((thd->security_ctx->master_access & want_access) == want_access &&
|
||||
!thd->db)
|
||||
/*
|
||||
The following test is just a shortcut for check_access() (to avoid
|
||||
calculating db_access) under the assumption that it's common to
|
||||
give persons global right to execute all stored SP (but not
|
||||
necessary to create them).
|
||||
*/
|
||||
if ((thd->security_ctx->master_access & want_access) == want_access)
|
||||
tables->grant.privilege= want_access;
|
||||
else if (check_access(thd,want_access,db,&tables->grant.privilege,
|
||||
0, no_errors, test(tables->schema_table)))
|
||||
0, no_errors, 0))
|
||||
return TRUE;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
@ -2887,7 +2887,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
||||
thd->protocol= &thd->protocol_simple; /* use normal protocol */
|
||||
|
||||
/* Assert that if an error, no cursor is open */
|
||||
DBUG_ASSERT(! (rc && cursor));
|
||||
DBUG_ASSERT(! (error && cursor));
|
||||
|
||||
if (! cursor)
|
||||
{
|
||||
|
@ -2474,11 +2474,11 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
and use them in equality propagation process (see details in
|
||||
OptimizerKBAndTodo)
|
||||
*/
|
||||
if ((cond->functype() == Item_func::BETWEEN) &&
|
||||
value[0]->eq(value[1], field->binary()))
|
||||
eq_func= TRUE;
|
||||
else
|
||||
if ((cond->functype() != Item_func::BETWEEN) ||
|
||||
((Item_func_between*) cond)->negated ||
|
||||
!value[0]->eq(value[1], field->binary()))
|
||||
return;
|
||||
eq_func= TRUE;
|
||||
}
|
||||
|
||||
if (field->result_type() == STRING_RESULT)
|
||||
|
@ -1258,9 +1258,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
||||
thread_info *thd_info;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *sctx;
|
||||
#endif
|
||||
time_t now= time(0);
|
||||
while ((thd_info=thread_infos.get()))
|
||||
{
|
||||
|
@ -3156,15 +3156,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (create_info->row_type == ROW_TYPE_NOT_USED)
|
||||
create_info->row_type= table->s->row_type;
|
||||
|
||||
DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
|
||||
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)
|
||||
|| ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||
DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
|
||||
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
|
||||
ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||
{
|
||||
DBUG_PRINT("info", ("doesn't support alter"));
|
||||
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_PRINT("info", ("supports alter"));
|
||||
|
||||
thd->proc_info="setup";
|
||||
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
|
||||
|
@ -1427,7 +1427,7 @@ mysql_rename_view(THD *thd,
|
||||
|
||||
/* get view definition and source */
|
||||
if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters,
|
||||
sizeof(view_parameters)/sizeof(view_parameters[0])-1))
|
||||
array_elements(view_parameters)-1))
|
||||
goto err;
|
||||
|
||||
/* rename view and it's backups */
|
||||
|
@ -474,16 +474,10 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
|
||||
char *dst;
|
||||
uint length= field->interval->type_lengths[pos], hex_length;
|
||||
const char *src= field->interval->type_names[pos];
|
||||
const char *srcend= src + length;
|
||||
hex_length= length * 2;
|
||||
field->interval->type_lengths[pos]= hex_length;
|
||||
field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1);
|
||||
for ( ; src < srcend; src++)
|
||||
{
|
||||
*dst++= _dig_vec_upper[((uchar) *src) >> 4];
|
||||
*dst++= _dig_vec_upper[((uchar) *src) & 15];
|
||||
}
|
||||
*dst= '\0';
|
||||
octet2hex(dst, src, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user