Merge trift2.:/MySQL/M51/mysql-5.1

into  trift2.:/MySQL/M51/push-5.1
This commit is contained in:
joerg@trift2. 2007-10-22 11:18:01 +02:00
commit 242fdacdfe
78 changed files with 3738 additions and 908 deletions

View file

@ -545,13 +545,13 @@ static int process_all_tables_in_db(char *database)
static int fix_object_name(const char *obj, const char *name)
static int fix_table_storage_name(const char *name)
{
char qbuf[100 + NAME_LEN*4];
int rc= 0;
if (strncmp(name, "#mysql50#", 9))
return 1;
sprintf(qbuf, "RENAME %s `%s` TO `%s`", obj, name, name + 9);
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
if (mysql_query(sock, qbuf))
{
fprintf(stderr, "Failed to %s\n", qbuf);
@ -563,6 +563,23 @@ static int fix_object_name(const char *obj, const char *name)
return rc;
}
static int fix_database_storage_name(const char *name)
{
char qbuf[100 + NAME_LEN*4];
int rc= 0;
if (strncmp(name, "#mysql50#", 9))
return 1;
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
if (mysql_query(sock, qbuf))
{
fprintf(stderr, "Failed to %s\n", qbuf);
fprintf(stderr, "Error: %s\n", mysql_error(sock));
rc= 1;
}
if (verbose)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
return rc;
}
static int process_one_db(char *database)
{
@ -571,7 +588,7 @@ static int process_one_db(char *database)
int rc= 0;
if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
{
rc= fix_object_name("DATABASE", database);
rc= fix_database_storage_name(database);
database+= 9;
}
if (rc || !opt_fix_table_names)
@ -626,7 +643,7 @@ static int handle_request_for_tables(char *tables, uint length)
op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
break;
case DO_UPGRADE:
return fix_object_name("TABLE", tables);
return fix_table_storage_name(tables);
}
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))

View file

@ -263,7 +263,7 @@ enum enum_commands {
Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
Q_SEND_QUIT,
Q_SEND_QUIT, Q_CHANGE_USER,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
@ -352,6 +352,7 @@ const char *command_names[]=
"cat_file",
"diff_files",
"send_quit",
"change_user",
0
};
@ -1507,7 +1508,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
die("Failed to create temporary file for ds");
/* Write ds to temporary file and set file pos to beginning*/
if (my_write(fd, ds->str, ds->length,
if (my_write(fd, (uchar *) ds->str, ds->length,
MYF(MY_FNABP | MY_WME)) ||
my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
{
@ -1998,7 +1999,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
const struct command_arg query_get_value_args[] = {
"query", ARG_STRING, TRUE, &ds_query, "Query to run",
"column name", ARG_STRING, TRUE, &ds_col, "Name of column",
"row number", ARG_STRING, TRUE, &ds_row, "Number for row",
"row number", ARG_STRING, TRUE, &ds_row, "Number for row"
};
DBUG_ENTER("var_set_query_get_value");
@ -3040,6 +3041,69 @@ void do_send_quit(struct st_command *command)
}
/*
SYNOPSIS
do_change_user
command called command
DESCRIPTION
change_user [<user>], [<passwd>], [<db>]
<user> - user to change to
<passwd> - user password
<db> - default database
Changes the user and causes the database specified by db to become
the default (current) database for the the current connection.
*/
void do_change_user(struct st_command *command)
{
MYSQL *mysql = &cur_con->mysql;
/* static keyword to make the NetWare compiler happy. */
static DYNAMIC_STRING ds_user, ds_passwd, ds_db;
const struct command_arg change_user_args[] = {
{ "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
{ "password", ARG_STRING, FALSE, &ds_passwd, "Password used when connecting" },
{ "database", ARG_STRING, FALSE, &ds_db, "Database to select after connect" },
};
DBUG_ENTER("do_change_user");
check_command_args(command, command->first_argument,
change_user_args,
sizeof(change_user_args)/sizeof(struct command_arg),
',');
if (cur_con->stmt)
{
mysql_stmt_close(cur_con->stmt);
cur_con->stmt= NULL;
}
if (!ds_user.length)
dynstr_set(&ds_user, mysql->user);
if (!ds_passwd.length)
dynstr_set(&ds_passwd, mysql->passwd);
if (!ds_db.length)
dynstr_set(&ds_db, mysql->db);
DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'",
cur_con->name, ds_user.str, ds_passwd.str, ds_db.str));
if (mysql_change_user(mysql, ds_user.str, ds_passwd.str, ds_db.str))
die("change user failed: %s", mysql_error(mysql));
dynstr_free(&ds_user);
dynstr_free(&ds_passwd);
dynstr_free(&ds_db);
DBUG_VOID_RETURN;
}
/*
SYNOPSIS
do_perl
@ -6854,6 +6918,7 @@ int main(int argc, char **argv)
case Q_APPEND_FILE: do_append_file(command); break;
case Q_DIFF_FILES: do_diff_files(command); break;
case Q_SEND_QUIT: do_send_quit(command); break;
case Q_CHANGE_USER: do_change_user(command); break;
case Q_CAT_FILE: do_cat_file(command); break;
case Q_COPY_FILE: do_copy_file(command); break;
case Q_CHMOD_FILE: do_chmod_file(command); break;

View file

@ -21,6 +21,9 @@
/* We have to do this define before including windows.h to get the AWE API
functions */
#define _WIN32_WINNT 0x0500
#else
/* Get NT 4.0 functions */
#define _WIN32_WINNT 0x0400
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400

View file

@ -101,6 +101,7 @@ struct timespec {
void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length);
int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
@ -156,7 +157,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#define pthread_equal(A,B) ((A) == (B))
#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
@ -472,7 +473,7 @@ typedef struct st_safe_mutex_info_t
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
const char *file, uint line);
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
@ -495,12 +496,12 @@ void safe_mutex_end(FILE *file);
#undef pthread_cond_timedwait
#undef pthread_mutex_trylock
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__)
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
#define pthread_mutex_trylock(A) pthread_mutex_lock(A)
#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__)
#define pthread_mutex_t safe_mutex_t
#define safe_mutex_assert_owner(mp) \
DBUG_ASSERT((mp)->count > 0 && \

View file

@ -203,7 +203,7 @@ typedef struct st_net {
unsigned char reading_or_writing;
char save_char;
my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
my_bool no_send_eof; /* For SPs' first version read-only cursors */
my_bool unused; /* Please remove with the next incompatible ABI change */
my_bool compress;
/*
Set if OK packet is already sent, and we do not need to send error

View file

@ -538,7 +538,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned
unsigned char reading_or_writing;
char save_char;
my_bool no_send_ok;
my_bool no_send_eof;
my_bool unused;
my_bool compress;
my_bool no_send_error;
unsigned char * query_cache_query;

View file

@ -63,3 +63,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
int init_embedded_server(int argc, char **argv, char **groups);
void end_embedded_server();
#endif /*EMBEDDED_LIBRARY*/
C_MODE_START
extern int mysql_init_character_set(MYSQL *mysql);
C_MODE_END

View file

@ -698,14 +698,25 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
return 0;
}
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db)
{
char buff[512],*end=buff;
int rc;
CHARSET_INFO *saved_cs= mysql->charset;
DBUG_ENTER("mysql_change_user");
/* Get the connection-default character set. */
if (mysql_init_character_set(mysql))
{
mysql->charset= saved_cs;
DBUG_RETURN(TRUE);
}
/* Use an empty string instead of NULL. */
if (!user)
user="";
if (!passwd)
@ -734,6 +745,14 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/* Add database if needed */
end= strmov(end, db ? db : "") + 1;
/* Add character set number. */
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
{
int2store(end, (ushort) mysql->charset->number);
end+= 2;
}
/* Write authentication package */
simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
@ -756,6 +775,11 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
}
else
{
mysql->charset= saved_cs;
}
DBUG_RETURN(rc);
}
@ -2515,7 +2539,7 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
5 /* execution flags */];
my_bool res;
DBUG_ENTER("execute");
DBUG_DUMP("packet", packet, length);
DBUG_DUMP("packet", (uchar *) packet, length);
mysql->last_used_con= mysql;
int4store(buff, stmt->stmt_id); /* Send stmt id to server */

View file

@ -111,7 +111,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
}
thd->net.no_send_error= 0;
result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
result= dispatch_command(command, thd, (char *) arg, arg_length);
thd->cur_data= 0;
if (!skip_check)

View file

@ -498,3 +498,71 @@ handler t1_alias read a next;
handler t1_alias READ a next where inexistent > 0;
handler t1_alias close;
drop table t1;
#
# Bug#21587 FLUSH TABLES causes server crash when used with HANDLER statements
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
--echo connection: default
handler t1 open;
handler t1 read first;
connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
--send flush tables;
connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Flushing tables";
--source include/wait_condition.inc
handler t2 open;
handler t2 read first;
handler t1 read next;
handler t1 close;
handler t2 close;
connection flush;
reap;
connection default;
drop table t1,t2;
disconnect flush;
#
# Bug#31409 RENAME TABLE causes server crash or deadlock when used with HANDLER statements
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (c1 int);
--echo connection: default
handler t1 open;
handler t1 read first;
connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
--send rename table t1 to t2;
connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table" and info = "rename table t1 to t2";
--source include/wait_condition.inc
handler t2 open;
handler t2 read first;
--error ER_NO_SUCH_TABLE
handler t1 read next;
handler t1 close;
handler t2 close;
connection flush;
reap;
connection default;
drop table t2;
disconnect flush;

View file

@ -1146,4 +1146,38 @@ select @b:=f2 from t1;
select if(@a=@b,"ok","wrong");
drop table t1;
#
# Bug#30747 Create table with identical constraint names behaves incorrectly
#
if ($test_foreign_keys)
{
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb;
--error ER_WRONG_FK_DEF
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
--error ER_WRONG_FK_DEF
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
ALTER TABLE t2 DROP FOREIGN KEY c2;
DROP TABLE t2;
--error ER_WRONG_FK_DEF
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
--error ER_WRONG_FK_DEF
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
FOREIGN KEY f3 (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
}
--echo End of 5.1 tests

View file

@ -0,0 +1,46 @@
Bug#20023
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
1
SELECT @@global.max_join_size;
@@global.max_join_size
-1
change_user
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
1
SELECT @@global.max_join_size;
@@global.max_join_size
-1
SET @@global.max_join_size = 10000;
SET @@session.max_join_size = default;
change_user
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
0
SET @@global.max_join_size = -1;
SET @@session.max_join_size = default;
change_user
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
1
Bug#31418
SELECT IS_FREE_LOCK('bug31418');
IS_FREE_LOCK('bug31418')
1
SELECT IS_USED_LOCK('bug31418');
IS_USED_LOCK('bug31418')
NULL
SELECT GET_LOCK('bug31418', 1);
GET_LOCK('bug31418', 1)
1
SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID();
IS_USED_LOCK('bug31418') = CONNECTION_ID()
1
change_user
SELECT IS_FREE_LOCK('bug31418');
IS_FREE_LOCK('bug31418')
1
SELECT IS_USED_LOCK('bug31418');
IS_USED_LOCK('bug31418')
NULL

View file

@ -1588,14 +1588,6 @@ CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
ERROR 42000: Unknown database 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
create database mysqltest;
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
drop database mysqltest;
USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
@ -1699,4 +1691,18 @@ ERROR 42000: Identifier name 'очень_очень_очень_очень_оче
drop view имя_вью_кодировке_утф8_длиной_большеем_42;
drop table имя_таблицы_в_кодировке_утф8_длиной_большеем_48;
set names default;
drop table if exists t1,t2,t3;
drop function if exists f1;
create function f1() returns int
begin
declare res int;
create temporary table t3 select 1 i;
set res:= (select count(*) from t1);
drop temporary table t3;
return res;
end|
create table t1 as select 1;
create table t2 as select f1() from t1;
drop table t1,t2;
drop function f1;
End of 5.1 tests

View file

@ -255,3 +255,32 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNION=(t1);
INSERT DELAYED INTO t2 VALUES(1);
ERROR HY000: Table storage engine for 't2' doesn't have this option
DROP TABLE t1, t2;
DROP TABLE IF EXISTS t1,t2;
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE `t1` (
`id` int(11) PRIMARY KEY auto_increment,
`f1` varchar(10) NOT NULL UNIQUE
);
INSERT DELAYED INTO t1 VALUES(0,"test1");
SELECT * FROM t1;
id f1
0 test1
SET SQL_MODE='PIPES_AS_CONCAT';
INSERT DELAYED INTO t1 VALUES(0,'a' || 'b');
SELECT * FROM t1;
id f1
0 test1
1 ab
SET SQL_MODE='ERROR_FOR_DIVISION_BY_ZERO,STRICT_ALL_TABLES';
INSERT DELAYED INTO t1 VALUES(mod(1,0),"test3");
ERROR 22012: Division by 0
CREATE TABLE t2 (
`id` int(11) PRIMARY KEY auto_increment,
`f1` date
);
SET SQL_MODE='NO_ZERO_DATE,STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
ERROR 22007: Incorrect date value: '0000-00-00' for column 'f1' at row 1
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
ERROR 22007: Incorrect date value: '2007-00-00' for column 'f1' at row 1
DROP TABLE t1,t2;

View file

@ -535,3 +535,43 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
drop table if exists t1,t2;
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
connection: default
handler t1 open;
handler t1 read first;
c1
1
connection: flush
flush tables;;
connection: default
handler t2 open;
handler t2 read first;
c1
2
handler t1 read next;
c1
1
handler t1 close;
handler t2 close;
drop table t1,t2;
drop table if exists t1,t2;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
rename table t1 to t2;;
connection: default
handler t2 open;
handler t2 read first;
c1
handler t1 read next;
ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close;
handler t2 close;
drop table t2;

View file

@ -535,3 +535,43 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
drop table if exists t1,t2;
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
connection: default
handler t1 open;
handler t1 read first;
c1
1
connection: flush
flush tables;;
connection: default
handler t2 open;
handler t2 read first;
c1
2
handler t1 read next;
c1
1
handler t1 close;
handler t2 close;
drop table t1,t2;
drop table if exists t1,t2;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
rename table t1 to t2;;
connection: default
handler t2 open;
handler t2 read first;
c1
handler t1 read next;
ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close;
handler t2 close;
drop table t2;

View file

@ -578,7 +578,7 @@ proc sql_data_access enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL
proc is_deterministic enum('YES','NO')
proc security_type enum('INVOKER','DEFINER')
proc param_list blob
proc returns char(64)
proc returns longblob
proc body longblob
proc definer char(77)
proc created timestamp

View file

@ -1419,4 +1419,40 @@ select if(@a=@b,"ok","wrong");
if(@a=@b,"ok","wrong")
ok
drop table t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb;
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
ERROR 42000: Incorrect foreign key definition for 'f2': Key reference and table reference don't match
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
ERROR 42000: Incorrect foreign key definition for 'c2': Key reference and table reference don't match
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
ALTER TABLE t2 DROP FOREIGN KEY c2;
DROP TABLE t2;
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
ERROR 42000: Incorrect foreign key definition for 'f1': Key reference and table reference don't match
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
FOREIGN KEY f3 (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`c` int(11) NOT NULL,
`d` int(11) NOT NULL,
PRIMARY KEY (`c`,`d`),
CONSTRAINT `c1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON DELETE NO ACTION,
CONSTRAINT `c2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION,
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION,
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
End of 5.1 tests

View file

@ -270,6 +270,10 @@ use mysql;
lock tables general_log read local, help_category read local;
ERROR HY000: You can't use locks with log tables.
unlock tables;
drop table if exists mysql.renamed_general_log;
drop table if exists mysql.renamed_slow_log;
drop table if exists mysql.general_log_new;
drop table if exists mysql.slow_log_new;
use mysql;
RENAME TABLE general_log TO renamed_general_log;
ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log'
@ -601,3 +605,218 @@ DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
DROP DATABASE IF EXISTS `db_17876`;
SET GLOBAL general_log = @old_general_log_state;
SET GLOBAL slow_query_log = @old_slow_log_state;
truncate table mysql.general_log;
set @old_general_log_state = @@global.general_log;
set global general_log = on;
set @lparam = "000 001 002 003 004 005 006 007 008 009"
"010 011 012 013 014 015 016 017 018 019"
"020 021 022 023 024 025 026 027 028 029"
"030 031 032 033 034 035 036 037 038 039"
"040 041 042 043 044 045 046 047 048 049"
"050 051 052 053 054 055 056 057 058 059"
"060 061 062 063 064 065 066 067 068 069"
"070 071 072 073 074 075 076 077 078 079"
"080 081 082 083 084 085 086 087 088 089"
"090 091 092 093 094 095 096 097 098 099"
"100 101 102 103 104 105 106 107 108 109"
"110 111 112 113 114 115 116 117 118 119"
"120 121 122 123 124 125 126 127 128 129"
"130 131 132 133 134 135 136 137 138 139"
"140 141 142 143 144 145 146 147 148 149"
"150 151 152 153 154 155 156 157 158 159"
"160 161 162 163 164 165 166 167 168 169"
"170 171 172 173 174 175 176 177 178 179"
"180 181 182 183 184 185 186 187 188 189"
"190 191 192 193 194 195 196 197 198 199"
"200 201 202 203 204 205 206 207 208 209"
"210 211 212 213 214 215 216 217 218 219"
"220 221 222 223 224 225 226 227 228 229"
"230 231 232 233 234 235 236 237 238 239"
"240 241 242 243 244 245 246 247 248 249"
"250 251 252 253 254 255 256 257 258 259"
"260 261 262 263 264 265 266 267 268 269"
"270 271 272 273 274 275 276 277 278 279"
"280 281 282 283 284 285 286 287 288 289"
"290 291 292 293 294 295 296 297 298 299"
"300 301 302 303 304 305 306 307 308 309"
"310 311 312 313 314 315 316 317 318 319"
"320 321 322 323 324 325 326 327 328 329"
"330 331 332 333 334 335 336 337 338 339"
"340 341 342 343 344 345 346 347 348 349"
"350 351 352 353 354 355 356 357 358 359"
"360 361 362 363 364 365 366 367 368 369"
"370 371 372 373 374 375 376 377 378 379"
"380 381 382 383 384 385 386 387 388 389"
"390 391 392 393 394 395 396 397 398 399"
"400 401 402 403 404 405 406 407 408 409"
"410 411 412 413 414 415 416 417 418 419"
"420 421 422 423 424 425 426 427 428 429"
"430 431 432 433 434 435 436 437 438 439"
"440 441 442 443 444 445 446 447 448 449"
"450 451 452 453 454 455 456 457 458 459"
"460 461 462 463 464 465 466 467 468 469"
"470 471 472 473 474 475 476 477 478 479"
"480 481 482 483 484 485 486 487 488 489"
"490 491 492 493 494 495 496 497 498 499"
"500 501 502 503 504 505 506 507 508 509"
"510 511 512 513 514 515 516 517 518 519"
"520 521 522 523 524 525 526 527 528 529"
"530 531 532 533 534 535 536 537 538 539"
"540 541 542 543 544 545 546 547 548 549"
"550 551 552 553 554 555 556 557 558 559"
"560 561 562 563 564 565 566 567 568 569"
"570 571 572 573 574 575 576 577 578 579"
"580 581 582 583 584 585 586 587 588 589"
"590 591 592 593 594 595 596 597 598 599"
"600 601 602 603 604 605 606 607 608 609"
"610 611 612 613 614 615 616 617 618 619"
"620 621 622 623 624 625 626 627 628 629"
"630 631 632 633 634 635 636 637 638 639"
"640 641 642 643 644 645 646 647 648 649"
"650 651 652 653 654 655 656 657 658 659"
"660 661 662 663 664 665 666 667 668 669"
"670 671 672 673 674 675 676 677 678 679"
"680 681 682 683 684 685 686 687 688 689"
"690 691 692 693 694 695 696 697 698 699"
"700 701 702 703 704 705 706 707 708 709"
"710 711 712 713 714 715 716 717 718 719"
"720 721 722 723 724 725 726 727 728 729"
"730 731 732 733 734 735 736 737 738 739"
"740 741 742 743 744 745 746 747 748 749"
"750 751 752 753 754 755 756 757 758 759"
"760 761 762 763 764 765 766 767 768 769"
"770 771 772 773 774 775 776 777 778 779"
"780 781 782 783 784 785 786 787 788 789"
"790 791 792 793 794 795 796 797 798 799"
"800 801 802 803 804 805 806 807 808 809"
"810 811 812 813 814 815 816 817 818 819"
"820 821 822 823 824 825 826 827 828 829"
"830 831 832 833 834 835 836 837 838 839"
"840 841 842 843 844 845 846 847 848 849"
"850 851 852 853 854 855 856 857 858 859"
"860 861 862 863 864 865 866 867 868 869"
"870 871 872 873 874 875 876 877 878 879"
"880 881 882 883 884 885 886 887 888 889"
"890 891 892 893 894 895 896 897 898 899"
"900 901 902 903 904 905 906 907 908 909"
"910 911 912 913 914 915 916 917 918 919"
"920 921 922 923 924 925 926 927 928 929"
"930 931 932 933 934 935 936 937 938 939"
"940 941 942 943 944 945 946 947 948 949"
"950 951 952 953 954 955 956 957 958 959"
"960 961 962 963 964 965 966 967 968 969"
"970 971 972 973 974 975 976 977 978 979"
"980 981 982 983 984 985 986 987 988 989"
"990 991 992 993 994 995 996 997 998 999";
prepare long_query from "select ? as long_query";
execute long_query using @lparam;
set global general_log = off;
select command_type, argument from mysql.general_log;
command_type argument
Query set @lparam = "000 001 002 003 004 005 006 007 008 009"
"010 011 012 013 014 015 016 017 018 019"
"020 021 022 023 024 025 026 027 028 029"
"030 031 032 033 034 035 036 037 038 039"
"040 041 042 043 044 045 046 047 048 049"
"050 051 052 053 054 055 056 057 058 059"
"060 061 062 063 064 065 066 067 068 069"
"070 071 072 073 074 075 076 077 078 079"
"080 081 082 083 084 085 086 087 088 089"
"090 091 092 093 094 095 096 097 098 099"
"100 101 102 103 104 105 106 107 108 109"
"110 111 112 113 114 115 116 117 118 119"
"120 121 122 123 124 125 126 127 128 129"
"130 131 132 133 134 135 136 137 138 139"
"140 141 142 143 144 145 146 147 148 149"
"150 151 152 153 154 155 156 157 158 159"
"160 161 162 163 164 165 166 167 168 169"
"170 171 172 173 174 175 176 177 178 179"
"180 181 182 183 184 185 186 187 188 189"
"190 191 192 193 194 195 196 197 198 199"
"200 201 202 203 204 205 206 207 208 209"
"210 211 212 213 214 215 216 217 218 219"
"220 221 222 223 224 225 226 227 228 229"
"230 231 232 233 234 235 236 237 238 239"
"240 241 242 243 244 245 246 247 248 249"
"250 251 252 253 254 255 256 257 258 259"
"260 261 262 263 264 265 266 267 268 269"
"270 271 272 273 274 275 276 277 278 279"
"280 281 282 283 284 285 286 287 288 289"
"290 291 292 293 294 295 296 297 298 299"
"300 301 302 303 304 305 306 307 308 309"
"310 311 312 313 314 315 316 317 318 319"
"320 321 322 323 324 325 326 327 328 329"
"330 331 332 333 334 335 336 337 338 339"
"340 341 342 343 344 345 346 347 348 349"
"350 351 352 353 354 355 356 357 358 359"
"360 361 362 363 364 365 366 367 368 369"
"370 371 372 373 374 375 376 377 378 379"
"380 381 382 383 384 385 386 387 388 389"
"390 391 392 393 394 395 396 397 398 399"
"400 401 402 403 404 405 406 407 408 409"
"410 411 412 413 414 415 416 417 418 419"
"420 421 422 423 424 425 426 427 428 429"
"430 431 432 433 434 435 436 437 438 439"
"440 441 442 443 444 445 446 447 448 449"
"450 451 452 453 454 455 456 457 458 459"
"460 461 462 463 464 465 466 467 468 469"
"470 471 472 473 474 475 476 477 478 479"
"480 481 482 483 484 485 486 487 488 489"
"490 491 492 493 494 495 496 497 498 499"
"500 501 502 503 504 505 506 507 508 509"
"510 511 512 513 514 515 516 517 518 519"
"520 521 522 523 524 525 526 527 528 529"
"530 531 532 533 534 535 536 537 538 539"
"540 541 542 543 544 545 546 547 548 549"
"550 551 552 553 554 555 556 557 558 559"
"560 561 562 563 564 565 566 567 568 569"
"570 571 572 573 574 575 576 577 578 579"
"580 581 582 583 584 585 586 587 588 589"
"590 591 592 593 594 595 596 597 598 599"
"600 601 602 603 604 605 606 607 608 609"
"610 611 612 613 614 615 616 617 618 619"
"620 621 622 623 624 625 626 627 628 629"
"630 631 632 633 634 635 636 637 638 639"
"640 641 642 643 644 645 646 647 648 649"
"650 651 652 653 654 655 656 657 658 659"
"660 661 662 663 664 665 666 667 668 669"
"670 671 672 673 674 675 676 677 678 679"
"680 681 682 683 684 685 686 687 688 689"
"690 691 692 693 694 695 696 697 698 699"
"700 701 702 703 704 705 706 707 708 709"
"710 711 712 713 714 715 716 717 718 719"
"720 721 722 723 724 725 726 727 728 729"
"730 731 732 733 734 735 736 737 738 739"
"740 741 742 743 744 745 746 747 748 749"
"750 751 752 753 754 755 756 757 758 759"
"760 761 762 763 764 765 766 767 768 769"
"770 771 772 773 774 775 776 777 778 779"
"780 781 782 783 784 785 786 787 788 789"
"790 791 792 793 794 795 796 797 798 799"
"800 801 802 803 804 805 806 807 808 809"
"810 811 812 813 814 815 816 817 818 819"
"820 821 822 823 824 825 826 827 828 829"
"830 831 832 833 834 835 836 837 838 839"
"840 841 842 843 844 845 846 847 848 849"
"850 851 852 853 854 855 856 857 858 859"
"860 861 862 863 864 865 866 867 868 869"
"870 871 872 873 874 875 876 877 878 879"
"880 881 882 883 884 885 886 887 888 889"
"890 891 892 893 894 895 896 897 898 899"
"900 901 902 903 904 905 906 907 908 909"
"910 911 912 913 914 915 916 917 918 919"
"920 921 922 923 924 925 926 927 928 929"
"930 931 932 933 934 935 936 937 938 939"
"940 941 942 943 944 945 946 947 948 949"
"950 951 952 953 954 955 956 957 958 959"
"960 961 962 963 964 965 966 967 968 969"
"970 971 972 973 974 975 976 977 978 979"
"980 981 982 983 984 985 986 987 988 989"
"990 991 992 993 994 995 996 997 998 999"
Query prepare long_query from "select ? as long_query"
Prepare select ? as long_query
Query execute long_query using @lparam
Execute select '000 001 002 003 004 005 006 007 008 009010 011 012 013 014 015 016 017 018 019020 021 022 023 024 025 026 027 028 029030 031 032 033 034 035 036 037 038 039040 041 042 043 044 045 046 047 048 049050 051 052 053 054 055 056 057 058 059060 061 062 063 064 065 066 067 068 069070 071 072 073 074 075 076 077 078 079080 081 082 083 084 085 086 087 088 089090 091 092 093 094 095 096 097 098 099100 101 102 103 104 105 106 107 108 109110 111 112 113 114 115 116 117 118 119120 121 122 123 124 125 126 127 128 129130 131 132 133 134 135 136 137 138 139140 141 142 143 144 145 146 147 148 149150 151 152 153 154 155 156 157 158 159160 161 162 163 164 165 166 167 168 169170 171 172 173 174 175 176 177 178 179180 181 182 183 184 185 186 187 188 189190 191 192 193 194 195 196 197 198 199200 201 202 203 204 205 206 207 208 209210 211 212 213 214 215 216 217 218 219220 221 222 223 224 225 226 227 228 229230 231 232 233 234 235 236 237 238 239240 241 242 243 244 245 246 247 248 249250 251 252 253 254 255 256 257 258 259260 261 262 263 264 265 266 267 268 269270 271 272 273 274 275 276 277 278 279280 281 282 283 284 285 286 287 288 289290 291 292 293 294 295 296 297 298 299300 301 302 303 304 305 306 307 308 309310 311 312 313 314 315 316 317 318 319320 321 322 323 324 325 326 327 328 329330 331 332 333 334 335 336 337 338 339340 341 342 343 344 345 346 347 348 349350 351 352 353 354 355 356 357 358 359360 361 362 363 364 365 366 367 368 369370 371 372 373 374 375 376 377 378 379380 381 382 383 384 385 386 387 388 389390 391 392 393 394 395 396 397 398 399400 401 402 403 404 405 406 407 408 409410 411 412 413 414 415 416 417 418 419420 421 422 423 424 425 426 427 428 429430 431 432 433 434 435 436 437 438 439440 441 442 443 444 445 446 447 448 449450 451 452 453 454 455 456 457 458 459460 461 462 463 464 465 466 467 468 469470 471 472 473 474 475 476 477 478 479480 481 482 483 484 485 486 487 488 489490 491 492 493 494 495 496 497 498 499500 501 502 503 504 505 506 507 508 509510 511 512 513 514 515 516 517 518 519520 521 522 523 524 525 526 527 528 529530 531 532 533 534 535 536 537 538 539540 541 542 543 544 545 546 547 548 549550 551 552 553 554 555 556 557 558 559560 561 562 563 564 565 566 567 568 569570 571 572 573 574 575 576 577 578 579580 581 582 583 584 585 586 587 588 589590 591 592 593 594 595 596 597 598 599600 601 602 603 604 605 606 607 608 609610 611 612 613 614 615 616 617 618 619620 621 622 623 624 625 626 627 628 629630 631 632 633 634 635 636 637 638 639640 641 642 643 644 645 646 647 648 649650 651 652 653 654 655 656 657 658 659660 661 662 663 664 665 666 667 668 669670 671 672 673 674 675 676 677 678 679680 681 682 683 684 685 686 687 688 689690 691 692 693 694 695 696 697 698 699700 701 702 703 704 705 706 707 708 709710 711 712 713 714 715 716 717 718 719720 721 722 723 724 725 726 727 728 729730 731 732 733 734 735 736 737 738 739740 741 742 743 744 745 746 747 748 749750 751 752 753 754 755 756 757 758 759760 761 762 763 764 765 766 767 768 769770 771 772 773 774 775 776 777 778 779780 781 782 783 784 785 786 787 788 789790 791 792 793 794 795 796 797 798 799800 801 802 803 804 805 806 807 808 809810 811 812 813 814 815 816 817 818 819820 821 822 823 824 825 826 827 828 829830 831 832 833 834 835 836 837 838 839840 841 842 843 844 845 846 847 848 849850 851 852 853 854 855 856 857 858 859860 861 862 863 864 865 866 867 868 869870 871 872 873 874 875 876 877 878 879880 881 882 883 884 885 886 887 888 889890 891 892 893 894 895 896 897 898 899900 901 902 903 904 905 906 907 908 909910 911 912 913 914 915 916 917 918 919920 921 922 923 924 925 926 927 928 929930 931 932 933 934 935 936 937 938 939940 941 942 943 944 945 946 947 948 949950 951 952 953 954 955 956 957 958 959960 961 962 963 964 965 966 967 968 969970 971 972 973 974 975 976 977 978 979980 981 982 983 984 985 986 987 988 989990 991 992 993 994 995 996 997 998 999' as long_query
Query set global general_log = off
deallocate prepare long_query;
set global general_log = @old_general_log_state;

View file

@ -722,4 +722,7 @@ a int(11) YES NULL
b varchar(255) YES NULL
c datetime YES NULL
drop table t1;
mysqltest: At line 1: change user failed: Unknown database 'inexistent'
mysqltest: At line 1: change user failed: Access denied for user 'inexistent'@'localhost' (using password: NO)
mysqltest: At line 1: change user failed: Access denied for user 'root'@'localhost' (using password: YES)
End of tests

View file

@ -1650,86 +1650,8 @@ a (select count(*) from t2)
3 0
4 0
drop table t1,t2;
DROP DATABASE IF EXISTS bug30269;
FLUSH STATUS;
CREATE DATABASE bug30269;
USE bug30269;
CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
set global query_cache_size= 81920;
USE bug30269;
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
# Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2;
id
5
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
SELECT id FROM view1 WHERE id>2;
id
5
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
DROP DATABASE bug30269;
DROP USER 'bug30269'@'localhost';
End of 5.0 tests
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
End of 5.0 tests
drop database if exists db1;
drop database if exists db2;
set GLOBAL query_cache_size=15*1024*1024;
create database db1;
use db1;
create table t1(c1 int)engine=myisam;
insert into t1(c1) values (1);
select * from db1.t1 f;
c1
1
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
rename schema db1 to db2;
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
drop database db2;
set global query_cache_size=default;
drop database if exists db1;
drop database if exists db3;
set GLOBAL query_cache_size=15*1024*1024;
create database db1;
create database db3;
use db1;
create table t1(c1 int) engine=myisam;
use db3;
create table t1(c1 int) engine=myisam;
use db1;
insert into t1(c1) values (1);
use mysql;
select * from db1.t1;
c1
1
select c1+1 from db1.t1;
c1+1
2
select * from db3.t1;
c1
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 3
rename schema db1 to db2;
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
drop database db2;
drop database db3;
End of 5.1 tests

View file

@ -347,3 +347,36 @@ drop table t1;
drop function f1;
set GLOBAL query_cache_size=0;
SET GLOBAL log_bin_trust_function_creators = 0;
DROP DATABASE IF EXISTS bug30269;
FLUSH STATUS;
CREATE DATABASE bug30269;
USE bug30269;
CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
set global query_cache_size= 81920;
USE bug30269;
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
# Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2;
id
5
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
SELECT id FROM view1 WHERE id>2;
id
5
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
DROP DATABASE bug30269;
DROP USER 'bug30269'@'localhost';
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;

View file

@ -1,33 +1,12 @@
drop database if exists testdb1;
create database testdb1 default character set latin2;
use testdb1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
show create database testdb1;
Database Create Database
testdb1 CREATE DATABASE `testdb1` /*!40100 DEFAULT CHARACTER SET latin2 */
show tables;
Tables_in_testdb1
t1
rename database testdb1 to testdb2;
show create database testdb1;
ERROR 42000: Unknown database 'testdb1'
show create database testdb2;
Database Create Database
testdb2 CREATE DATABASE `testdb2` /*!40100 DEFAULT CHARACTER SET latin2 */
select database();
database()
testdb2
show tables;
Tables_in_testdb2
t1
select a from t1 order by a;
a
1
2
3
drop database testdb2;
create database testdb1;
rename database testdb1 to testdb1;
ERROR HY000: Can't create database 'testdb1'; database exists
drop database testdb1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'database testdb1 to testdb2' at line 1
ALTER DATABASE wrong UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Unknown database '#mysql50#upgrade-me'

View file

@ -155,11 +155,11 @@ Pos Instruction
0 stmt 9 "drop temporary table if exists sudoku..."
1 stmt 1 "create temporary table sudoku_work ( ..."
2 stmt 1 "create temporary table sudoku_schedul..."
3 stmt 95 "call sudoku_init()"
3 stmt 94 "call sudoku_init()"
4 jump_if_not 7(8) p_naive@0
5 stmt 4 "update sudoku_work set cnt = 0 where ..."
6 jump 8
7 stmt 95 "call sudoku_count()"
7 stmt 94 "call sudoku_count()"
8 stmt 6 "insert into sudoku_schedule (row,col)..."
9 set v_scounter@2 0
10 set v_i@3 1

View file

@ -142,7 +142,10 @@ declare c cursor for insert into test.t1 values ("foo", 42);
open c;
close c;
end|
ERROR 42000: Cursor statement must be a SELECT
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insert into test.t1 values ("foo", 42);
open c;
close c;
end' at line 3
create procedure p()
begin
declare x int;
@ -1223,7 +1226,7 @@ ERROR 42S02: Unknown table 'c' in field list
drop procedure bug15091;
drop function if exists bug16896;
create aggregate function bug16896() returns int return 1;
ERROR 42000: AGGREGATE is not supported for stored functions
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '() returns int return 1' at line 1
DROP PROCEDURE IF EXISTS bug14702;
CREATE IF NOT EXISTS PROCEDURE bug14702()
BEGIN
@ -1478,3 +1481,45 @@ end
until true end repeat retry;
end//
ERROR 42000: LEAVE with no matching label: retry
drop procedure if exists proc_28360;
drop function if exists func_28360;
CREATE PROCEDURE proc_28360()
BEGIN
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
END//
ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
CREATE FUNCTION func_28360() RETURNS int
BEGIN
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
RETURN 0;
END//
ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1()
BEGIN
DECLARE c char(100);
DECLARE cur1 CURSOR FOR SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END' at line 4
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
SELECT inexistent(), 1 + ,;
ERROR 42000: FUNCTION inexistent does not exist
SELECT inexistent();
ERROR 42000: FUNCTION inexistent does not exist
SELECT .inexistent();
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '()' at line 1
SELECT ..inexistent();
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.inexistent()' at line 1
USE test;

View file

@ -4914,7 +4914,7 @@ create table t3 as select * from v1|
show create table t3|
Table Create Table
t3 CREATE TABLE `t3` (
`j` bigint(11) DEFAULT NULL
`j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3|
j
@ -6620,4 +6620,295 @@ DROP TABLE t1;
DROP PROCEDURE p1;
DROP PROCEDURE p2;
#
# Bug#31035.
#
#
# - Prepare.
#
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP FUNCTION IF EXISTS f3;
DROP FUNCTION IF EXISTS f4;
#
# - Create required objects.
#
CREATE TABLE t1(c1 INT);
INSERT INTO t1 VALUES (1), (2), (3);
CREATE FUNCTION f1()
RETURNS INT
NOT DETERMINISTIC
RETURN 1;
CREATE FUNCTION f2(p INT)
RETURNS INT
NOT DETERMINISTIC
RETURN 1;
CREATE FUNCTION f3()
RETURNS INT
DETERMINISTIC
RETURN 1;
CREATE FUNCTION f4(p INT)
RETURNS INT
DETERMINISTIC
RETURN 1;
#
# - Check.
#
SELECT f1() AS a FROM t1 GROUP BY a;
a
1
SELECT f2(@a) AS a FROM t1 GROUP BY a;
a
1
SELECT f3() AS a FROM t1 GROUP BY a;
a
1
SELECT f4(0) AS a FROM t1 GROUP BY a;
a
1
SELECT f4(@a) AS a FROM t1 GROUP BY a;
a
1
#
# - Cleanup.
#
DROP TABLE t1;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP FUNCTION f3;
DROP FUNCTION f4;
#
# Bug#31191.
#
#
# - Prepare.
#
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP FUNCTION IF EXISTS f1;
#
# - Create required objects.
#
CREATE TABLE t1 (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
barcode INT(8) UNSIGNED ZEROFILL nOT NULL,
PRIMARY KEY (id),
UNIQUE KEY barcode (barcode)
);
INSERT INTO t1 (id, barcode) VALUES (1, 12345678);
INSERT INTO t1 (id, barcode) VALUES (2, 12345679);
CREATE TABLE test.t2 (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
barcode BIGINT(11) UNSIGNED ZEROFILL NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO test.t2 (id, barcode) VALUES (1, 12345106708);
INSERT INTO test.t2 (id, barcode) VALUES (2, 12345106709);
CREATE FUNCTION f1(p INT(8))
RETURNS BIGINT(11) UNSIGNED
READS SQL DATA
RETURN FLOOR(p/1000)*1000000 + 100000 + FLOOR((p MOD 1000)/10)*100 + (p MOD 10);
#
# - Check.
#
SELECT DISTINCT t1.barcode, f1(t1.barcode)
FROM t1
INNER JOIN t2
ON f1(t1.barcode) = t2.barcode
WHERE t1.barcode=12345678;
barcode f1(t1.barcode)
12345678 12345106708
#
# - Cleanup.
#
DROP TABLE t1;
DROP TABLE t2;
DROP FUNCTION f1;
#
# Bug#31226.
#
#
# - Prepare.
#
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
#
# - Create required objects.
#
CREATE TABLE t1(id INT);
INSERT INTO t1 VALUES (1), (2), (3);
CREATE FUNCTION f1()
RETURNS DATETIME
NOT DETERMINISTIC NO SQL
RETURN NOW();
#
# - Check.
#
SELECT f1() FROM t1 GROUP BY 1;
f1()
<timestamp>
#
# - Cleanup.
#
DROP TABLE t1;
DROP FUNCTION f1;
DROP PROCEDURE IF EXISTS db28318_a.t1;
DROP PROCEDURE IF EXISTS db28318_b.t2;
DROP DATABASE IF EXISTS db28318_a;
DROP DATABASE IF EXISTS db28318_b;
CREATE DATABASE db28318_a;
CREATE DATABASE db28318_b;
CREATE PROCEDURE db28318_a.t1() SELECT "db28318_a.t1";
CREATE PROCEDURE db28318_b.t2() CALL t1();
use db28318_a;
CALL db28318_b.t2();
ERROR 42000: PROCEDURE db28318_b.t1 does not exist
DROP PROCEDURE db28318_a.t1;
DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
use test;
End of 5.0 tests
#
# Bug#20550.
#
#
# - Prepare.
#
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
#
# - Create required objects.
#
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
CREATE VIEW v1 AS SELECT f1();
CREATE VIEW v2 AS SELECT f2();
#
# - Check.
#
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
DATA_TYPE
varchar
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
DATA_TYPE
tinyint
#
# - Cleanup.
#
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1;
DROP VIEW v2;
#
# - Bug#24923: prepare.
#
DROP FUNCTION IF EXISTS f1;
#
# - Bug#24923: create required objects.
#
CREATE FUNCTION f1(p INT)
RETURNS ENUM ('Very_long_enum_element_identifier',
'Another_very_long_enum_element_identifier')
BEGIN
CASE p
WHEN 1 THEN
RETURN 'Very_long_enum_element_identifier';
ELSE
RETURN 'Another_very_long_enum_element_identifier';
END CASE;
END|
#
# - Bug#24923: check.
#
SELECT f1(1);
f1(1)
Very_long_enum_element_identifier
SELECT f1(2);
f1(2)
Another_very_long_enum_element_identifier
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`(p INT) RETURNS enum('Very_long_enum_element_identifier','Another_very_long_enum_element_identifier') CHARSET latin1
BEGIN
CASE p
WHEN 1 THEN
RETURN 'Very_long_enum_element_identifier';
ELSE
RETURN 'Another_very_long_enum_element_identifier';
END CASE;
END latin1 latin1_swedish_ci latin1_swedish_ci
#
# - Bug#24923: cleanup.
#
DROP FUNCTION f1;
End of 5.1 tests

View file

@ -196,7 +196,7 @@ proc CREATE TABLE `proc` (
`is_deterministic` enum('YES','NO') NOT NULL DEFAULT 'NO',
`security_type` enum('INVOKER','DEFINER') NOT NULL DEFAULT 'DEFINER',
`param_list` blob NOT NULL,
`returns` char(64) NOT NULL DEFAULT '',
`returns` longblob NOT NULL,
`body` longblob NOT NULL,
`definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

View file

@ -95,10 +95,10 @@ FR
DROP TABLE bug19904;
CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
RETURNS STRING SONAME "should_not_parse.so";
ERROR HY000: Incorrect usage of SONAME and DEFINER
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RETURNS STRING SONAME "should_not_parse.so"' at line 2
CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
RETURNS STRING SONAME "should_not_parse.so";
ERROR HY000: Incorrect usage of SONAME and DEFINER
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RETURNS STRING SONAME "should_not_parse.so"' at line 2
create table t1(f1 int);
insert into t1 values(1),(2);
explain select myfunc_int(f1) from t1 order by 1;
@ -214,7 +214,7 @@ DROP FUNCTION IF EXISTS metaphon;
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Function 'metaphon' already exists
DROP FUNCTION metaphon;
DROP FUNCTION metaphon;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
CREATE FUNCTION metaphon(a int) RETURNS int
@ -334,6 +334,13 @@ Qcache_queries_in_cache 0
drop table t1;
drop function metaphon;
set GLOBAL query_cache_size=default;
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
USE test;
CREATE TABLE const_len_bug (
str_const varchar(4000),
result1 varchar(4000),

View file

@ -59,3 +59,28 @@ drop table `txu@0023p@0023p1`;
drop table `txu#p#p1`;
truncate t1;
drop table t1;
drop database if exists `tabc`;
drop database if exists `a-b-c`;
create database `tabc` default character set latin2;
create table tabc.t1 (a int);
FLUSH TABLES;
show databases like '%a-b-c%';
Database (%a-b-c%)
#mysql50#a-b-c
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
show databases like '%a-b-c%';
Database (%a-b-c%)
a-b-c
show create database `a-b-c`;
Database Create Database
a-b-c CREATE DATABASE `a-b-c` /*!40100 DEFAULT CHARACTER SET latin2 */
show tables in `a-b-c`;
Tables_in_a-b-c
t1
show create table `a-b-c`.`t1`;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin2
drop database `a-b-c`;
drop database `tabc`;

View file

@ -0,0 +1,35 @@
#
# Bug#20023 mysql_change_user() resets the value of SQL_BIG_SELECTS
#
--echo Bug#20023
SELECT @@session.sql_big_selects;
SELECT @@global.max_join_size;
--echo change_user
--change_user
SELECT @@session.sql_big_selects;
SELECT @@global.max_join_size;
SET @@global.max_join_size = 10000;
SET @@session.max_join_size = default;
--echo change_user
--change_user
SELECT @@session.sql_big_selects;
SET @@global.max_join_size = -1;
SET @@session.max_join_size = default;
--echo change_user
--change_user
SELECT @@session.sql_big_selects;
#
# Bug#31418 User locks misfunctioning after mysql_change_user()
#
--echo Bug#31418
SELECT IS_FREE_LOCK('bug31418');
SELECT IS_USED_LOCK('bug31418');
SELECT GET_LOCK('bug31418', 1);
SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID();
--echo change_user
--change_user
SELECT IS_FREE_LOCK('bug31418');
SELECT IS_USED_LOCK('bug31418');

View file

@ -1197,14 +1197,17 @@ drop table t1,t2;
CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
--error 1102
DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
--error 1049
RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
--error 1102
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
create database mysqltest;
--error 1102
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
drop database mysqltest;
# TODO: enable these tests when RENAME DATABASE is implemented.
# --error 1049
# RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
# --error 1102
# RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
# create database mysqltest;
# --error 1102
# RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
# drop database mysqltest;
--error 1102
USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
--error 1102
@ -1300,4 +1303,29 @@ return 0;
drop view имя_вью_кодировке_утф8_длиной_большеем_42;
drop table имя_таблицы_в_кодировке_утф8_длиной_большеем_48;
set names default;
#
# Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash
#
--disable_warnings
drop table if exists t1,t2,t3;
drop function if exists f1;
--enable_warnings
--delimiter |
create function f1() returns int
begin
declare res int;
create temporary table t3 select 1 i;
set res:= (select count(*) from t1);
drop temporary table t3;
return res;
end|
--delimiter ;
create table t1 as select 1;
create table t2 as select f1() from t1;
drop table t1,t2;
drop function f1;
--echo End of 5.1 tests

View file

@ -251,4 +251,35 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNION=(t1);
--error 1031
INSERT DELAYED INTO t2 VALUES(1);
DROP TABLE t1, t2;
#
# Bug#27358 INSERT DELAYED does not honour SQL_MODE of the client
#
--disable_warnings
DROP TABLE IF EXISTS t1,t2;
--enable_warnings
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE `t1` (
`id` int(11) PRIMARY KEY auto_increment,
`f1` varchar(10) NOT NULL UNIQUE
);
INSERT DELAYED INTO t1 VALUES(0,"test1");
sleep 1;
SELECT * FROM t1;
SET SQL_MODE='PIPES_AS_CONCAT';
INSERT DELAYED INTO t1 VALUES(0,'a' || 'b');
sleep 1;
SELECT * FROM t1;
SET SQL_MODE='ERROR_FOR_DIVISION_BY_ZERO,STRICT_ALL_TABLES';
--error 1365
INSERT DELAYED INTO t1 VALUES(mod(1,0),"test3");
CREATE TABLE t2 (
`id` int(11) PRIMARY KEY auto_increment,
`f1` date
);
SET SQL_MODE='NO_ZERO_DATE,STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
--error ER_TRUNCATED_WRONG_VALUE
INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
--error ER_TRUNCATED_WRONG_VALUE
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
DROP TABLE t1,t2;

View file

@ -953,7 +953,7 @@ BEGIN
DECLARE col1, col2, col3, col4, col6 CHAR(255);
DECLARE default_val VARCHAR(65532);
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SHOW COLUMNS FROM bug23037;
DECLARE cur1 CURSOR FOR SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='bug23037';
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
FETCH cur1 INTO col1, col2, col3, col4, default_val, col6;

View file

@ -295,6 +295,13 @@ unlock tables;
# Bug #21785 Server crashes after rename of the log table
#
--disable_warnings
drop table if exists mysql.renamed_general_log;
drop table if exists mysql.renamed_slow_log;
drop table if exists mysql.general_log_new;
drop table if exists mysql.slow_log_new;
--enable_warnings
use mysql;
# Should result in error
--error ER_CANT_RENAME_LOG_TABLE
@ -358,6 +365,55 @@ flush logs;
drop table renamed_general_log, renamed_slow_log;
use test;
#
# Bug#27858 (Failing to log to a log table doesn't log anything to error log)
#
# This test works as expected, it's a negative test.
# The message "[ERROR] Failed to write to mysql.general_log"
# is printed to master.err when writing to the table mysql.general_log
# failed.
# However, this message is picked up by mysql-test-run.pl,
# and reported as a test failure, which is a false negative.
# There is no current way to *selectively* filter out these expected error conditions
# (see mysql-test/lib/mtr_report.pl, mtr_report_stats()).
# Instead of filtering all occurences of "Failed to write to
# mysql.general_log", which could hide bugs when the error is not expected,
# this test case is commented instead.
# TODO: improve filtering of expected errors in master.err in
# mysql-test-run.pl (based on the test name ?), and uncomment this test.
# --disable_warnings
# drop table if exists mysql.bad_general_log;
# drop table if exists mysql.bad_slow_log;
# drop table if exists mysql.general_log_hide;
# drop table if exists mysql.slow_log_hide;
# --enable_warnings
#
# create table mysql.bad_general_log (a int) engine= CSV;
# create table mysql.bad_slow_log (a int) engine= CSV;
#
# # Rename does not perform checks on the table structure,
# # exploiting this to force a failure to log
# rename table mysql.general_log to mysql.general_log_hide, mysql.bad_general_log TO mysql.general_log;
# rename table mysql.slow_log to mysql.slow_log_hide, mysql.bad_slow_log TO mysql.slow_log;
#
# # The following message should be printed in master.log:
# # [ERROR] Failed to write to mysql.general_log
# # TODO: See how verifying this could be automated
#
# flush tables;
# select "logging this should fail";
#
# # Restore the log tables
#
# rename table mysql.general_log to mysql.bad_general_log, mysql.general_log_hide TO mysql.general_log;
# rename table mysql.slow_log to mysql.bad_slow_log, mysql.slow_log_hide TO mysql.slow_log;
#
# flush tables;
#
# drop table mysql.bad_general_log;
# drop table mysql.bad_slow_log;
#
# Bug #21966 Strange warnings on repair of the log tables
#
@ -751,3 +807,120 @@ DROP DATABASE IF EXISTS `db_17876`;
SET GLOBAL general_log = @old_general_log_state;
SET GLOBAL slow_query_log = @old_slow_log_state;
#
# Bug#21557 entries in the general query log truncated at 1000 characters.
#
truncate table mysql.general_log;
set @old_general_log_state = @@global.general_log;
set global general_log = on;
--disable_result_log
set @lparam = "000 001 002 003 004 005 006 007 008 009"
"010 011 012 013 014 015 016 017 018 019"
"020 021 022 023 024 025 026 027 028 029"
"030 031 032 033 034 035 036 037 038 039"
"040 041 042 043 044 045 046 047 048 049"
"050 051 052 053 054 055 056 057 058 059"
"060 061 062 063 064 065 066 067 068 069"
"070 071 072 073 074 075 076 077 078 079"
"080 081 082 083 084 085 086 087 088 089"
"090 091 092 093 094 095 096 097 098 099"
"100 101 102 103 104 105 106 107 108 109"
"110 111 112 113 114 115 116 117 118 119"
"120 121 122 123 124 125 126 127 128 129"
"130 131 132 133 134 135 136 137 138 139"
"140 141 142 143 144 145 146 147 148 149"
"150 151 152 153 154 155 156 157 158 159"
"160 161 162 163 164 165 166 167 168 169"
"170 171 172 173 174 175 176 177 178 179"
"180 181 182 183 184 185 186 187 188 189"
"190 191 192 193 194 195 196 197 198 199"
"200 201 202 203 204 205 206 207 208 209"
"210 211 212 213 214 215 216 217 218 219"
"220 221 222 223 224 225 226 227 228 229"
"230 231 232 233 234 235 236 237 238 239"
"240 241 242 243 244 245 246 247 248 249"
"250 251 252 253 254 255 256 257 258 259"
"260 261 262 263 264 265 266 267 268 269"
"270 271 272 273 274 275 276 277 278 279"
"280 281 282 283 284 285 286 287 288 289"
"290 291 292 293 294 295 296 297 298 299"
"300 301 302 303 304 305 306 307 308 309"
"310 311 312 313 314 315 316 317 318 319"
"320 321 322 323 324 325 326 327 328 329"
"330 331 332 333 334 335 336 337 338 339"
"340 341 342 343 344 345 346 347 348 349"
"350 351 352 353 354 355 356 357 358 359"
"360 361 362 363 364 365 366 367 368 369"
"370 371 372 373 374 375 376 377 378 379"
"380 381 382 383 384 385 386 387 388 389"
"390 391 392 393 394 395 396 397 398 399"
"400 401 402 403 404 405 406 407 408 409"
"410 411 412 413 414 415 416 417 418 419"
"420 421 422 423 424 425 426 427 428 429"
"430 431 432 433 434 435 436 437 438 439"
"440 441 442 443 444 445 446 447 448 449"
"450 451 452 453 454 455 456 457 458 459"
"460 461 462 463 464 465 466 467 468 469"
"470 471 472 473 474 475 476 477 478 479"
"480 481 482 483 484 485 486 487 488 489"
"490 491 492 493 494 495 496 497 498 499"
"500 501 502 503 504 505 506 507 508 509"
"510 511 512 513 514 515 516 517 518 519"
"520 521 522 523 524 525 526 527 528 529"
"530 531 532 533 534 535 536 537 538 539"
"540 541 542 543 544 545 546 547 548 549"
"550 551 552 553 554 555 556 557 558 559"
"560 561 562 563 564 565 566 567 568 569"
"570 571 572 573 574 575 576 577 578 579"
"580 581 582 583 584 585 586 587 588 589"
"590 591 592 593 594 595 596 597 598 599"
"600 601 602 603 604 605 606 607 608 609"
"610 611 612 613 614 615 616 617 618 619"
"620 621 622 623 624 625 626 627 628 629"
"630 631 632 633 634 635 636 637 638 639"
"640 641 642 643 644 645 646 647 648 649"
"650 651 652 653 654 655 656 657 658 659"
"660 661 662 663 664 665 666 667 668 669"
"670 671 672 673 674 675 676 677 678 679"
"680 681 682 683 684 685 686 687 688 689"
"690 691 692 693 694 695 696 697 698 699"
"700 701 702 703 704 705 706 707 708 709"
"710 711 712 713 714 715 716 717 718 719"
"720 721 722 723 724 725 726 727 728 729"
"730 731 732 733 734 735 736 737 738 739"
"740 741 742 743 744 745 746 747 748 749"
"750 751 752 753 754 755 756 757 758 759"
"760 761 762 763 764 765 766 767 768 769"
"770 771 772 773 774 775 776 777 778 779"
"780 781 782 783 784 785 786 787 788 789"
"790 791 792 793 794 795 796 797 798 799"
"800 801 802 803 804 805 806 807 808 809"
"810 811 812 813 814 815 816 817 818 819"
"820 821 822 823 824 825 826 827 828 829"
"830 831 832 833 834 835 836 837 838 839"
"840 841 842 843 844 845 846 847 848 849"
"850 851 852 853 854 855 856 857 858 859"
"860 861 862 863 864 865 866 867 868 869"
"870 871 872 873 874 875 876 877 878 879"
"880 881 882 883 884 885 886 887 888 889"
"890 891 892 893 894 895 896 897 898 899"
"900 901 902 903 904 905 906 907 908 909"
"910 911 912 913 914 915 916 917 918 919"
"920 921 922 923 924 925 926 927 928 929"
"930 931 932 933 934 935 936 937 938 939"
"940 941 942 943 944 945 946 947 948 949"
"950 951 952 953 954 955 956 957 958 959"
"960 961 962 963 964 965 966 967 968 969"
"970 971 972 973 974 975 976 977 978 979"
"980 981 982 983 984 985 986 987 988 989"
"990 991 992 993 994 995 996 997 998 999";
--enable_result_log
prepare long_query from "select ? as long_query";
--disable_result_log
execute long_query using @lparam;
--enable_result_log
set global general_log = off;
select command_type, argument from mysql.general_log;
deallocate prepare long_query;
set global general_log = @old_general_log_state;

View file

@ -8,8 +8,8 @@
# server or run mysql-test-run --debug mysql_client_test and check
# var/log/mysql_client_test.trace
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
# End of 4.1 tests
echo ok;

View file

@ -2083,5 +2083,23 @@ eval $show_statement;
drop table t1;
# ----------------------------------------------------------------------------
# Test change_user command
# ----------------------------------------------------------------------------
--error 1
--exec echo "--change_user root,,inexistent" | $MYSQL_TEST 2>&1
--error 1
--exec echo "--change_user inexistent,,test" | $MYSQL_TEST 2>&1
--error 1
--exec echo "--change_user root,inexistent,test" | $MYSQL_TEST 2>&1
--change_user
--change_user root
--change_user root,,
--change_user root,,test
--echo End of tests

View file

@ -1,10 +1,5 @@
-- source include/have_query_cache.inc
# Disabled on embedded due to bug #30710, "query_cache.test fails on
# embedded w/ per-column privs test". Please re-enable when that bug
# is resolved.
-- source include/not_embedded.inc
#
# Tests with query cache
#
@ -1255,82 +1250,52 @@ disconnect user1;
disconnect user2;
disconnect user3;
#
# Bug #30269 Query cache eats memory
#
--disable_warnings
DROP DATABASE IF EXISTS bug30269;
--enable_warnings
FLUSH STATUS;
CREATE DATABASE bug30269;
USE bug30269;
CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
set global query_cache_size= 81920;
connect (bug30269, localhost, bug30269,,);
connection bug30269;
USE bug30269;
show status like 'Qcache_queries_in_cache';
--echo # Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2;
show status like 'Qcache_queries_in_cache';
SELECT id FROM view1 WHERE id>2;
show status like 'Qcache_queries_in_cache';
--echo End of 5.0 tests
connection default;
DROP DATABASE bug30269;
disconnect bug30269;
DROP USER 'bug30269'@'localhost';
#
# Bug #28211 RENAME DATABASE and query cache don't play nicely together
# TODO: enable these tests when RENAME DATABASE is implemented.
# --disable_warnings
# drop database if exists db1;
# drop database if exists db2;
# --enable_warnings
# set GLOBAL query_cache_size=15*1024*1024;
# create database db1;
# use db1;
# create table t1(c1 int)engine=myisam;
# insert into t1(c1) values (1);
# select * from db1.t1 f;
# show status like 'Qcache_queries_in_cache';
# rename schema db1 to db2;
# show status like 'Qcache_queries_in_cache';
# drop database db2;
# set global query_cache_size=default;
#
# --disable_warnings
# drop database if exists db1;
# drop database if exists db3;
# --enable_warnings
# set GLOBAL query_cache_size=15*1024*1024;
# create database db1;
# create database db3;
# use db1;
# create table t1(c1 int) engine=myisam;
# use db3;
# create table t1(c1 int) engine=myisam;
# use db1;
# insert into t1(c1) values (1);
# use mysql;
# select * from db1.t1;
# select c1+1 from db1.t1;
# select * from db3.t1;
# show status like 'Qcache_queries_in_cache';
# rename schema db1 to db2;
# show status like 'Qcache_queries_in_cache';
# drop database db2;
# drop database db3;
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
--echo End of 5.0 tests
#
# Bug #28211 RENAME DATABASE and query cache don't play nicely together
#
--disable_warnings
drop database if exists db1;
drop database if exists db2;
--enable_warnings
set GLOBAL query_cache_size=15*1024*1024;
create database db1;
use db1;
create table t1(c1 int)engine=myisam;
insert into t1(c1) values (1);
select * from db1.t1 f;
show status like 'Qcache_queries_in_cache';
rename schema db1 to db2;
show status like 'Qcache_queries_in_cache';
drop database db2;
set global query_cache_size=default;
--disable_warnings
drop database if exists db1;
drop database if exists db3;
--enable_warnings
set GLOBAL query_cache_size=15*1024*1024;
create database db1;
create database db3;
use db1;
create table t1(c1 int) engine=myisam;
use db3;
create table t1(c1 int) engine=myisam;
use db1;
insert into t1(c1) values (1);
use mysql;
select * from db1.t1;
select c1+1 from db1.t1;
select * from db3.t1;
show status like 'Qcache_queries_in_cache';
rename schema db1 to db2;
show status like 'Qcache_queries_in_cache';
drop database db2;
drop database db3;
--echo End of 5.1 tests

View file

@ -225,3 +225,39 @@ connection default;
set GLOBAL query_cache_size=0;
SET GLOBAL log_bin_trust_function_creators = 0;
#
# Bug #30269 Query cache eats memory
#
--disable_warnings
DROP DATABASE IF EXISTS bug30269;
--enable_warnings
FLUSH STATUS;
CREATE DATABASE bug30269;
USE bug30269;
CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
set global query_cache_size= 81920;
connect (bug30269, localhost, bug30269,,);
connection bug30269;
USE bug30269;
show status like 'Qcache_queries_in_cache';
--echo # Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2;
show status like 'Qcache_queries_in_cache';
SELECT id FROM view1 WHERE id>2;
show status like 'Qcache_queries_in_cache';
connection default;
DROP DATABASE bug30269;
disconnect bug30269;
DROP USER 'bug30269'@'localhost';
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;

View file

@ -1,26 +1,53 @@
--disable_warnings
drop database if exists testdb1;
--enable_warnings
create database testdb1 default character set latin2;
use testdb1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
show create database testdb1;
show tables;
rename database testdb1 to testdb2;
--error 1049
show create database testdb1;
show create database testdb2;
select database();
show tables;
select a from t1 order by a;
drop database testdb2;
# TODO: enable these tests when RENAME DATABASE is implemented.
#
# --disable_warnings
# drop database if exists testdb1;
# --enable_warnings
#
# create database testdb1 default character set latin2;
# use testdb1;
# create table t1 (a int);
# insert into t1 values (1),(2),(3);
# show create database testdb1;
# show tables;
# rename database testdb1 to testdb2;
# --error 1049
# show create database testdb1;
# show create database testdb2;
# select database();
# show tables;
# select a from t1 order by a;
# drop database testdb2;
#
#
# Bug#19392 Rename Database: Crash if case change
#
create database testdb1;
--error 1007
rename database testdb1 to testdb1;
drop database testdb1;
# create database testdb1;
# --error 1007
# rename database testdb1 to testdb1;
# drop database testdb1;
#
# WL#4030 (Deprecate RENAME DATABASE: replace with ALTER DATABASE <name> UPGRADE)
#
--error ER_PARSE_ERROR
rename database testdb1 to testdb2;
--error ER_WRONG_USAGE
ALTER DATABASE wrong UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE
ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
--error ER_BAD_DB_ERROR
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;

View file

@ -196,7 +196,7 @@ select f(10)|
drop function f|
--error 1322
--error ER_PARSE_ERROR
create procedure p()
begin
declare c cursor for insert into test.t1 values ("foo", 42);
@ -1763,7 +1763,7 @@ drop procedure bug15091;
drop function if exists bug16896;
--enable_warnings
--error ER_SP_NO_AGGREGATE
--error ER_PARSE_ERROR
create aggregate function bug16896() returns int return 1;
#
@ -2150,6 +2150,78 @@ end//
delimiter ;//
#
# Bug#28360 (RENAME DATABASE destroys routines)
#
--disable_warnings
drop procedure if exists proc_28360;
drop function if exists func_28360;
--enable_warnings
delimiter //;
--error ER_SP_NO_DROP_SP
CREATE PROCEDURE proc_28360()
BEGIN
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
END//
--error ER_SP_NO_DROP_SP
CREATE FUNCTION func_28360() RETURNS int
BEGIN
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
RETURN 0;
END//
delimiter ;//
#
# Bug#29223 declare cursor c for SHOW .....
#
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
--delimiter |
--error ER_PARSE_ERROR
CREATE PROCEDURE p1()
BEGIN
DECLARE c char(100);
DECLARE cur1 CURSOR FOR SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END|
--delimiter ;
#
# Bug#29816 Syntactically wrong query fails with misleading error message
#
--disable_warnings
DROP DATABASE IF EXISTS mysqltest;
--enable_warnings
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
# Both ER_SP_DOES_NOT_EXIST and ER_PARSE_ERROR are valid here,
# the result is implementation dependent:
# See Bug#29816 for details
--error ER_SP_DOES_NOT_EXIST
SELECT inexistent(), 1 + ,;
--error ER_SP_DOES_NOT_EXIST
SELECT inexistent();
--error ER_PARSE_ERROR
SELECT .inexistent();
--error ER_PARSE_ERROR
SELECT ..inexistent();
USE test;
#
# BUG#NNNN: New bug synopsis
#

View file

@ -7581,4 +7581,479 @@ DROP TABLE t1;
DROP PROCEDURE p1;
DROP PROCEDURE p2;
###########################################################################
#
# Bug#31035: select from function, group by result crasher.
#
###########################################################################
--echo
--echo #
--echo # Bug#31035.
--echo #
--echo
--echo #
--echo # - Prepare.
--echo #
--echo
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP FUNCTION IF EXISTS f3;
DROP FUNCTION IF EXISTS f4;
--enable_warnings
--echo
--echo #
--echo # - Create required objects.
--echo #
--echo
CREATE TABLE t1(c1 INT);
--echo
INSERT INTO t1 VALUES (1), (2), (3);
--echo
CREATE FUNCTION f1()
RETURNS INT
NOT DETERMINISTIC
RETURN 1;
--echo
CREATE FUNCTION f2(p INT)
RETURNS INT
NOT DETERMINISTIC
RETURN 1;
--echo
CREATE FUNCTION f3()
RETURNS INT
DETERMINISTIC
RETURN 1;
--echo
CREATE FUNCTION f4(p INT)
RETURNS INT
DETERMINISTIC
RETURN 1;
--echo
--echo #
--echo # - Check.
--echo #
--echo
# Not deterministic function, no arguments.
SELECT f1() AS a FROM t1 GROUP BY a;
--echo
# Not deterministic function, non-constant argument.
SELECT f2(@a) AS a FROM t1 GROUP BY a;
--echo
# Deterministic function, no arguments.
SELECT f3() AS a FROM t1 GROUP BY a;
--echo
# Deterministic function, constant argument.
SELECT f4(0) AS a FROM t1 GROUP BY a;
--echo
# Deterministic function, non-constant argument.
SELECT f4(@a) AS a FROM t1 GROUP BY a;
--echo
--echo #
--echo # - Cleanup.
--echo #
--echo
DROP TABLE t1;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP FUNCTION f3;
DROP FUNCTION f4;
--echo
###########################################################################
#
# Bug#31191: JOIN in combination with stored function crashes the server.
#
###########################################################################
--echo #
--echo # Bug#31191.
--echo #
--echo
--echo #
--echo # - Prepare.
--echo #
--echo
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
--echo
--echo #
--echo # - Create required objects.
--echo #
--echo
CREATE TABLE t1 (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
barcode INT(8) UNSIGNED ZEROFILL nOT NULL,
PRIMARY KEY (id),
UNIQUE KEY barcode (barcode)
);
--echo
INSERT INTO t1 (id, barcode) VALUES (1, 12345678);
INSERT INTO t1 (id, barcode) VALUES (2, 12345679);
--echo
CREATE TABLE test.t2 (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
barcode BIGINT(11) UNSIGNED ZEROFILL NOT NULL,
PRIMARY KEY (id)
);
--echo
INSERT INTO test.t2 (id, barcode) VALUES (1, 12345106708);
INSERT INTO test.t2 (id, barcode) VALUES (2, 12345106709);
--echo
CREATE FUNCTION f1(p INT(8))
RETURNS BIGINT(11) UNSIGNED
READS SQL DATA
RETURN FLOOR(p/1000)*1000000 + 100000 + FLOOR((p MOD 1000)/10)*100 + (p MOD 10);
--echo
--echo #
--echo # - Check.
--echo #
--echo
SELECT DISTINCT t1.barcode, f1(t1.barcode)
FROM t1
INNER JOIN t2
ON f1(t1.barcode) = t2.barcode
WHERE t1.barcode=12345678;
--echo
--echo #
--echo # - Cleanup.
--echo #
--echo
DROP TABLE t1;
DROP TABLE t2;
DROP FUNCTION f1;
--echo
###########################################################################
#
# Bug#31226: Group by function crashes mysql.
#
###########################################################################
--echo #
--echo # Bug#31226.
--echo #
--echo
--echo #
--echo # - Prepare.
--echo #
--echo
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
--echo
--echo #
--echo # - Create required objects.
--echo #
--echo
CREATE TABLE t1(id INT);
--echo
INSERT INTO t1 VALUES (1), (2), (3);
--echo
CREATE FUNCTION f1()
RETURNS DATETIME
NOT DETERMINISTIC NO SQL
RETURN NOW();
--echo
--echo #
--echo # - Check.
--echo #
--echo
--replace_column 1 <timestamp>
SELECT f1() FROM t1 GROUP BY 1;
--echo
--echo #
--echo # - Cleanup.
--echo #
--echo
DROP TABLE t1;
DROP FUNCTION f1;
--echo
###########################################################################
#
# Bug#28318 (CREATE FUNCTION (UDF) requires a schema)
#
--disable_warnings
DROP PROCEDURE IF EXISTS db28318_a.t1;
DROP PROCEDURE IF EXISTS db28318_b.t2;
DROP DATABASE IF EXISTS db28318_a;
DROP DATABASE IF EXISTS db28318_b;
--enable_warnings
CREATE DATABASE db28318_a;
CREATE DATABASE db28318_b;
CREATE PROCEDURE db28318_a.t1() SELECT "db28318_a.t1";
CREATE PROCEDURE db28318_b.t2() CALL t1();
use db28318_a;
# In db28318_b.t2, t1 refers to db28318_b.t1
--error ER_SP_DOES_NOT_EXIST
CALL db28318_b.t2();
DROP PROCEDURE db28318_a.t1;
DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
use test;
###########################################################################
--echo End of 5.0 tests
###########################################################################
#
# Bug#20550: Stored function: wrong RETURN type metadata when used in a VIEW.
#
###########################################################################
--echo
--echo #
--echo # Bug#20550.
--echo #
--echo
--echo #
--echo # - Prepare.
--echo #
--echo
--disable_warnings
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
--enable_warnings
--echo
--echo #
--echo # - Create required objects.
--echo #
--echo
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
--echo
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
--echo
CREATE VIEW v1 AS SELECT f1();
--echo
CREATE VIEW v2 AS SELECT f2();
--echo
--echo #
--echo # - Check.
--echo #
--echo
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
--echo
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
--echo
--echo #
--echo # - Cleanup.
--echo #
--echo
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1;
DROP VIEW v2;
--echo
###########################################################################
#
# Bug#24923: Functions with ENUM issues.
#
###########################################################################
--echo #
--echo # - Bug#24923: prepare.
--echo #
--echo
--disable_warnings
DROP FUNCTION IF EXISTS f1;
--enable_warnings
--echo
--echo #
--echo # - Bug#24923: create required objects.
--echo #
--echo
delimiter |;
CREATE FUNCTION f1(p INT)
RETURNS ENUM ('Very_long_enum_element_identifier',
'Another_very_long_enum_element_identifier')
BEGIN
CASE p
WHEN 1 THEN
RETURN 'Very_long_enum_element_identifier';
ELSE
RETURN 'Another_very_long_enum_element_identifier';
END CASE;
END|
delimiter ;|
--echo
--echo #
--echo # - Bug#24923: check.
--echo #
--echo
SELECT f1(1);
--echo
SELECT f1(2);
--echo
SHOW CREATE FUNCTION f1;
--echo #
--echo # - Bug#24923: cleanup.
--echo #
--echo
DROP FUNCTION f1;
--echo
###########################################################################
--echo End of 5.1 tests

View file

@ -113,11 +113,11 @@ DROP TABLE bug19904;
# Bug#21269: DEFINER-clause is allowed for UDF-functions
#
--error ER_WRONG_USAGE
--error ER_PARSE_ERROR
CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
RETURNS STRING SONAME "should_not_parse.so";
--error ER_WRONG_USAGE
--error ER_PARSE_ERROR
CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
RETURNS STRING SONAME "should_not_parse.so";
#
@ -206,10 +206,11 @@ DROP FUNCTION IF EXISTS metaphon;
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
# this currently passes, and eclipse the stored function
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
--error ER_UDF_EXISTS
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
DROP FUNCTION metaphon;
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
@ -363,6 +364,20 @@ drop table t1;
drop function metaphon;
set GLOBAL query_cache_size=default;
#
# Bug#28318 CREATE FUNCTION (UDF) requires a schema
#
--disable_warnings
DROP DATABASE IF EXISTS mysqltest;
--enable_warnings
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
USE test;
#
# Bug #29804 UDF parameters don't contain correct string length

View file

@ -1,5 +1,10 @@
-- source include/not_embedded.inc
# Temporary disabled on windows,
# because of --exec mkdir
# TODO: implement Bug#31004 and remove this limitation
--source include/not_windows.inc
--disable_warnings
drop database if exists `mysqltest1`;
drop database if exists `mysqltest-1`;
@ -56,3 +61,33 @@ system cp $MYSQL_TEST_DIR/std_data/old_table-323.frm $MYSQLTEST_VARDIR/master-da
truncate t1;
drop table t1;
#
# Bug#28360 (RENAME DATABASE destroys routines)
#
--disable_warnings
drop database if exists `tabc`;
drop database if exists `a-b-c`;
--enable_warnings
create database `tabc` default character set latin2;
create table tabc.t1 (a int);
FLUSH TABLES;
# Manually make a 5.0 database from the template
--exec mkdir $MYSQLTEST_VARDIR/master-data/a-b-c
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/db.opt $MYSQLTEST_VARDIR/master-data/a-b-c/db.opt
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.frm $MYSQLTEST_VARDIR/master-data/a-b-c/t1.frm
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYD $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYD
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYI $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYI
show databases like '%a-b-c%';
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
# The physical directory name is now a@002db@002dc, the logical name still a-b-c
show databases like '%a-b-c%';
show create database `a-b-c`;
show tables in `a-b-c`;
show create table `a-b-c`.`t1`;
drop database `a-b-c`;
drop database `tabc`;

View file

@ -40,6 +40,29 @@ void win_pthread_init(void)
pthread_mutex_init(&THR_LOCK_thread,MY_MUTEX_INIT_FAST);
}
/**
Adapter to @c pthread_mutex_trylock()
@retval 0 Mutex was acquired
@retval EBUSY Mutex was already locked by a thread
*/
int
win_pthread_mutex_trylock(pthread_mutex_t *mutex)
{
if (TryEnterCriticalSection(mutex))
{
/* Don't allow recursive lock */
if (mutex->RecursionCount > 1){
LeaveCriticalSection(mutex);
return EBUSY;
}
return 0;
}
return EBUSY;
}
/*
** We have tried to use '_beginthreadex' instead of '_beginthread' here
** but in this case the program leaks about 512 characters for each

View file

@ -91,7 +91,7 @@ int safe_mutex_init(safe_mutex_t *mp,
}
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line)
{
int error;
if (!mp->file)
@ -104,15 +104,50 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
}
pthread_mutex_lock(&mp->global);
if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
if (mp->count > 0)
{
fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d in thread %s\n",
file,line,mp->file, mp->line, my_thread_name());
fflush(stderr);
abort();
if (try_lock)
{
pthread_mutex_unlock(&mp->global);
return EBUSY;
}
else if (pthread_equal(pthread_self(),mp->thread))
{
fprintf(stderr,
"safe_mutex: Trying to lock mutex at %s, line %d, when the"
" mutex was already locked at %s, line %d in thread %s\n",
file,line,mp->file, mp->line, my_thread_name());
fflush(stderr);
abort();
}
}
pthread_mutex_unlock(&mp->global);
error=pthread_mutex_lock(&mp->mutex);
/*
If we are imitating trylock(), we need to take special
precautions.
- We cannot use pthread_mutex_lock() only since another thread can
overtake this thread and take the lock before this thread
causing pthread_mutex_trylock() to hang. In this case, we should
just return EBUSY. Hence, we use pthread_mutex_trylock() to be
able to return immediately.
- We cannot just use trylock() and continue execution below, since
this would generate an error and abort execution if the thread
was overtaken and trylock() returned EBUSY . In this case, we
instead just return EBUSY, since this is the expected behaviour
of trylock().
*/
if (try_lock)
{
error= pthread_mutex_trylock(&mp->mutex);
if (error == EBUSY)
return error;
}
else
error= pthread_mutex_lock(&mp->mutex);
if (error || (error=pthread_mutex_lock(&mp->global)))
{
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",

View file

@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';

View file

@ -344,6 +344,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
'MODIFIES_SQL_DATA'
) DEFAULT 'CONTAINS_SQL' NOT NULL,
MODIFY body longblob NOT NULL,
MODIFY returns longblob NOT NULL,
MODIFY sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',

View file

@ -4459,12 +4459,14 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
else
field= new Field_blob(max_length, maybe_null, name, collation.collation);
break; // Blob handled outside of case
#ifdef HAVE_SPATIAL
case MYSQL_TYPE_GEOMETRY:
field= new Field_geom(max_length, maybe_null, name, table->s,
(Field::geometry_type)
((type() == Item::TYPE_HOLDER) ?
((Item_type_holder *)this)->get_geometry_type() :
((Item_geometry_func *)this)->get_geometry_type()));
#endif /* HAVE_SPATIAL */
}
if (field)
field->init(table);
@ -6588,10 +6590,12 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
if (Field::result_merge_type(fld_type) == INT_RESULT)
decimals= 0;
prev_decimal_int_part= item->decimal_int_part();
#ifdef HAVE_SPATIAL
if (item->field_type() == MYSQL_TYPE_GEOMETRY)
geometry_type= (item->type() == Item::FIELD_ITEM) ?
((Item_field *)item)->get_geometry_type() :
(Field::geometry_type)((Item_geometry_func *)item)->get_geometry_type();
#endif /* HAVE_SPATIAL */
}

View file

@ -2326,6 +2326,25 @@ Item*
Create_qfunc::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
LEX_STRING db;
if (! thd->db && ! thd->lex->sphead)
{
/*
The proper error message should be in the lines of:
Can't resolve <name>() to a function call,
because this function:
- is not a native function,
- is not a user defined function,
- can not match a qualified (read: stored) function
since no database is selected.
Reusing ER_SP_DOES_NOT_EXIST have a message consistent with
the case when a default database exist, see Create_sp_func::create().
*/
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
"FUNCTION", name.str);
return NULL;
}
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;

View file

@ -5592,8 +5592,13 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
}
if (!m_sp->m_chistics->detistic)
used_tables_cache |= RAND_TABLE_BIT;
{
used_tables_cache |= RAND_TABLE_BIT;
const_item_cache= FALSE;
}
DBUG_RETURN(res);
}
@ -5601,8 +5606,12 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
void Item_func_sp::update_used_tables()
{
Item_func::update_used_tables();
if (!m_sp->m_chistics->detistic)
used_tables_cache |= RAND_TABLE_BIT;
{
used_tables_cache |= RAND_TABLE_BIT;
const_item_cache= FALSE;
}
}

View file

@ -1535,6 +1535,11 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec(void);
bool is_expensive() { return 1; }
inline Field *get_sp_result_field()
{
return sp_result_field;
}
};

View file

@ -387,10 +387,15 @@ bool Log_to_csv_event_handler::
if (table->field[1]->store(user_host, user_host_len, client_cs) ||
table->field[2]->store((longlong) thread_id, TRUE) ||
table->field[3]->store((longlong) server_id, TRUE) ||
table->field[4]->store(command_type, command_type_len, client_cs) ||
table->field[5]->store(sql_text, sql_text_len, client_cs))
table->field[4]->store(command_type, command_type_len, client_cs))
goto err;
/*
A positive return value in store() means truncation.
Still logging a message in the log in this case.
*/
if (table->field[5]->store(sql_text, sql_text_len, client_cs) < 0)
goto err;
/* mark all fields as not null */
table->field[1]->set_notnull();
@ -407,19 +412,14 @@ bool Log_to_csv_event_handler::
/* log table entries are not replicated */
if (table->file->ha_write_row(table->record[0]))
{
struct tm start;
localtime_r(&event_time, &start);
sql_print_error("%02d%02d%02d %2d:%02d:%02d - Failed to write to mysql.general_log",
start.tm_year % 100, start.tm_mon + 1,
start.tm_mday, start.tm_hour,
start.tm_min, start.tm_sec);
}
goto err;
result= FALSE;
err:
if (result)
sql_print_error("Failed to write to mysql.general_log");
if (need_rnd_end)
{
table->file->ha_rnd_end();
@ -595,25 +595,24 @@ bool Log_to_csv_event_handler::
goto err;
table->field[9]->set_notnull();
/* sql_text */
if (table->field[10]->store(sql_text,sql_text_len, client_cs))
/*
Column sql_text.
A positive return value in store() means truncation.
Still logging a message in the log in this case.
*/
if (table->field[10]->store(sql_text, sql_text_len, client_cs) < 0)
goto err;
/* log table entries are not replicated */
if (table->file->ha_write_row(table->record[0]))
{
struct tm start;
localtime_r(&current_time, &start);
sql_print_error("%02d%02d%02d %2d:%02d:%02d - Failed to write to mysql.slow_log",
start.tm_year % 100, start.tm_mon + 1,
start.tm_mday, start.tm_hour,
start.tm_min, start.tm_sec);
}
goto err;
result= FALSE;
err:
if (result)
sql_print_error("Failed to write to mysql.slow_log");
if (need_rnd_end)
{
table->file->ha_rnd_end();
@ -945,73 +944,65 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
return error;
}
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
const char *format, va_list args)
bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
const char *query, uint query_length)
{
bool error= FALSE;
Log_event_handler **current_handler= general_log_handler_list;
char user_host_buff[MAX_USER_HOST_SIZE];
Security_context *sctx= thd->security_ctx;
ulong id;
uint user_host_len= 0;
time_t current_time;
/*
Print the message to the buffer if we have at least one log event handler
enabled and want to log this king of commands
*/
if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
if (thd)
id= thd->thread_id; /* Normal thread */
else
id= 0; /* Log from connect handler */
lock_shared();
if (!opt_log)
{
char message_buff[MAX_LOG_BUFFER_SIZE];
char user_host_buff[MAX_USER_HOST_SIZE];
Security_context *sctx= thd->security_ctx;
ulong id;
uint message_buff_len= 0, user_host_len= 0;
time_t current_time;
if (thd)
{ /* Normal thread */
if ((thd->options & OPTION_LOG_OFF)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
&& (sctx->master_access & SUPER_ACL)
#endif
)
{
return 0; /* No logging */
}
id= thd->thread_id;
}
else
id=0; /* Log from connect handler */
lock_shared();
if (!opt_log)
{
unlock();
return 0;
}
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff;
/* prepare message */
if (format)
message_buff_len= my_vsnprintf(message_buff,
sizeof(message_buff), format, args);
else
message_buff[0]= '\0';
current_time= my_time(0);
while (*current_handler)
error+= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
user_host_len, id,
command_name[(uint) command].str,
command_name[(uint) command].length,
message_buff, message_buff_len,
thd->variables.character_set_client) || error;
unlock();
return 0;
}
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff;
current_time= my_time(0);
while (*current_handler)
error+= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
user_host_len, id,
command_name[(uint) command].str,
command_name[(uint) command].length,
query, query_length,
thd->variables.character_set_client) || error;
unlock();
return error;
}
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
const char *format, va_list args)
{
uint message_buff_len= 0;
char message_buff[MAX_LOG_BUFFER_SIZE];
/* prepare message */
if (format)
message_buff_len= my_vsnprintf(message_buff, sizeof(message_buff),
format, args);
else
message_buff[0]= '\0';
return general_log_write(thd, command, message_buff, message_buff_len);
}
void LOGGER::init_error_log(uint error_log_printer)
{
if (error_log_printer & LOG_NONE)
@ -2076,10 +2067,10 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
if (my_b_write(&log_file, (uchar*) buff, buff_len))
tmp_errno= errno;
}
if (my_b_printf(&log_file, "# User@Host: ", sizeof("# User@Host: ") - 1)
!= sizeof("# User@Host: ") - 1)
const uchar uh[]= "# User@Host: ";
if (my_b_write(&log_file, uh, sizeof(uh) - 1))
tmp_errno= errno;
if (my_b_printf(&log_file, user_host, user_host_len) != user_host_len)
if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
tmp_errno= errno;
if (my_b_write(&log_file, (uchar*) "\n", 1))
tmp_errno= errno;
@ -3737,12 +3728,44 @@ bool slow_log_print(THD *thd, const char *query, uint query_length,
}
bool LOGGER::log_command(THD *thd, enum enum_server_command command)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *sctx= thd->security_ctx;
#endif
/*
Log command if we have at least one log event handler enabled and want
to log this king of commands
*/
if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
{
if ((thd->options & OPTION_LOG_OFF)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
&& (sctx->master_access & SUPER_ACL)
#endif
)
{
/* No logging */
return FALSE;
}
return TRUE;
}
return FALSE;
}
bool general_log_print(THD *thd, enum enum_server_command command,
const char *format, ...)
{
va_list args;
uint error= 0;
/* Print the message to the buffer if we want to log this king of commands */
if (! logger.log_command(thd, command))
return FALSE;
va_start(args, format);
error= logger.general_log_print(thd, command, format, args);
va_end(args);
@ -3750,6 +3773,16 @@ bool general_log_print(THD *thd, enum enum_server_command command,
return error;
}
bool general_log_write(THD *thd, enum enum_server_command command,
const char *query, uint query_length)
{
/* Write the message to the log if we want to log this king of commands */
if (logger.log_command(thd, command))
return logger.general_log_write(thd, command, query, query_length);
return FALSE;
}
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
{
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))

View file

@ -499,6 +499,8 @@ public:
void lock_exclusive() { rw_wrlock(&LOCK_logger); }
void unlock() { rw_unlock(&LOCK_logger); }
bool is_log_table_enabled(uint log_table_type);
bool log_command(THD *thd, enum enum_server_command command);
/*
We want to initialize all log mutexes as soon as possible,
but we cannot do it in constructor, as safe_mutex relies on
@ -518,6 +520,8 @@ public:
ulonglong current_utime);
bool general_log_print(THD *thd,enum enum_server_command command,
const char *format, va_list args);
bool general_log_write(THD *thd, enum enum_server_command command,
const char *query, uint query_length);
/* we use this function to setup all enabled log event handlers */
int set_handlers(uint error_log_printer,

View file

@ -2113,7 +2113,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query);
/* If the query was not ignored, it is printed to the general log */
if (thd->net.last_errno != ER_SLAVE_IGNORED_TABLE)
general_log_print(thd, COM_QUERY, "%s", thd->query);
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
compare_errors:

View file

@ -745,6 +745,9 @@ bool slow_log_print(THD *thd, const char *query, uint query_length,
bool general_log_print(THD *thd, enum enum_server_command command,
const char *format,...);
bool general_log_write(THD *thd, enum enum_server_command command,
const char *query, uint query_length);
#include "sql_class.h"
#include "sql_acl.h"
#include "tztime.h"
@ -922,13 +925,12 @@ void decrease_user_connections(USER_CONN *uc);
void thd_init_client_charset(THD *thd, uint cs_number);
bool setup_connection_thread_globals(THD *thd);
bool login_connection(THD *thd);
void prepare_new_connection_state(THD* thd);
void end_connection(THD *thd);
bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db);
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
void mysql_client_binlog_statement(THD *thd);
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,

View file

@ -123,7 +123,7 @@ my_bool my_net_init(NET *net, Vio* vio)
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
net->no_send_ok= net->no_send_eof= net->no_send_error= 0;
net->no_send_ok= net->no_send_error= 0;
net->error=0; net->return_errno=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;

View file

@ -346,7 +346,7 @@ send_eof(THD *thd)
{
NET *net= &thd->net;
DBUG_ENTER("send_eof");
if (net->vio != 0 && !net->no_send_eof)
if (net->vio != 0)
{
write_eof_packet(thd, net);
VOID(net_flush(net));

View file

@ -6109,3 +6109,6 @@ ER_EVENT_INVALID_CREATION_CTX
ER_TRG_CANT_OPEN_TABLE
eng "Cannot open table for trigger `%-.64s`.`%-.64s`"
ER_CANT_CREATE_SROUTINE
eng "Cannot create stored routine `%-.64s`. Check warnings"

144
sql/sp.cc
View file

@ -682,6 +682,10 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
enum_check_fields saved_count_cuted_fields;
bool store_failed= FALSE;
DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
sp->m_name.str));
@ -696,6 +700,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
*/
thd->clear_current_stmt_binlog_row_based();
saved_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_WARN;
if (!(table= open_proc_table_for_update(thd)))
ret= SP_OPEN_TABLE_FAILED;
else
@ -725,43 +732,77 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
ret= SP_BODY_TOO_LONG;
goto done;
}
table->field[MYSQL_PROC_FIELD_DB]->
store(sp->m_db.str, sp->m_db.length, system_charset_info);
table->field[MYSQL_PROC_FIELD_NAME]->
store(sp->m_name.str, sp->m_name.length, system_charset_info);
table->field[MYSQL_PROC_MYSQL_TYPE]->
store((longlong)type, TRUE);
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
store(sp->m_name.str, sp->m_name.length, system_charset_info);
store_failed=
table->field[MYSQL_PROC_FIELD_DB]->
store(sp->m_db.str, sp->m_db.length, system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_NAME]->
store(sp->m_name.str, sp->m_name.length, system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_MYSQL_TYPE]->
store((longlong)type, TRUE);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
store(sp->m_name.str, sp->m_name.length, system_charset_info);
if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
table->field[MYSQL_PROC_FIELD_ACCESS]->
store((longlong)sp->m_chistics->daccess, TRUE);
table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
{
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_ACCESS]->
store((longlong)sp->m_chistics->daccess, TRUE);
}
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID)
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
store((longlong)sp->m_chistics->suid, TRUE);
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
store(sp->m_params.str, sp->m_params.length, system_charset_info);
{
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
store((longlong)sp->m_chistics->suid, TRUE);
}
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
store(sp->m_params.str, sp->m_params.length, system_charset_info);
if (sp->m_type == TYPE_ENUM_FUNCTION)
{
String retstr(64);
sp_returns_type(thd, retstr, sp);
table->field[MYSQL_PROC_FIELD_RETURNS]->
store(retstr.ptr(), retstr.length(), system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_RETURNS]->
store(retstr.ptr(), retstr.length(), system_charset_info);
}
table->field[MYSQL_PROC_FIELD_BODY]->
store(sp->m_body.str, sp->m_body.length, system_charset_info);
table->field[MYSQL_PROC_FIELD_DEFINER]->
store(definer, (uint)strlen(definer), system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_BODY]->
store(sp->m_body.str, sp->m_body.length, system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_DEFINER]->
store(definer, (uint)strlen(definer), system_charset_info);
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
table->field[MYSQL_PROC_FIELD_SQL_MODE]->
store((longlong)thd->variables.sql_mode, TRUE);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SQL_MODE]->
store((longlong)thd->variables.sql_mode, TRUE);
if (sp->m_chistics->comment.str)
table->field[MYSQL_PROC_FIELD_COMMENT]->
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info);
{
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_COMMENT]->
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info);
}
if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open())
@ -794,24 +835,34 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
}
table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
thd->charset()->csname,
strlen(thd->charset()->csname),
system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
thd->charset()->csname,
strlen(thd->charset()->csname),
system_charset_info);
table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull();
table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
thd->variables.collation_connection->name,
strlen(thd->variables.collation_connection->name),
system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
thd->variables.collation_connection->name,
strlen(thd->variables.collation_connection->name),
system_charset_info);
table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull();
table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
db_cs->name, strlen(db_cs->name), system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
db_cs->name, strlen(db_cs->name), system_charset_info);
table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull();
table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
if (store_failed)
{
ret= SP_FLD_STORE_FAILED;
goto done;
}
ret= SP_OK;
if (table->file->ha_write_row(table->record[0]))
@ -842,6 +893,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
}
done:
thd->count_cuted_fields= saved_count_cuted_fields;
close_thread_tables(thd);
DBUG_RETURN(ret);
}
@ -1591,12 +1644,12 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
{
Sroutine_hash_entry *rn=
(Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry) +
key->length);
key->length + 1);
if (!rn) // OOM. Error will be reported using fatal_error().
return FALSE;
rn->key.length= key->length;
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
memcpy(rn->key.str, key->str, key->length);
memcpy(rn->key.str, key->str, key->length + 1);
my_hash_insert(&lex->sroutines, (uchar *)rn);
lex->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
rn->belong_to_view= belong_to_view;
@ -1779,7 +1832,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
{
sp_name name(rt->key.str, rt->key.length);
sp_name name(thd, rt->key.str, rt->key.length);
int type= rt->key.str[0];
sp_head *sp;
@ -1787,13 +1840,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
&thd->sp_func_cache : &thd->sp_proc_cache),
&name)))
{
name.m_name.str= strchr(name.m_qname.str, '.');
name.m_db.length= name.m_name.str - name.m_qname.str;
name.m_db.str= strmake_root(thd->mem_root, name.m_qname.str,
name.m_db.length);
name.m_name.str+= 1;
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
switch ((ret= db_find_routine(thd, type, &name, &sp)))
{
case SP_OK:

View file

@ -29,6 +29,7 @@
#define SP_NO_DB_ERROR -8
#define SP_BAD_IDENTIFIER -9
#define SP_BODY_TOO_LONG -10
#define SP_FLD_STORE_FAILED -11
/* Drop all routines in database 'db' */
int

View file

@ -386,17 +386,43 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
*
*/
sp_name::sp_name(THD *thd, char *key, uint key_len)
{
m_sroutines_key.str= key;
m_sroutines_key.length= key_len;
m_qname.str= ++key;
m_qname.length= key_len - 1;
if ((m_name.str= strchr(m_qname.str, '.')))
{
m_db.length= m_name.str - key;
m_db.str= strmake_root(thd->mem_root, key, m_db.length);
m_name.str++;
m_name.length= m_qname.length - m_db.length - 1;
}
else
{
m_name.str= m_qname.str;
m_name.length= m_qname.length;
m_db.str= 0;
m_db.length= 0;
}
m_explicit_name= false;
}
void
sp_name::init_qname(THD *thd)
{
m_sroutines_key.length= m_db.length + m_name.length + 2;
const uint dot= !!m_db.length;
/* m_sroutines format: m_type + [database + dot] + name + nul */
m_sroutines_key.length= 1 + m_db.length + dot + m_name.length;
if (!(m_sroutines_key.str= (char*) thd->alloc(m_sroutines_key.length + 1)))
return;
m_qname.length= m_sroutines_key.length - 1;
m_qname.str= m_sroutines_key.str + 1;
sprintf(m_qname.str, "%.*s.%.*s",
(int) m_db.length, (m_db.length ? m_db.str : ""),
(int) m_name.length, m_name.str);
sprintf(m_qname.str, "%.*s%.*s%.*s",
(int) m_db.length, (m_db.length ? m_db.str : ""),
dot, ".",
(int) m_name.length, m_name.str);
}
@ -2699,7 +2725,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
query= thd->query;
query_length= thd->query_length;
if (!(res= alloc_query(thd, m_query.str, m_query.length+1)) &&
if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
!(res=subst_spvars(thd, this, &m_query)))
{
/*
@ -2707,7 +2733,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
queries with SP vars can't be cached)
*/
if (unlikely((thd->options & OPTION_LOG_OFF)==0))
general_log_print(thd, COM_QUERY, "%s", thd->query);
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
if (query_cache_send_result_to_client(thd,
thd->query, thd->query_length) <= 0)

View file

@ -129,16 +129,7 @@ public:
Creates temporary sp_name object from key, used mainly
for SP-cache lookups.
*/
sp_name(char *key, uint key_len)
{
m_sroutines_key.str= key;
m_sroutines_key.length= key_len;
m_name.str= m_qname.str= key + 1;
m_name.length= m_qname.length= key_len - 1;
m_db.str= 0;
m_db.length= 0;
m_explicit_name= false;
}
sp_name(THD *thd, char *key, uint key_len);
// Init. the qualified name from the db and name.
void init_qname(THD *thd); // thd for memroot allocation

View file

@ -2466,7 +2466,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(0);
}
/* close handler tables which are marked for flush */
/*
In order for the back off and re-start process to work properly,
handler tables having old versions (due to FLUSH TABLES or pending
name-lock) MUST be closed. This is specially important if a name-lock
is pending for any table of the handler_tables list, otherwise a
deadlock may occur.
*/
if (thd->handler_tables)
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
@ -2533,6 +2539,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->db_stat == 0 signals wait_for_locked_table_names
that the tables in question are not used any more. See
table_is_used call for details.
Notice that HANDLER tables were already taken care of by
the earlier call to mysql_ha_flush() in this same critical
section.
*/
close_old_data_files(thd,thd->open_tables,0,0);
/*

View file

@ -3240,7 +3240,7 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
for (; tables_used; tables_used= tables_used->next_global)
{
table_count++;
#ifdef HAVE_QUERY_CACHE
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
Disable any attempt to store this statement if there are
column level grants on any referenced tables.

View file

@ -585,6 +585,12 @@ void THD::init(void)
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
options= thd_startup_options;
if (variables.max_join_size == HA_POS_ERROR)
options |= OPTION_BIG_SELECTS;
else
options &= ~OPTION_BIG_SELECTS;
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE;
open_options=ha_open_options;
update_lock_default= (variables.low_priority_updates ?
@ -692,6 +698,7 @@ void THD::cleanup(void)
pthread_mutex_lock(&LOCK_user_locks);
item_user_lock_release(ull);
pthread_mutex_unlock(&LOCK_user_locks);
ull= NULL;
}
cleanup_done=1;
@ -1416,7 +1423,14 @@ bool select_to_file::send_eof()
if (my_close(file,MYF(MY_WME)))
error= 1;
if (!error)
{
/*
In order to remember the value of affected rows for ROW_COUNT()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
::send_ok(thd,row_count);
}
file= -1;
return error;
}
@ -2331,6 +2345,11 @@ bool select_dumpvar::send_eof()
if (! row_count)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
/*
In order to remember the value of affected rows for ROW_COUNT()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
::send_ok(thd,row_count);
return 0;
}

View file

@ -2133,6 +2133,10 @@ class select_create: public select_insert {
TABLE_LIST *select_tables;
Alter_info *alter_info;
Field **field;
/* lock data for tmp table */
MYSQL_LOCK *m_lock;
/* m_lock or thd->extra_lock */
MYSQL_LOCK **m_plock;
public:
select_create (TABLE_LIST *table_arg,
HA_CREATE_INFO *create_info_par,
@ -2143,7 +2147,8 @@ public:
create_table(table_arg),
create_info(create_info_par),
select_tables(select_tables_arg),
alter_info(alter_info_arg)
alter_info(alter_info_arg),
m_plock(NULL)
{}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);

View file

@ -933,7 +933,7 @@ bool login_connection(THD *thd)
NET *net= &thd->net;
Security_context *sctx= thd->security_ctx;
DBUG_ENTER("login_connection");
DBUG_PRINT("info", ("handle_one_connection called by thread %lu",
DBUG_PRINT("info", ("login_connection called by thread %lu",
thd->thread_id));
net->no_send_error= 0;
@ -973,21 +973,29 @@ void end_connection(THD *thd)
plugin_thdvar_cleanup(thd);
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
if (thd->killed ||
net->error && net->vio != 0 && net->report_error)
{
statistic_increment(aborted_threads,&LOCK_status);
}
if (net->error && net->vio != 0 && net->report_error)
{
Security_context *sctx= thd->security_ctx;
if (!thd->killed && thd->variables.log_warnings > 1)
{
Security_context *sctx= thd->security_ctx;
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip,
(net->last_errno ? ER(net->last_errno) :
ER(ER_UNKNOWN_ERROR)));
}
net_send_error(thd, net->last_errno, NullS);
statistic_increment(aborted_threads,&LOCK_status);
}
else if (thd->killed)
statistic_increment(aborted_threads,&LOCK_status);
}
@ -995,7 +1003,7 @@ void end_connection(THD *thd)
Initialize THD to handle queries
*/
void prepare_new_connection_state(THD* thd)
static void prepare_new_connection_state(THD* thd)
{
Security_context *sctx= thd->security_ctx;

View file

@ -1727,41 +1727,21 @@ lock_databases(THD *thd, const char *db1, uint length1,
}
/*
Rename database.
/**
Upgrade a 5.0 database.
This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
SYNOPSIS
mysql_rename_db()
thd Thread handler
olddb Old database name
newdb New database name
If we have managed to rename (move) tables to the new database
but something failed on a later step, then we store the
RENAME DATABASE event in the log. mysql_rename_db() is atomic in
the sense that it will rename all or none of the tables.
DESCRIPTION
This function is invoked whenever a RENAME DATABASE query is executed:
RENAME DATABASE 'olddb' TO 'newdb'.
NOTES
If we have managed to rename (move) tables to the new database
but something failed on a later step, then we store the
RENAME DATABASE event in the log. mysql_rename_db() is atomic in
the sense that it will rename all or none of the tables.
TODO:
- Better trigger, stored procedure, event, grant handling,
see the comments below.
NOTE: It's probably a good idea to call wait_if_global_read_lock()
once in mysql_rename_db(), instead of locking inside all
the required functions for renaming triggerts, SP, events, grants, etc.
RETURN VALUES
0 ok
1 error
@param thd Current thread
@param old_db 5.0 database name, in #mysql50#name format
@return 0 on success, 1 on error
*/
bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
{
int error= 0, change_to_newdb= 0;
char path[FN_REFLEN+16];
@ -1770,11 +1750,27 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
MY_DIR *dirp;
TABLE_LIST *table_list;
SELECT_LEX *sl= thd->lex->current_select;
DBUG_ENTER("mysql_rename_db");
LEX_STRING new_db;
DBUG_ENTER("mysql_upgrade_db");
if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
(strncmp(old_db->str,
MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
{
my_error(ER_WRONG_USAGE, MYF(0),
"ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
"name");
DBUG_RETURN(1);
}
/* `#mysql50#<name>` converted to encoded `<name>` */
new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
if (lock_databases(thd, old_db->str, old_db->length,
new_db->str, new_db->length))
return 1;
new_db.str, new_db.length))
DBUG_RETURN(1);
/*
Let's remember if we should do "USE newdb" afterwards.
@ -1798,7 +1794,7 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
}
/* Step1: Create the new database */
if ((error= mysql_create_db(thd, new_db->str, &create_info, 1)))
if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
goto exit;
/* Step2: Move tables to the new database */
@ -1819,12 +1815,12 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* A frm file found, add the table info rename list */
*extension= '\0';
table_str.length= filename_to_tablename(file->name,
tname, sizeof(tname)-1);
table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
Table_ident *new_ident= new Table_ident(thd, *new_db, table_str, 0);
Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
if (!old_ident || !new_ident ||
!sl->add_table_to_list(thd, old_ident, NULL,
TL_OPTION_UPDATING, TL_IGNORE) ||
@ -1854,9 +1850,9 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
It garantees we never loose any tables.
*/
build_table_filename(path, sizeof(path)-1,
new_db->str,"",MY_DB_OPT_FILE, 0);
new_db.str,"",MY_DB_OPT_FILE, 0);
my_delete(path, MYF(MY_WME));
length= build_table_filename(path, sizeof(path)-1, new_db->str, "", "", 0);
length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
if (length && path[length-1] == FN_LIBCHAR)
path[length-1]=0; // remove ending '\'
rmdir(path);
@ -1910,46 +1906,12 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
build_table_filename(oldname, sizeof(oldname)-1,
old_db->str, "", file->name, 0);
build_table_filename(newname, sizeof(newname)-1,
new_db->str, "", file->name, 0);
new_db.str, "", file->name, 0);
my_rename(oldname, newname, MYF(MY_WME));
}
my_dirend(dirp);
my_dirend(dirp);
}
/*
Step4: TODO: moving stored procedures in the 'proc' system table
We need a new function: sp_move_db_routines(thd, olddb, newdb)
Which will basically have the same effect with:
UPDATE proc SET db='newdb' WHERE db='olddb'
Note, for 5.0 to 5.1 upgrade purposes we don't really need it.
The biggest problem here is that we can't have a lock on LOCK_open() while
calling open_table() for 'proc'.
Two solutions:
- Start by opening the 'event' and 'proc' (and other) tables for write
even before creating the 'to' database. (This will have the nice
effect of blocking another 'rename database' while the lock is active).
- Use the solution "Disable create of new tables during lock table"
For an example of how to read through all rows, see:
sql_help.cc::search_topics()
*/
/*
Step5: TODO: moving events in the 'event' system table
We need a new function evex_move_db_events(thd, olddb, newdb)
Which will have the same effect with:
UPDATE event SET db='newdb' WHERE db='olddb'
Note, for 5.0 to 5.1 upgrade purposes we don't really need it.
*/
/*
Step6: TODO: moving grants in the 'db', 'tables_priv', 'columns_priv'.
Update each grant table, doing the same with:
UPDATE system_table SET db='newdb' WHERE db='olddb'
*/
/*
Step7: drop the old database.
remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
@ -1968,13 +1930,13 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* Step9: Let's do "use newdb" if we renamed the current database */
if (change_to_newdb)
error|= mysql_change_db(thd, new_db, FALSE);
error|= mysql_change_db(thd, & new_db, FALSE);
exit:
pthread_mutex_lock(&LOCK_lock_db);
/* Remove the databases from db lock cache */
lock_db_delete(old_db->str, old_db->length);
lock_db_delete(new_db->str, new_db->length);
lock_db_delete(new_db.str, new_db.length);
creating_database--;
/* Signal waiting CREATE TABLE's to continue */
pthread_cond_signal(&COND_refresh);

View file

@ -142,7 +142,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
send_ok(thd); // No matching records
send_ok(thd, (ha_rows) thd->row_count_func); // No matching records
DBUG_RETURN(0);
}
#endif
@ -159,7 +159,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
delete select;
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
send_ok(thd,0L);
send_ok(thd, (ha_rows) thd->row_count_func);
/*
We don't need to call reset_auto_increment in this case, because
mysql_truncate always gives a NULL conds argument, hence we never
@ -386,7 +386,7 @@ cleanup:
if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
{
thd->row_count_func= deleted;
send_ok(thd,deleted);
send_ok(thd, (ha_rows) thd->row_count_func);
DBUG_PRINT("info",("%ld records deleted",(long) deleted));
}
DBUG_RETURN(error >= 0 || thd->net.report_error);
@ -889,7 +889,7 @@ bool multi_delete::send_eof()
if (!local_error)
{
thd->row_count_func= deleted;
::send_ok(thd, deleted);
::send_ok(thd, (ha_rows) thd->row_count_func);
}
return 0;
}

View file

@ -65,11 +65,6 @@
static enum enum_ha_read_modes rkey_to_rnext[]=
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
#define HANDLER_TABLES_HACK(thd) { \
TABLE *tmp=thd->open_tables; \
thd->open_tables=thd->handler_tables; \
thd->handler_tables=tmp; }
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags);
@ -187,6 +182,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
char *db, *name, *alias;
uint dblen, namelen, aliaslen, counter;
int error;
TABLE *backup_open_tables;
DBUG_ENTER("mysql_ha_open");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
tables->db, tables->table_name, tables->alias,
@ -215,17 +211,38 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
}
}
/*
Save and reset the open_tables list so that open_tables() won't
be able to access (or know about) the previous list. And on return
from open_tables(), thd->open_tables will contain only the opened
table.
The thd->handler_tables list is kept as-is to avoid deadlocks if
open_table(), called by open_tables(), needs to back-off because
of a pending name-lock on the table being opened.
See open_table() back-off comments for more details.
*/
backup_open_tables= thd->open_tables;
thd->open_tables= NULL;
/*
open_tables() will set 'tables->table' if successful.
It must be NULL for a real open when calling open_tables().
*/
DBUG_ASSERT(! tables->table);
HANDLER_TABLES_HACK(thd);
/* for now HANDLER can be used only for real TABLES */
tables->required_type= FRMTYPE_TABLE;
error= open_tables(thd, &tables, &counter, 0);
HANDLER_TABLES_HACK(thd);
/* restore the state and merge the opened table into handler_tables list */
if (thd->open_tables)
{
thd->open_tables->next= thd->handler_tables;
thd->handler_tables= thd->open_tables;
}
thd->open_tables= backup_open_tables;
if (error)
goto err;
@ -351,7 +368,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
{
TABLE_LIST *hash_tables;
TABLE *table;
TABLE *table, *backup_open_tables;
MYSQL_LOCK *lock;
List<Item> list;
Protocol *protocol= thd->protocol;
@ -361,7 +378,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
uint num_rows;
uchar *key;
uint key_len;
bool not_used;
bool need_reopen;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
@ -375,6 +392,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
List_iterator<Item> it(list);
it++;
retry:
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
(uchar*) tables->alias,
strlen(tables->alias) + 1)))
@ -428,9 +446,34 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
tables->table=table;
HANDLER_TABLES_HACK(thd);
lock= mysql_lock_tables(thd, &tables->table, 1, 0, &not_used);
HANDLER_TABLES_HACK(thd);
/* save open_tables state */
backup_open_tables= thd->open_tables;
/*
mysql_lock_tables() needs thd->open_tables to be set correctly to
be able to handle aborts properly. When the abort happens, it's
safe to not protect thd->handler_tables because it won't close any
tables.
*/
thd->open_tables= thd->handler_tables;
lock= mysql_lock_tables(thd, &tables->table, 1,
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
/* restore previous context */
thd->open_tables= backup_open_tables;
if (need_reopen)
{
mysql_ha_close_table(thd, tables);
hash_tables->table= NULL;
/*
The lock might have been aborted, we need to manually reset
thd->some_tables_deleted because handler's tables are closed
in a non-standard way. Otherwise we might loop indefinitely.
*/
thd->some_tables_deleted= 0;
goto retry;
}
if (!lock)
goto err0; // mysql_lock_tables() printed error message already

View file

@ -1639,6 +1639,8 @@ public:
char *record;
enum_duplicates dup;
time_t start_time;
ulong sql_mode;
bool auto_increment_field_not_null;
bool query_start_used, ignore, log_query;
bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
ulonglong first_successful_insert_id_in_prev_stmt;
@ -2141,6 +2143,9 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
/* Copy session variables. */
row->auto_increment_increment= thd->variables.auto_increment_increment;
row->auto_increment_offset= thd->variables.auto_increment_offset;
row->sql_mode= thd->variables.sql_mode;
row->auto_increment_field_not_null= table->auto_increment_field_not_null;
/* Copy the next forced auto increment value, if any. */
if ((forced_auto_inc= thd->auto_inc_intervals_forced.get_next()))
{
@ -2555,10 +2560,13 @@ bool Delayed_insert::handle_inserts(void)
thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
table->timestamp_field_type= row->timestamp_field_type;
table->auto_increment_field_not_null= row->auto_increment_field_not_null;
/* Copy the session variables. */
thd.variables.auto_increment_increment= row->auto_increment_increment;
thd.variables.auto_increment_offset= row->auto_increment_offset;
thd.variables.sql_mode= row->sql_mode;
/* Copy a forced insert_id, if any. */
if (row->forced_insert_id)
{
@ -3419,6 +3427,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
MYSQL_LOCK *extra_lock= NULL;
DBUG_ENTER("select_create::prepare");
TABLEOP_HOOKS *hook_ptr= NULL;
@ -3488,9 +3497,21 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
if (!(table= create_table_from_items(thd, create_info, create_table,
alter_info, &values,
&thd->extra_lock, hook_ptr)))
&extra_lock, hook_ptr)))
DBUG_RETURN(-1); // abort() deletes table
if (extra_lock)
{
DBUG_ASSERT(m_plock == NULL);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
m_plock= &m_lock;
else
m_plock= &thd->extra_lock;
*m_plock= extra_lock;
}
if (table->s->fields < values.elements)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
@ -3629,10 +3650,11 @@ bool select_create::send_eof()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
if (thd->extra_lock)
if (m_plock)
{
mysql_unlock_tables(thd, thd->extra_lock);
thd->extra_lock=0;
mysql_unlock_tables(thd, *m_plock);
*m_plock= NULL;
m_plock= NULL;
}
}
return tmp;
@ -3667,10 +3689,11 @@ void select_create::abort()
if (thd->current_stmt_binlog_row_based)
ha_rollback_stmt(thd);
if (thd->extra_lock)
if (m_plock)
{
mysql_unlock_tables(thd, thd->extra_lock);
thd->extra_lock=0;
mysql_unlock_tables(thd, *m_plock);
*m_plock= NULL;
m_plock= NULL;
}
if (table)

View file

@ -78,7 +78,6 @@ enum enum_sql_command {
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT,
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
SQLCOM_RENAME_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
@ -117,6 +116,7 @@ enum enum_sql_command {
SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS,
SQLCOM_SHOW_CREATE_TRIGGER,
SQLCOM_ALTER_DB_UPGRADE,
/* This should be the last !!! */
@ -1550,7 +1550,6 @@ typedef struct st_lex : public Query_tables_list
required a local context, the parser pops the top-most context.
*/
List<Name_resolution_context> context_stack;
List<LEX_STRING> db_list;
SQL_LIST proc_list, auxiliary_table_list, save_list;
Create_field *last_field;

View file

@ -86,7 +86,6 @@ const char *xa_state_names[]={
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
};
static void unlock_locked_tables(THD *thd)
{
if (thd->locked_tables)
@ -321,8 +320,6 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
values of init_command_var can't be changed
*/
rw_rdlock(var_mutex);
thd->query= init_command_var->value;
thd->query_length= init_command_var->value_length;
save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
/*
@ -332,7 +329,9 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
save_vio= thd->net.vio;
thd->net.vio= 0;
thd->net.no_send_error= 0;
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
dispatch_command(COM_QUERY, thd,
init_command_var->value,
init_command_var->value_length);
rw_unlock(var_mutex);
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
@ -681,40 +680,49 @@ bool do_command(THD *thd)
DBUG_PRINT("info",("Got error %d reading command from socket %s",
net->error,
vio_description(net->vio)));
/* Check if we can continue without closing the connection */
if (net->error != 3)
{
statistic_increment(aborted_threads,&LOCK_status);
DBUG_RETURN(TRUE); // We have to close it.
}
net_send_error(thd, net->last_errno, NullS);
net->error= 0;
DBUG_RETURN(FALSE);
}
else
packet= (char*) net->read_pos;
/*
'packet_length' contains length of data, as it was stored in packet
header. In case of malformed header, my_net_read returns zero.
If packet_length is not zero, my_net_read ensures that the returned
number of bytes was actually read from network.
There is also an extra safety measure in my_net_read:
it sets packet[packet_length]= 0, but only for non-zero packets.
*/
if (packet_length == 0) /* safety */
{
packet=(char*) net->read_pos;
command = (enum enum_server_command) (uchar) packet[0];
if (command >= COM_END)
command= COM_END; // Wrong command
DBUG_PRINT("info",("Command on %s = %d (%s)",
vio_description(net->vio), command,
command_name[command].str));
/* Initialize with COM_SLEEP packet */
packet[0]= (uchar) COM_SLEEP;
packet_length= 1;
}
/* Do not rely on my_net_read, extra safety against programming errors. */
packet[packet_length]= '\0'; /* safety */
command= (enum enum_server_command) (uchar) packet[0];
if (command >= COM_END)
command= COM_END; // Wrong command
DBUG_PRINT("info",("Command on %s = %d (%s)",
vio_description(net->vio), command,
command_name[command].str));
/* Restore read timeout value */
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
/*
packet_length contains length of data, as it was stored in packet
header. In case of malformed header, packet_length can be zero.
If packet_length is not zero, my_net_read ensures that this number
of bytes was actually read from network. Additionally my_net_read
sets packet[packet_length]= 0 (thus if packet_length == 0,
command == packet[0] == COM_SLEEP).
In dispatch_command packet[packet_length] points beyond the end of packet.
*/
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
DBUG_ASSERT(packet_length);
DBUG_RETURN(dispatch_command(command, thd, packet+1, (uint) (packet_length-1)));
}
#endif /* EMBEDDED_LIBRARY */
@ -727,9 +735,7 @@ bool do_command(THD *thd)
thd connection handle
command type of command to perform
packet data for the command, packet is always null-terminated
packet_length length of packet + 1 (to show that data is
null-terminated) except for COM_SLEEP, where it
can be zero.
packet_length length of packet. Can be zero, e.g. in case of COM_SLEEP.
RETURN VALUE
0 ok
1 request of thread shutdown, i. e. if command is
@ -773,10 +779,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
LEX_STRING tmp;
status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
thd->convert_string(&tmp, system_charset_info,
packet, packet_length-1, thd->charset());
packet, packet_length, thd->charset());
if (!mysql_change_db(thd, &tmp, FALSE))
{
general_log_print(thd, command, "%s",thd->db);
general_log_write(thd, command, thd->db, thd->db_length);
send_ok(thd);
}
break;
@ -793,14 +799,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
char *tbl_name;
LEX_STRING db;
/* Safe because there is always a trailing \0 at the end of the packet */
uint db_len= *(uchar*) packet;
if (db_len >= packet_length || db_len > NAME_LEN)
if (db_len + 1 > packet_length || db_len > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
/* Safe because there is always a trailing \0 at the end of the packet */
uint tbl_len= *(uchar*) (packet + db_len + 1);
if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN)
if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
@ -823,7 +831,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_CHANGE_USER:
{
status_var_increment(thd->status_var.com_other);
char *user= (char*) packet, *packet_end= packet+ packet_length;
char *user= (char*) packet, *packet_end= packet + packet_length;
/* Safe because there is always a trailing \0 at the end of the packet */
char *passwd= strend(user)+1;
thd->change_user();
@ -840,6 +849,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
char *save_db;
/*
If there is no password supplied, the packet must contain '\0',
in any type of handshake (4.1 or pre-4.1).
*/
if (passwd >= packet_end)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd));
uint dummy_errors, save_db_length, db_length;
@ -848,22 +866,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
USER_CONN *save_user_connect;
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
/* Small check for incoming packet */
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
/*
Database name is always NUL-terminated, so in case of empty database
the packet must contain at least the trailing '\0'.
*/
if (db >= packet_end)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
#endif
db_length= strlen(db);
char *ptr= db + db_length + 1;
uint cs_number= 0;
if (ptr < packet_end)
{
if (ptr + 2 > packet_end)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
cs_number= uint2korr(ptr);
}
/* Convert database name to utf8 */
/*
Handle problem with old bug in client protocol where db had an extra
\0
*/
db_length= (packet_end - db);
if (db_length > 0 && db[db_length-1] == 0)
db_length--;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info, db, db_length,
thd->charset(), &dummy_errors)]= 0;
@ -907,6 +935,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
x_free((uchar*) save_db);
x_free((uchar*) save_security_ctx.user);
if (cs_number)
{
thd_init_client_charset(thd, cs_number);
thd->update_charset();
}
}
break;
}
@ -946,10 +980,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; // fatal error is set
char *packet_end= thd->query + thd->query_length;
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
const char *format= "%.*b";
const char* found_semicolon= NULL;
general_log_print(thd, command, format, thd->query_length, thd->query);
general_log_write(thd, command, thd->query, thd->query_length);
DBUG_PRINT("query",("%-.4096s",thd->query));
if (!(specialflag & SPECIAL_NO_PRIOR))
@ -999,7 +1032,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
#else
{
char *fields, *packet_end= packet + packet_length - 1, *arg_end;
char *fields, *packet_end= packet + packet_length, *arg_end;
/* Locked closure of all tables */
TABLE_LIST table_list;
LEX_STRING conv_name;
@ -1073,7 +1106,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
HA_CREATE_INFO create_info;
status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
if (thd->make_lex_string(&db, packet, packet_length - 1, FALSE) ||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
check_db_name(&db))
{
@ -1094,7 +1127,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
LEX_STRING db;
if (thd->make_lex_string(&db, packet, packet_length - 1, FALSE) ||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
check_db_name(&db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
@ -1108,7 +1141,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
break;
}
general_log_print(thd, command, db.str);
general_log_write(thd, command, db.str, db.length);
mysql_rm_db(thd, db.str, 0, 0);
break;
}
@ -1163,7 +1196,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; /* purecov: inspected */
/*
If the client is < 4.1.3, it is going to send us no argument; then
packet_length is 1, packet[0] is the end 0 of the packet. Note that
packet_length is 0, packet[0] is the end 0 of the packet. Note that
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
packet[0].
*/
@ -1521,9 +1554,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
bool alloc_query(THD *thd, const char *packet, uint packet_length)
{
packet_length--; // Remove end null
/* Remove garbage at start and end of query */
while (my_isspace(thd->charset(),packet[0]) && packet_length > 0)
while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
{
packet++;
packet_length--;
@ -3173,12 +3205,9 @@ end_with_restore_list:
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
break;
}
case SQLCOM_RENAME_DB:
case SQLCOM_ALTER_DB_UPGRADE:
{
LEX_STRING *olddb, *newdb;
List_iterator <LEX_STRING> db_list(lex->db_list);
olddb= db_list++;
newdb= db_list++;
LEX_STRING *db= & lex->name;
if (end_active_trans(thd))
{
res= 1;
@ -3186,24 +3215,22 @@ end_with_restore_list:
}
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(olddb->str) ||
!rpl_filter->db_ok(newdb->str) ||
!rpl_filter->db_ok_with_wild_table(olddb->str) ||
!rpl_filter->db_ok_with_wild_table(newdb->str)))
(!rpl_filter->db_ok(db->str) ||
!rpl_filter->db_ok_with_wild_table(db->str)))
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
if (check_db_name(newdb))
if (check_db_name(db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), newdb->str);
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
break;
}
if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
check_access(thd, DROP_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
check_access(thd, CREATE_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
{
res= 1;
break;
@ -3215,7 +3242,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
res= mysql_rename_db(thd, olddb, newdb);
res= mysql_upgrade_db(thd, db);
if (!res)
send_ok(thd);
break;
@ -3328,12 +3356,6 @@ end_with_restore_list:
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
break;
#ifdef HAVE_DLOPEN
if (sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
&thd->sp_func_cache, FALSE))
{
my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str);
goto error;
}
if (!(res = mysql_create_function(thd, &lex->udf)))
send_ok(thd);
#else
@ -3789,6 +3811,9 @@ end_with_restore_list:
case SP_BODY_TOO_LONG:
my_error(ER_TOO_LONG_BODY, MYF(0), name);
break;
case SP_FLD_STORE_FAILED:
my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
break;
default:
my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
break;
@ -7242,7 +7267,12 @@ bool parse_sql(THD *thd,
/* Parse the query. */
bool err_status= MYSQLparse(thd) != 0 || thd->is_fatal_error;
bool mysql_parse_status= MYSQLparse(thd) != 0;
/* Check that if MYSQLparse() failed, thd->net.report_error is set. */
DBUG_ASSERT(!mysql_parse_status ||
mysql_parse_status && thd->net.report_error);
/* Reset Lex_input_stream. */
@ -7255,7 +7285,7 @@ bool parse_sql(THD *thd,
/* That's it. */
return err_status;
return mysql_parse_status || thd->is_fatal_error;
}
/**

View file

@ -1799,7 +1799,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
case SQLCOM_UNINSTALL_PLUGIN:
case SQLCOM_CREATE_DB:
case SQLCOM_DROP_DB:
case SQLCOM_RENAME_DB:
case SQLCOM_ALTER_DB_UPGRADE:
case SQLCOM_CHECKSUM:
case SQLCOM_CREATE_USER:
case SQLCOM_RENAME_USER:
@ -2107,7 +2107,7 @@ void mysql_sql_stmt_prepare(THD *thd)
DBUG_VOID_RETURN;
}
if (stmt->prepare(query, query_len+1))
if (stmt->prepare(query, query_len))
{
/* Statement map deletes the statement on erase */
thd->stmt_map.erase(stmt);
@ -2270,7 +2270,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
/* Query text for binary, general or slow log, if any of them is open */
String expanded_query;
#ifndef EMBEDDED_LIBRARY
uchar *packet_end= packet + packet_length - 1;
uchar *packet_end= packet + packet_length;
#endif
Prepared_statement *stmt;
bool error;
@ -2585,14 +2585,14 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
Prepared_statement *stmt;
Item_param *param;
#ifndef EMBEDDED_LIBRARY
char *packet_end= packet + packet_length - 1;
char *packet_end= packet + packet_length;
#endif
DBUG_ENTER("mysql_stmt_get_longdata");
status_var_increment(thd->status_var.com_stmt_send_long_data);
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
if (packet_length <= MYSQL_LONG_DATA_HEADER)
if (packet_length < MYSQL_LONG_DATA_HEADER)
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
DBUG_VOID_RETURN;
@ -2866,6 +2866,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
error= parse_sql(thd, &lip, NULL) ||
thd->net.report_error ||
init_param_array(this);
lex->set_trg_event_type_for_tables();
/* Remember the current database. */
@ -2946,12 +2947,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
the general log.
*/
if (thd->spcont == NULL)
{
const char *format= "[%lu] %.*b";
general_log_print(thd, COM_STMT_PREPARE, format, id,
query_length, query);
}
general_log_write(thd, COM_STMT_PREPARE, query, query_length);
}
DBUG_RETURN(error);
}
@ -3059,7 +3055,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (expanded_query->length() &&
alloc_query(thd, (char*) expanded_query->ptr(),
expanded_query->length()+1))
expanded_query->length()))
{
my_error(ER_OUTOFMEMORY, 0, expanded_query->length());
goto error;
@ -3149,11 +3145,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
the general log.
*/
if (error == 0 && thd->spcont == NULL)
{
const char *format= "[%lu] %.*b";
general_log_print(thd, COM_STMT_EXECUTE, format, id,
thd->query_length, thd->query);
}
general_log_write(thd, COM_STMT_EXECUTE, thd->query, thd->query_length);
error:
flags&= ~ (uint) IS_IN_USE;

View file

@ -9343,6 +9343,36 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
}
/* Fall through */
case Item::FUNC_ITEM:
if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
{
Item_func_sp *item_func_sp= (Item_func_sp *) item;
Field *sp_result_field= item_func_sp->get_sp_result_field();
if (make_copy_field)
{
DBUG_ASSERT(item_func_sp->result_field);
*from_field= item_func_sp->result_field;
}
else
{
*((*copy_func)++)= item;
}
Field *result_field=
create_tmp_field_from_field(thd,
sp_result_field,
item_func_sp->name,
table,
NULL,
convert_blob_length);
if (modify_item)
item->set_result_field(result_field);
return result_field;
}
/* Fall through */
case Item::COND_ITEM:
case Item::FIELD_AVG_ITEM:
case Item::FIELD_STD_ITEM:

View file

@ -415,7 +415,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (check_string_char_length(&udf->name, "", NAME_CHAR_LEN,
system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name);
my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name.str);
DBUG_RETURN(1);
}
@ -429,7 +429,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
rw_wrlock(&THR_LOCK_udf);
if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length)))
{
my_error(ER_UDF_EXISTS, MYF(0), udf->name);
my_error(ER_UDF_EXISTS, MYF(0), udf->name.str);
goto err;
}
if (!(dl = find_udf_dl(udf->dl)))

View file

@ -1211,8 +1211,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <cast_type> cast_type
%type <udf_type> udf_func_type
%type <symbol> keyword keyword_sp
%type <lex_user> user grant_user
@ -1254,14 +1252,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use
opt_delete_options opt_delete_option varchar nchar nvarchar
opt_outer table_list table_name table_alias_ref_list table_alias_ref
opt_option opt_place
opt_option opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges grant_ident grant_list grant_option
object_privilege object_privilege_list user_list rename_list
clear_privileges flush_options flush_option
equal optional_braces
opt_mi_check_type opt_to mi_check_types normal_join
db_to_db table_to_table_list table_to_table opt_table_list opt_as
table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
union_clause union_list
@ -1272,14 +1270,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
statement sp_suid
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
definer view_replace_or_algorithm view_replace
view_replace_or_algorithm view_replace
view_algorithm view_or_trigger_or_sp_or_event
view_or_trigger_or_sp_or_event_tail
definer_tail no_definer_tail
view_suid view_tail view_list_opt view_list view_select
view_check_option trigger_tail sp_tail
view_check_option trigger_tail sp_tail sf_tail udf_tail event_tail
install uninstall partition_entry binlog_base64_event
init_key_options key_options key_opts key_opt key_using_alg
server_def server_options_list server_option
definer_opt no_definer definer
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@ -2002,181 +2001,6 @@ sp_name:
}
;
create_function_tail:
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
if (lex->definer != NULL)
{
/*
DEFINER is a concept meaningful when interpreting SQL code.
UDF functions are compiled.
Using DEFINER with UDF has therefore no semantic,
and is considered a parsing error.
*/
my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER");
MYSQL_YYABORT;
}
if (is_native_function(thd, & lex->spname->m_name))
{
my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
lex->spname->m_name.str);
MYSQL_YYABORT;
}
lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.name = lex->spname->m_name;
lex->udf.returns=(Item_result) $2;
lex->udf.dl=$4.str;
}
| '('
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
sp_head *sp;
const char* tmp_param_begin;
/*
First check if AGGREGATE was used, in that case it's a
syntax error.
*/
if (lex->udf.type == UDFTYPE_AGGREGATE)
{
my_error(ER_SP_NO_AGGREGATE, MYF(0));
MYSQL_YYABORT;
}
if (lex->sphead)
{
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
MYSQL_YYABORT;
}
/* Order is important here: new - reset - init */
sp= new sp_head();
sp->reset_thd_mem_root(thd);
sp->init(lex);
sp->init_sp_name(thd, lex->spname);
sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp;
/*
We have to turn off CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
tmp_param_begin= lip->get_cpp_tok_start();
tmp_param_begin++;
lex->sphead->m_param_begin= tmp_param_begin;
}
sp_fdparam_list ')'
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_param_end= lip->get_cpp_tok_start();
}
RETURNS_SYM
{
LEX *lex= Lex;
lex->charset= NULL;
lex->length= lex->dec= NULL;
lex->interval_list.empty();
lex->type= 0;
}
type
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
/*
This was disabled in 5.1.12. See bug #20701
When collation support in SP is implemented, then this test
should be removed.
*/
if (($8 == MYSQL_TYPE_STRING || $8 == MYSQL_TYPE_VARCHAR)
&& (lex->type & BINCMP_FLAG))
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
MYSQL_YYABORT;
}
if (sp->fill_field_definition(YYTHD, lex,
(enum enum_field_types) $8,
&sp->m_return_field_def))
MYSQL_YYABORT;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
sp_c_chistics
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
sp_proc_stmt
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
if (sp->is_not_allowed_in_function("function"))
MYSQL_YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN))
{
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
MYSQL_YYABORT;
}
if (is_native_function(thd, & sp->m_name))
{
/*
This warning will be printed when
[1] A client query is parsed,
[2] A stored function is loaded by db_load_routine.
Printing the warning for [2] is intentional, to cover the
following scenario:
- A user define a SF 'foo' using MySQL 5.N
- An application uses select foo(), and works.
- MySQL 5.{N+1} defines a new native function 'foo', as
part of a new feature.
- MySQL 5.{N+1} documentation is updated, and should mention
that there is a potential incompatible change in case of
existing stored function named 'foo'.
- The user deploys 5.{N+1}. At this point, 'select foo()'
means something different, and the user code is most likely
broken (it's only safe if the code is 'select db.foo()').
With a warning printed when the SF is loaded (which has to occur
before the call), the warning will provide a hint explaining
the root cause of a later failure of 'select foo()'.
With no warning printed, the user code will fail with no
apparent reason.
Printing a warning each time db_load_routine is executed for
an ambiguous function is annoying, since that can happen a lot,
but in practice should not happen unless there *are* name
collisions.
If a collision exists, it should not be silenced but fixed.
*/
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NATIVE_FCT_NAME_COLLISION,
ER(ER_NATIVE_FCT_NAME_COLLISION),
sp->m_name.str);
}
/* Restore flag if it was cleared above */
thd->client_capabilities |= $<ulong_num>2;
sp->restore_thd_mem_root(thd);
}
;
sp_a_chistics:
/* Empty */ {}
| sp_a_chistics sp_chistic {}
@ -2540,25 +2364,13 @@ sp_decl:
sp_cursor_stmt:
{
Lex->sphead->reset_lex(YYTHD);
/*
We use statement here just be able to get a better
error message. Using 'select' works too, but will then
result in a generic "syntax error" if a non-select
statement is given.
*/
}
statement
select
{
LEX *lex= Lex;
if (lex->sql_command != SQLCOM_SELECT &&
!(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
{
my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY),
MYF(0));
MYSQL_YYABORT;
}
DBUG_ASSERT(lex->sql_command == SQLCOM_SELECT);
if (lex->result)
{
my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT),
@ -3362,7 +3174,6 @@ change_ts_option:
;
tablespace_option_list:
/* empty */ {}
tablespace_options
;
@ -3384,7 +3195,6 @@ tablespace_option:
;
alter_tablespace_option_list:
/* empty */ {}
alter_tablespace_options
;
@ -3403,7 +3213,6 @@ alter_tablespace_option:
;
logfile_group_option_list:
/* empty */ {}
logfile_group_options
;
@ -3424,7 +3233,6 @@ logfile_group_option:
;
alter_logfile_group_option_list:
/* empty */ {}
alter_logfile_group_options
;
@ -3669,7 +3477,7 @@ size_number:
create2:
'(' create2a {}
| opt_create_table_options
opt_partitioning {}
opt_partitioning
create3 {}
| LIKE table_ident
{
@ -3693,19 +3501,22 @@ create2:
create2a:
field_list ')' opt_create_table_options
opt_partitioning {}
opt_partitioning
create3 {}
| opt_partitioning {}
| opt_partitioning
create_select ')'
{ Select->set_braces(1);} union_opt {}
{ Select->set_braces(1);}
union_opt {}
;
create3:
/* empty */ {}
| opt_duplicate opt_as create_select
{ Select->set_braces(0);} union_clause {}
{ Select->set_braces(0);}
union_clause {}
| opt_duplicate opt_as '(' create_select ')'
{ Select->set_braces(1);} union_opt {}
{ Select->set_braces(1);}
union_opt {}
;
/*
@ -3787,7 +3598,7 @@ partition_entry:
;
partition:
BY part_type_def opt_no_parts {} opt_sub_part {} part_defs
BY part_type_def opt_no_parts opt_sub_part part_defs
;
part_type_def:
@ -3988,10 +3799,11 @@ part_definition:
part_info->use_default_partitions= FALSE;
part_info->use_default_no_partitions= FALSE;
}
part_name {}
opt_part_values {}
opt_part_options {}
opt_sub_partition {}
part_name
opt_part_values
opt_part_options
opt_sub_partition
{}
;
part_name:
@ -4501,11 +4313,10 @@ create_table_option:
}
| TRANSACTIONAL_SYM opt_equal ulong_num
{
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.transactional= ($3 != 0 ? HA_CHOICE_YES :
HA_CHOICE_NO);
HA_CHOICE_NO);
}
;
default_charset:
@ -4587,7 +4398,7 @@ row_types:
| COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
| REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; }
| COMPACT_SYM { $$= ROW_TYPE_COMPACT; }
| PAGE_SYM { $$= ROW_TYPE_PAGE; }
| PAGE_SYM { $$= ROW_TYPE_PAGE; }
;
merge_insert_types:
@ -4601,10 +4412,6 @@ opt_select_from:
| select_from select_lock_type
;
udf_func_type:
/* empty */ { $$ = UDFTYPE_FUNCTION; }
| AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; };
udf_type:
STRING_SYM {$$ = (int) STRING_RESULT; }
| REAL {$$ = (int) REAL_RESULT; }
@ -4657,8 +4464,9 @@ key_def:
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
LEX *lex=Lex;
const char *key_name= $4 ? $4 : $1;
Key *key= new Foreign_key(key_name, lex->col_list,
const char *key_name= $1 ? $1 : $4;
const char *fkey_name = $4 ? $4 : key_name;
Key *key= new Foreign_key(fkey_name, lex->col_list,
$8,
lex->ref_list,
lex->fk_delete_opt,
@ -5401,6 +5209,17 @@ alter:
lex->copy_db_to(&lex->name.str, &lex->name.length))
MYSQL_YYABORT;
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
LEX *lex= Lex;
if (lex->sphead)
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "DATABASE");
MYSQL_YYABORT;
}
lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
lex->name= $3;
}
| ALTER PROCEDURE sp_name
{
LEX *lex= Lex;
@ -5437,7 +5256,7 @@ alter:
lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->spname= $3;
}
| ALTER view_algorithm definer
| ALTER view_algorithm definer_opt
{
LEX *lex= Lex;
@ -5450,7 +5269,7 @@ alter:
}
view_tail
{}
| ALTER definer
| ALTER definer_opt
/*
We have two separate rules for ALTER VIEW rather that
optional view_algorithm above, to resolve the ambiguity
@ -5469,7 +5288,7 @@ alter:
}
view_tail
{}
| ALTER definer EVENT_SYM sp_name
| ALTER definer_opt EVENT_SYM sp_name
/*
BE CAREFUL when you add a new rule to update the block where
YYTHD->client_capabilities is set back to original value
@ -5505,7 +5324,7 @@ alter:
{
/*
$1 - ALTER
$2 - definer
$2 - definer_opt
$3 - EVENT_SYM
$4 - sp_name
$5 - the block above
@ -6185,13 +6004,6 @@ rename:
}
table_to_table_list
{}
| RENAME DATABASE
{
Lex->db_list.empty();
Lex->sql_command= SQLCOM_RENAME_DB;
}
db_to_db
{}
| RENAME USER clear_privileges rename_list
{
Lex->sql_command = SQLCOM_RENAME_USER;
@ -6229,18 +6041,6 @@ table_to_table:
}
;
db_to_db:
ident TO_SYM ident
{
LEX *lex=Lex;
if (lex->db_list.push_back((LEX_STRING*)
sql_memdup(&$1, sizeof(LEX_STRING))) ||
lex->db_list.push_back((LEX_STRING*)
sql_memdup(&$3, sizeof(LEX_STRING))))
MYSQL_YYABORT;
}
;
keycache:
CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
{
@ -8578,9 +8378,11 @@ drop:
lex->drop_if_exists=$3;
lex->name= $4;
}
| DROP FUNCTION_SYM if_exists sp_name
| DROP FUNCTION_SYM if_exists ident '.' ident
{
LEX *lex=Lex;
THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_name *spname;
if (lex->sphead)
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
@ -8588,7 +8390,28 @@ drop:
}
lex->sql_command = SQLCOM_DROP_FUNCTION;
lex->drop_if_exists= $3;
lex->spname= $4;
spname= new sp_name($4, $6, true);
spname->init_qname(thd);
lex->spname= spname;
}
| DROP FUNCTION_SYM if_exists ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
LEX_STRING db= {0, 0};
sp_name *spname;
if (lex->sphead)
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
MYSQL_YYABORT;
}
if (thd->db && lex->copy_db_to(&db.str, &db.length))
MYSQL_YYABORT;
lex->sql_command = SQLCOM_DROP_FUNCTION;
lex->drop_if_exists= $3;
spname= new sp_name(db, $4, false);
spname->init_qname(thd);
lex->spname= spname;
}
| DROP PROCEDURE if_exists sp_name
{
@ -8658,18 +8481,19 @@ table_name:
;
table_alias_ref_list:
table_alias_ref
| table_alias_ref_list ',' table_alias_ref;
table_alias_ref
| table_alias_ref_list ',' table_alias_ref
;
table_alias_ref:
table_ident
{
if (!Select->add_table_to_list(YYTHD, $1, NULL,
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
Lex->lock_option ))
MYSQL_YYABORT;
}
;
table_ident
{
if (!Select->add_table_to_list(YYTHD, $1, NULL,
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
Lex->lock_option ))
MYSQL_YYABORT;
}
;
if_exists:
/* empty */ { $$= 0; }
@ -10644,7 +10468,7 @@ keyword_sp:
| TEXT_SYM {}
| THAN_SYM {}
| TRANSACTION_SYM {}
| TRANSACTIONAL_SYM {}
| TRANSACTIONAL_SYM {}
| TRIGGERS_SYM {}
| TIMESTAMP {}
| TIMESTAMP_ADD {}
@ -11874,21 +11698,29 @@ subselect_end:
**************************************************************************/
view_or_trigger_or_sp_or_event:
definer view_or_trigger_or_sp_or_event_tail
definer definer_tail
{}
| view_replace_or_algorithm definer view_tail
| no_definer no_definer_tail
{}
| view_replace_or_algorithm definer_opt view_tail
{}
;
view_or_trigger_or_sp_or_event_tail:
definer_tail:
view_tail
{}
| trigger_tail
{}
| sp_tail
{}
| sf_tail
| event_tail
;
no_definer_tail:
view_tail
| trigger_tail
| sp_tail
| sf_tail
| udf_tail
| event_tail
{}
;
/**************************************************************************
@ -11897,7 +11729,12 @@ view_or_trigger_or_sp_or_event_tail:
**************************************************************************/
definer:
definer_opt:
no_definer
| definer
;
no_definer:
/* empty */
{
/*
@ -11909,7 +11746,10 @@ definer:
*/
YYTHD->lex->definer= 0;
}
| DEFINER_SYM EQ user
;
definer:
DEFINER_SYM EQ user
{
YYTHD->lex->definer= get_current_user(YYTHD, $3);
}
@ -12146,17 +11986,193 @@ trigger_tail:
**************************************************************************/
sp_tail:
udf_func_type remember_name FUNCTION_SYM sp_name
udf_tail:
AGGREGATE_SYM remember_name FUNCTION_SYM ident
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{
LEX *lex=Lex;
lex->udf.type= $1;
THD *thd= YYTHD;
LEX *lex= thd->lex;
if (is_native_function(thd, & $4))
{
my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
$4.str);
MYSQL_YYABORT;
}
lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.type= UDFTYPE_AGGREGATE;
lex->stmt_definition_begin= $2;
lex->spname= $4;
lex->udf.name = $4;
lex->udf.returns=(Item_result) $6;
lex->udf.dl=$8.str;
}
create_function_tail
{}
| PROCEDURE remember_name sp_name
| remember_name FUNCTION_SYM ident
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
if (is_native_function(thd, & $3))
{
my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
$3.str);
MYSQL_YYABORT;
}
lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.type= UDFTYPE_FUNCTION;
lex->stmt_definition_begin= $1;
lex->udf.name = $3;
lex->udf.returns=(Item_result) $5;
lex->udf.dl=$7.str;
}
;
sf_tail:
remember_name /* $1 */
FUNCTION_SYM /* $2 */
sp_name /* $3 */
'(' /* $4 */
{ /* $5 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
sp_head *sp;
const char* tmp_param_begin;
lex->stmt_definition_begin= $1;
lex->spname= $3;
if (lex->sphead)
{
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
MYSQL_YYABORT;
}
/* Order is important here: new - reset - init */
sp= new sp_head();
sp->reset_thd_mem_root(thd);
sp->init(lex);
sp->init_sp_name(thd, lex->spname);
sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp;
/*
We have to turn off CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
$<ulong_num>$= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
tmp_param_begin= lip->get_cpp_tok_start();
tmp_param_begin++;
lex->sphead->m_param_begin= tmp_param_begin;
}
sp_fdparam_list /* $6 */
')' /* $7 */
{ /* $8 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_param_end= lip->get_cpp_tok_start();
}
RETURNS_SYM /* $9 */
{ /* $10 */
LEX *lex= Lex;
lex->charset= NULL;
lex->length= lex->dec= NULL;
lex->interval_list.empty();
lex->type= 0;
}
type /* $11 */
{ /* $12 */
LEX *lex= Lex;
sp_head *sp= lex->sphead;
/*
This was disabled in 5.1.12. See bug #20701
When collation support in SP is implemented, then this test
should be removed.
*/
if (($11 == MYSQL_TYPE_STRING || $11 == MYSQL_TYPE_VARCHAR)
&& (lex->type & BINCMP_FLAG))
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
MYSQL_YYABORT;
}
if (sp->fill_field_definition(YYTHD, lex,
(enum enum_field_types) $11,
&sp->m_return_field_def))
MYSQL_YYABORT;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
sp_c_chistics /* $13 */
{ /* $14 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
sp_proc_stmt /* $15 */
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
if (sp->is_not_allowed_in_function("function"))
MYSQL_YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN))
{
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
MYSQL_YYABORT;
}
if (is_native_function(thd, & sp->m_name))
{
/*
This warning will be printed when
[1] A client query is parsed,
[2] A stored function is loaded by db_load_routine.
Printing the warning for [2] is intentional, to cover the
following scenario:
- A user define a SF 'foo' using MySQL 5.N
- An application uses select foo(), and works.
- MySQL 5.{N+1} defines a new native function 'foo', as
part of a new feature.
- MySQL 5.{N+1} documentation is updated, and should mention
that there is a potential incompatible change in case of
existing stored function named 'foo'.
- The user deploys 5.{N+1}. At this point, 'select foo()'
means something different, and the user code is most likely
broken (it's only safe if the code is 'select db.foo()').
With a warning printed when the SF is loaded (which has to occur
before the call), the warning will provide a hint explaining
the root cause of a later failure of 'select foo()'.
With no warning printed, the user code will fail with no
apparent reason.
Printing a warning each time db_load_routine is executed for
an ambiguous function is annoying, since that can happen a lot,
but in practice should not happen unless there *are* name
collisions.
If a collision exists, it should not be silenced but fixed.
*/
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NATIVE_FCT_NAME_COLLISION,
ER(ER_NATIVE_FCT_NAME_COLLISION),
sp->m_name.str);
}
/* Restore flag if it was cleared above */
thd->client_capabilities |= $<ulong_num>5;
sp->restore_thd_mem_root(thd);
}
;
sp_tail:
PROCEDURE remember_name sp_name
{
LEX *lex= Lex;
sp_head *sp;

View file

@ -119,6 +119,8 @@ static void client_disconnect(void);
#define DIE_UNLESS(expr) \
((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
#define DIE_IF(expr) \
((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0))
#define DIE(expr) \
die(__FILE__, __LINE__, #expr)
@ -177,8 +179,8 @@ if (stmt == 0) \
DIE_UNLESS(stmt == 0);\
}
#define mytest(x) if (!x) {myerror(NULL);DIE_UNLESS(FALSE);}
#define mytest_r(x) if (x) {myerror(NULL);DIE_UNLESS(FALSE);}
#define mytest(x) if (!(x)) {myerror(NULL);DIE_UNLESS(FALSE);}
#define mytest_r(x) if ((x)) {myerror(NULL);DIE_UNLESS(FALSE);}
/* A workaround for Sun Forte 5.6 on Solaris x86 */
@ -13534,7 +13536,7 @@ static void test_bug9478()
{
char buff[8];
/* Fill in the fethc packet */
/* Fill in the fetch packet */
int4store(buff, stmt->stmt_id);
buff[4]= 1; /* prefetch rows */
rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
@ -16214,6 +16216,204 @@ static void test_bug28934()
myquery(mysql_query(mysql, "drop table t1"));
}
/*
Test mysql_change_user() C API and COM_CHANGE_USER
*/
static void test_change_user()
{
char buff[256];
const char *user_pw= "mysqltest_pw";
const char *user_no_pw= "mysqltest_no_pw";
const char *pw= "password";
const char *db= "mysqltest_user_test_database";
int rc;
DBUG_ENTER("test_change_user");
myheader("test_change_user");
/* Prepare environment */
sprintf(buff, "drop database if exists %s", db);
rc= mysql_query(mysql, buff);
myquery(rc);
sprintf(buff, "create database %s", db);
rc= mysql_query(mysql, buff);
myquery(rc);
sprintf(buff,
"grant select on %s.* to %s@'%%' identified by '%s'",
db,
user_pw,
pw);
rc= mysql_query(mysql, buff);
myquery(rc);
sprintf(buff,
"grant select on %s.* to %s@'%%'",
db,
user_no_pw);
rc= mysql_query(mysql, buff);
myquery(rc);
/* Try some combinations */
rc= mysql_change_user(mysql, NULL, NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", "", NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", "", "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, NULL, "", "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, NULL, NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, "", "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, "", NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, "", db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, NULL, db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_pw, pw, db);
myquery(rc);
rc= mysql_change_user(mysql, user_pw, pw, NULL);
myquery(rc);
rc= mysql_change_user(mysql, user_pw, pw, "");
myquery(rc);
rc= mysql_change_user(mysql, user_no_pw, pw, db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_no_pw, pw, "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_no_pw, pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, user_no_pw, "", NULL);
myquery(rc);
rc= mysql_change_user(mysql, user_no_pw, "", "");
myquery(rc);
rc= mysql_change_user(mysql, user_no_pw, "", db);
myquery(rc);
rc= mysql_change_user(mysql, user_no_pw, NULL, db);
myquery(rc);
rc= mysql_change_user(mysql, "", pw, db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", pw, "");
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, NULL, pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, NULL, NULL, db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, NULL, "", db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
rc= mysql_change_user(mysql, "", "", db);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
/* Cleanup the environment */
mysql_change_user(mysql, opt_user, opt_password, current_db);
sprintf(buff, "drop database %s", db);
rc= mysql_query(mysql, buff);
myquery(rc);
sprintf(buff, "drop user %s@'%%'", user_pw);
rc= mysql_query(mysql, buff);
myquery(rc);
sprintf(buff, "drop user %s@'%%'", user_no_pw);
rc= mysql_query(mysql, buff);
myquery(rc);
DBUG_VOID_RETURN;
}
/*
Bug#27592 (stack overrun when storing datetime value using prepared statements)
@ -16451,6 +16651,446 @@ static void test_bug29306()
DBUG_VOID_RETURN;
}
/*
Bug#30472: libmysql doesn't reset charset, insert_id after succ.
mysql_change_user() call row insertions.
*/
static void bug30472_retrieve_charset_info(MYSQL *con,
char *character_set_name,
char *character_set_client,
char *character_set_results,
char *collation_connection)
{
MYSQL_RES *rs;
MYSQL_ROW row;
/* Get the cached client character set name. */
strcpy(character_set_name, mysql_character_set_name(con));
/* Retrieve server character set information. */
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
DIE_UNLESS(rs= mysql_store_result(con));
DIE_UNLESS(row= mysql_fetch_row(rs));
strcpy(character_set_client, row[1]);
mysql_free_result(rs);
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
DIE_UNLESS(rs= mysql_store_result(con));
DIE_UNLESS(row= mysql_fetch_row(rs));
strcpy(character_set_results, row[1]);
mysql_free_result(rs);
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
DIE_UNLESS(rs= mysql_store_result(con));
DIE_UNLESS(row= mysql_fetch_row(rs));
strcpy(collation_connection, row[1]);
mysql_free_result(rs);
}
static void test_bug30472()
{
MYSQL con;
char character_set_name_1[MY_CS_NAME_SIZE];
char character_set_client_1[MY_CS_NAME_SIZE];
char character_set_results_1[MY_CS_NAME_SIZE];
char collation_connnection_1[MY_CS_NAME_SIZE];
char character_set_name_2[MY_CS_NAME_SIZE];
char character_set_client_2[MY_CS_NAME_SIZE];
char character_set_results_2[MY_CS_NAME_SIZE];
char collation_connnection_2[MY_CS_NAME_SIZE];
char character_set_name_3[MY_CS_NAME_SIZE];
char character_set_client_3[MY_CS_NAME_SIZE];
char character_set_results_3[MY_CS_NAME_SIZE];
char collation_connnection_3[MY_CS_NAME_SIZE];
char character_set_name_4[MY_CS_NAME_SIZE];
char character_set_client_4[MY_CS_NAME_SIZE];
char character_set_results_4[MY_CS_NAME_SIZE];
char collation_connnection_4[MY_CS_NAME_SIZE];
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
opt_user,
opt_password,
opt_db ? opt_db : "test",
opt_port,
opt_unix_socket,
CLIENT_FOUND_ROWS));
/* Retrieve character set information. */
bug30472_retrieve_charset_info(&con,
character_set_name_1,
character_set_client_1,
character_set_results_1,
collation_connnection_1);
/* Switch client character set. */
DIE_IF(mysql_set_character_set(&con, "utf8"));
/* Retrieve character set information. */
bug30472_retrieve_charset_info(&con,
character_set_name_2,
character_set_client_2,
character_set_results_2,
collation_connnection_2);
/*
Check that
1) character set has been switched and
2) new character set is different from the original one.
*/
DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
/* Call mysql_change_user() with the same username, password, database. */
DIE_IF(mysql_change_user(&con,
opt_user,
opt_password,
opt_db ? opt_db : "test"));
/* Retrieve character set information. */
bug30472_retrieve_charset_info(&con,
character_set_name_3,
character_set_client_3,
character_set_results_3,
collation_connnection_3);
/* Check that character set information has been reset. */
DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
/* Change connection-default character set in the client. */
con.options.charset_name= my_strdup("utf8", MYF(MY_FAE));
/*
Call mysql_change_user() in order to check that new connection will
have UTF8 character set on the client and on the server.
*/
DIE_IF(mysql_change_user(&con,
opt_user,
opt_password,
opt_db ? opt_db : "test"));
/* Retrieve character set information. */
bug30472_retrieve_charset_info(&con,
character_set_name_4,
character_set_client_4,
character_set_results_4,
collation_connnection_4);
/* Check that we have UTF8 on the server and on the client. */
DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
/* That's it. Cleanup. */
mysql_close(&con);
}
static void bug20023_change_user(MYSQL *con)
{
DIE_IF(mysql_change_user(con,
opt_user,
opt_password,
opt_db ? opt_db : "test"));
}
static bool query_int_variable(MYSQL *con,
const char *var_name,
int *var_value)
{
MYSQL_RES *rs;
MYSQL_ROW row;
char query_buffer[MAX_TEST_QUERY_LENGTH];
bool is_null;
my_snprintf(query_buffer,
sizeof (query_buffer),
"SELECT %s",
(const char *) var_name);
DIE_IF(mysql_query(con, query_buffer));
DIE_UNLESS(rs= mysql_store_result(con));
DIE_UNLESS(row= mysql_fetch_row(rs));
is_null= row[0] == NULL;
if (!is_null)
*var_value= atoi(row[0]);
mysql_free_result(rs);
return is_null;
}
static void test_bug20023()
{
MYSQL con;
int sql_big_selects_orig;
int max_join_size_orig;
int sql_big_selects_2;
int sql_big_selects_3;
int sql_big_selects_4;
int sql_big_selects_5;
char query_buffer[MAX_TEST_QUERY_LENGTH];
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
opt_user,
opt_password,
opt_db ? opt_db : "test",
opt_port,
opt_unix_socket,
CLIENT_FOUND_ROWS));
/***********************************************************************
Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
***********************************************************************/
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_orig);
query_int_variable(&con,
"@@global.max_join_size",
&max_join_size_orig);
/***********************************************************************
Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
***********************************************************************/
/* Issue COM_CHANGE_USER. */
bug20023_change_user(&con);
/* Query SQL_BIG_SELECTS. */
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_2);
/* Check that SQL_BIG_SELECTS is reset properly. */
DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
/***********************************************************************
Test that if MAX_JOIN_SIZE set to non-default value,
SQL_BIG_SELECTS will be 0.
***********************************************************************/
/* Set MAX_JOIN_SIZE to some non-default value. */
DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */
bug20023_change_user(&con);
/* Query SQL_BIG_SELECTS. */
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_3);
/* Check that SQL_BIG_SELECTS is 0. */
DIE_UNLESS(sql_big_selects_3 == 0);
/***********************************************************************
Test that if MAX_JOIN_SIZE set to default value,
SQL_BIG_SELECTS will be 1.
***********************************************************************/
/* Set MAX_JOIN_SIZE to the default value (-1). */
DIE_IF(mysql_query(&con, "SET @@global.max_join_size = -1"));
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */
bug20023_change_user(&con);
/* Query SQL_BIG_SELECTS. */
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_4);
/* Check that SQL_BIG_SELECTS is 1. */
DIE_UNLESS(sql_big_selects_4 == 1);
/***********************************************************************
Restore MAX_JOIN_SIZE.
Check that SQL_BIG_SELECTS will be the original one.
***********************************************************************/
/* Restore MAX_JOIN_SIZE. */
my_snprintf(query_buffer,
sizeof (query_buffer),
"SET @@global.max_join_size = %d",
(int) max_join_size_orig);
DIE_IF(mysql_query(&con, query_buffer));
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */
bug20023_change_user(&con);
/* Query SQL_BIG_SELECTS. */
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_5);
/* Check that SQL_BIG_SELECTS is 1. */
DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
/***********************************************************************
That's it. Cleanup.
***********************************************************************/
mysql_close(&con);
}
static void bug31418_impl()
{
MYSQL con;
bool is_null;
int rc;
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
opt_user,
opt_password,
opt_db ? opt_db : "test",
opt_port,
opt_unix_socket,
CLIENT_FOUND_ROWS));
/***********************************************************************
Check that lock is free:
- IS_FREE_LOCK() should return 1;
- IS_USED_LOCK() should return NULL;
***********************************************************************/
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(is_null);
/***********************************************************************
Acquire lock and check the lock status (the lock must be in use):
- IS_FREE_LOCK() should return 0;
- IS_USED_LOCK() should return non-zero thread id;
***********************************************************************/
query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
DIE_UNLESS(rc);
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && !rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
/***********************************************************************
Issue COM_CHANGE_USER command and check the lock status
(the lock must be free):
- IS_FREE_LOCK() should return 1;
- IS_USED_LOCK() should return NULL;
**********************************************************************/
bug20023_change_user(&con);
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(is_null);
/***********************************************************************
That's it. Cleanup.
***********************************************************************/
mysql_close(&con);
}
static void test_bug31418()
{
/* Run test case for BUG#31418 for three different connections. */
bug31418_impl();
bug31418_impl();
bug31418_impl();
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -16750,6 +17390,10 @@ static struct my_tests_st my_tests[]= {
{ "test_bug29687", test_bug29687 },
{ "test_bug29692", test_bug29692 },
{ "test_bug29306", test_bug29306 },
{ "test_change_user", test_change_user },
{ "test_bug30472", test_bug30472 },
{ "test_bug20023", test_bug20023 },
{ "test_bug31418", test_bug31418 },
{ 0, 0 }
};