mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge trift2.:/MySQL/M51/mysql-5.1
into trift2.:/MySQL/M51/push-5.1
This commit is contained in:
commit
242fdacdfe
78 changed files with 3738 additions and 908 deletions
|
@ -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))))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 && \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
46
mysql-test/r/change_user.result
Normal file
46
mysql-test/r/change_user.result
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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`;
|
||||
|
|
35
mysql-test/t/change_user.test
Normal file
35
mysql-test/t/change_user.test
Normal 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');
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
197
sql/log.cc
197
sql/log.cc
|
@ -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(¤t_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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
144
sql/sp.cc
|
@ -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:
|
||||
|
|
1
sql/sp.h
1
sql/sp.h
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
/*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
118
sql/sql_db.cc
118
sql/sql_db.cc
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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, ¬_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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
182
sql/sql_parse.cc
182
sql/sql_parse.cc
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)))
|
||||
|
|
568
sql/sql_yacc.yy
568
sql/sql_yacc.yy
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue