Commit 004f3990 authored by lars@mysql.com's avatar lars@mysql.com

Merge lthalmann@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  mysql.com:/users/lthalmann/bkroot/mysql-5.1-new
parents 2d3fcf26 0b30190c
......@@ -49,6 +49,8 @@ mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \
$(top_srcdir)/mysys/base64.c
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
mysqlslap_LDADD = $(LDADD) $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS)
mysqlimport_LDADD = $(LDADD) $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
$(top_builddir)/mysys/libmysys.a
mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c
mysqltestmanagerc_SOURCES= mysqlmanagerc.c $(yassl_dummy_link_fix)
mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix)
......@@ -57,7 +59,8 @@ mysqlslap_SOURCES= mysqlslap.c $(top_srcdir)/mysys/my_lock.c \
$(top_srcdir)/mysys/my_alarm.c \
$(yassl_dummy_link_fix)
mysqldump_SOURCES= mysqldump.c my_user.c $(yassl_dummy_link_fix)
mysqlimport_SOURCES= mysqlimport.c $(yassl_dummy_link_fix)
mysqlimport_SOURCES= mysqlimport.c \
$(yassl_dummy_link_fix)
sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc
strings_src=decimal.c
......
......@@ -54,6 +54,7 @@ enum options_client
OPT_MYSQL_LOCK_DIRECTORY,
OPT_MYSQL_SLAP_SLAVE,
OPT_USE_THREADS,
OPT_IMPORT_USE_THREADS,
OPT_MYSQL_NUMBER_OF_QUERY,
OPT_MYSQL_PRESERVE_SCHEMA,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
......
......@@ -29,6 +29,12 @@
#include "client_priv.h"
#include "mysql_version.h"
#include <my_pthread.h>
/* Global Thread counter */
int counter= 0;
pthread_mutex_t counter_mutex;
static void db_error_with_table(MYSQL *mysql, char *table);
static void db_error(MYSQL *mysql);
......@@ -39,6 +45,7 @@ static char *add_load_option(char *ptr,const char *object,
static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
replace=0,silent=0,ignore=0,opt_compress=0,
opt_low_priority= 0, tty_password= 0;
static my_bool opt_use_threads= 0;
static uint opt_local_file=0;
static MYSQL mysql_connection;
static char *opt_password=0, *current_user=0,
......@@ -108,8 +115,9 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"local", 'L', "Read all files through the client.", (gptr*) &opt_local_file,
(gptr*) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"lock-tables", 'l', "Lock all tables for write.", (gptr*) &lock_tables,
(gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"lock-tables", 'l', "Lock all tables for write (this disables threads).",
(gptr*) &lock_tables, (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"low-priority", OPT_LOW_PRIORITY,
"Use LOW_PRIORITY when updating the table.", (gptr*) &opt_low_priority,
(gptr*) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
......@@ -138,6 +146,11 @@ static struct my_option my_long_options[] =
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
{"use-threads", OPT_USE_THREADS,
"Parrelize the loading of files. Requires an arguement for the number \
threads to use for loading of data.",
(gptr*) &opt_use_threads, (gptr*) &opt_use_threads, 0,
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &current_user,
(gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -287,7 +300,7 @@ static int write_to_table(char *filename, MYSQL *sock)
{
if (verbose)
fprintf(stdout, "Deleting the old data from table %s\n", tablename);
sprintf(sql_statement, "DELETE FROM %s", tablename);
snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
if (mysql_query(sock, sql_statement))
{
db_error_with_table(sock, tablename);
......@@ -497,12 +510,41 @@ static char *field_escape(char *to,const char *from,uint length)
}
int
worker_thread(char *raw_table_name)
{
MYSQL *sock= 0;
if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
{
goto error;
}
if (mysql_query(sock, "set @@character_set_database=binary;"))
{
db_error(sock); /* We shall countinue here, if --force was given */
goto error;
}
/*
We should do something about the error
*/
write_to_table(raw_table_name, sock);
error:
if (sock)
db_disconnect(current_host, sock);
pthread_mutex_lock(&counter_mutex);
counter--;
pthread_mutex_unlock(&counter_mutex);
return 0;
}
int main(int argc, char **argv)
{
int exitcode=0, error=0;
char **argv_to_free;
MYSQL *sock=0;
MY_INIT(argv[0]);
load_defaults("my",load_default_groups,&argc,&argv);
......@@ -513,6 +555,59 @@ int main(int argc, char **argv)
free_defaults(argv_to_free);
return(1);
}
if (opt_use_threads && !lock_tables)
{
pthread_t mainthread; /* Thread descriptor */
pthread_attr_t attr; /* Thread attributes */
VOID(pthread_mutex_init(&counter_mutex, NULL));
for (; *argv != NULL; argv++) // Loop through tables
{
/*
If we hit thread count limit we loop until some threads exit.
We sleep for a second, so that we don't chew up a lot of
CPU in the loop.
*/
sanity_label:
if (counter == opt_use_threads)
{
sleep(1);
goto sanity_label;
}
pthread_mutex_lock(&counter_mutex);
counter++;
pthread_mutex_unlock(&counter_mutex);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_DETACHED);
/* now create the thread */
if (pthread_create(&mainthread, &attr, (void *)worker_thread,
(void *)*argv) != 0)
{
pthread_mutex_lock(&counter_mutex);
counter--;
pthread_mutex_unlock(&counter_mutex);
fprintf(stderr,"%s: Could not create thread\n",
my_progname);
}
}
/*
We loop until we know that all children have cleaned up.
*/
loop_label:
if (counter)
{
sleep(1);
goto loop_label;
}
VOID(pthread_mutex_destroy(&counter_mutex));
}
else
{
MYSQL *sock= 0;
if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
{
free_defaults(argv_to_free);
......@@ -532,6 +627,7 @@ int main(int argc, char **argv)
if (exitcode == 0)
exitcode = error;
db_disconnect(current_host, sock);
}
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
......
......@@ -2650,3 +2650,35 @@ DELIMITER ;
DROP TRIGGER tr1;
DROP TABLE t1;
create table t1 (a text , b text);
create table t2 (a text , b text);
insert t1 values ("Duck, Duck", "goose");
insert t1 values ("Duck, Duck", "pidgeon");
insert t2 values ("We the people", "in order to perform");
insert t2 values ("a more perfect", "union");
select * from t1;
a b
Duck, Duck goose
Duck, Duck pidgeon
select * from t2;
a b
We the people in order to perform
a more perfect union
test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
select * from t1;
a b
Duck, Duck goose
Duck, Duck pidgeon
Duck, Duck goose
Duck, Duck pidgeon
select * from t2;
a b
We the people in order to perform
a more perfect union
We the people in order to perform
a more perfect union
drop table t1;
drop table t2;
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;
......@@ -10,6 +10,7 @@
#
##############################################################################
archive : Change between azio and gzio is causing an issue
events : Test case instability - infinite locking. To be fixed.
func_group : Bug#15448
func_math : Bug#15448
......
......@@ -1048,3 +1048,27 @@ SET SQL_MODE = @old_sql_mode;
DROP TRIGGER tr1;
DROP TABLE t1;
#
# Added for use-thread option
#
create table t1 (a text , b text);
create table t2 (a text , b text);
insert t1 values ("Duck, Duck", "goose");
insert t1 values ("Duck, Duck", "pidgeon");
insert t2 values ("We the people", "in order to perform");
insert t2 values ("a more perfect", "union");
select * from t1;
select * from t2;
--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ test
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/t1.sql
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/t2.sql
# The first load tests the pausing code
--exec $MYSQL_IMPORT --use-threads=1 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt
# Now we test with multiple threads!
--exec $MYSQL_IMPORT --use-threads=5 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt
select * from t1;
select * from t2;
drop table t1;
drop table t2;
--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;
......@@ -405,12 +405,14 @@ int ha_archive::write_meta_file(File meta_file, ha_rows rows,
See ha_example.cc for a longer description.
*/
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name,
TABLE *table, int *rc)
{
ARCHIVE_SHARE *share;
char meta_file_name[FN_REFLEN];
uint length;
char *tmp_name;
DBUG_ENTER("ha_archive::get_share");
pthread_mutex_lock(&archive_mutex);
length=(uint) strlen(table_name);
......@@ -425,7 +427,8 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
NullS))
{
pthread_mutex_unlock(&archive_mutex);
return NULL;
*rc= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
share->use_count= 0;
......@@ -468,9 +471,14 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
thr_lock_init(&share->lock);
}
share->use_count++;
DBUG_PRINT("info", ("archive table %.*s has %d open handles now",
share->table_name_length, share->table_name,
share->use_count));
if (share->crashed)
*rc= HA_ERR_CRASHED_ON_USAGE;
pthread_mutex_unlock(&archive_mutex);
return share;
DBUG_RETURN(share);
}
......@@ -481,12 +489,21 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
int ha_archive::free_share(ARCHIVE_SHARE *share)
{
int rc= 0;
DBUG_ENTER("ha_archive::free_share");
DBUG_PRINT("info", ("archive table %.*s has %d open handles on entrance",
share->table_name_length, share->table_name,
share->use_count));
pthread_mutex_lock(&archive_mutex);
if (!--share->use_count)
{
hash_delete(&archive_open_tables, (byte*) share);
thr_lock_delete(&share->lock);
VOID(pthread_mutex_destroy(&share->mutex));
if (share->crashed)
(void)write_meta_file(share->meta_file, share->rows_recorded,
share->auto_increment_value, TRUE);
else
(void)write_meta_file(share->meta_file, share->rows_recorded,
share->auto_increment_value, FALSE);
if (azclose(&(share->archive_write)))
......@@ -497,7 +514,7 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
}
pthread_mutex_unlock(&archive_mutex);
return rc;
DBUG_RETURN(rc);
}
......@@ -524,10 +541,23 @@ const char **ha_archive::bas_ext() const
*/
int ha_archive::open(const char *name, int mode, uint open_options)
{
int rc= 0;
DBUG_ENTER("ha_archive::open");
if (!(share= get_share(name, table)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM); // Not handled well by calling code!
DBUG_PRINT("info", ("archive table was opened for crash %s",
(open_options & HA_OPEN_FOR_REPAIR) ? "yes" : "no"));
share= get_share(name, table, &rc);
if (rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR))
{
free_share(share);
DBUG_RETURN(rc);
}
else if (rc == HA_ERR_OUT_OF_MEM)
{
DBUG_RETURN(rc);
}
thr_lock_data_init(&share->lock,&lock,NULL);
if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY)))
......@@ -537,10 +567,14 @@ int ha_archive::open(const char *name, int mode, uint open_options)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
}
if (open_options & HA_OPEN_FOR_REPAIR)
DBUG_PRINT("info", ("archive table was crashed %s",
rc == HA_ERR_CRASHED_ON_USAGE ? "yes" : "no"));
if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR)
{
DBUG_RETURN(0);
DBUG_RETURN(share->crashed ? HA_ERR_CRASHED_ON_USAGE : 0);
}
else
DBUG_RETURN(rc);
}
......@@ -926,6 +960,7 @@ int ha_archive::rnd_init(bool scan)
if (scan)
{
scan_rows= share->rows_recorded;
DBUG_PRINT("info", ("archive will retrieve %llu rows", scan_rows));
records= 0;
/*
......@@ -937,6 +972,7 @@ int ha_archive::rnd_init(bool scan)
pthread_mutex_lock(&share->mutex);
if (share->dirty == TRUE)
{
DBUG_PRINT("info", ("archive flushing out rows for scan"));
azflush(&(share->archive_write), Z_SYNC_FLUSH);
share->dirty= FALSE;
}
......@@ -1176,6 +1212,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
share->rows_recorded++;
}
}
DBUG_PRINT("info", ("recovered %llu archive rows", share->rows_recorded));
my_free((char*)buf, MYF(0));
if (rc && rc != HA_ERR_END_OF_FILE)
......@@ -1200,10 +1237,24 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
azwrite(&writer, block, read);
}
azclose(&writer);
azflush(&writer, Z_SYNC_FLUSH);
share->dirty= FALSE;
azclose(&(share->archive_write));
share->archive_write= writer;
my_rename(writer_filename,share->data_file_name,MYF(0));
/*
Now we need to reopen our read descriptor since it has changed.
*/
azclose(&archive);
if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY)))
{
rc= HA_ERR_CRASHED_ON_USAGE;
goto error;
}
DBUG_RETURN(0);
error:
......
......@@ -101,7 +101,7 @@ public:
int read_meta_file(File meta_file, ha_rows *rows, ulonglong *auto_increment);
int write_meta_file(File meta_file, ha_rows rows,
ulonglong auto_increment, bool dirty);
ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table);
ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table, int *rc);
int free_share(ARCHIVE_SHARE *share);
bool auto_repair() const { return 1; } // For the moment we just do this
int read_data_header(azio_stream *file_to_read);
......
......@@ -611,6 +611,7 @@ void write_bin_log(THD *thd, bool clear_error,
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);
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,
......@@ -623,7 +624,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
bool quick_rm_table(handlerton *base,const char *db,
const char *table_name);
void close_cached_table(THD *thd, TABLE *table);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
void mysql_parse(THD *thd,char *inBuf,uint length);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
......@@ -1228,10 +1229,12 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
bool is_keyword(const char *name, uint len);
#define MY_DB_OPT_FILE "db.opt"
bool my_database_names_init(void);
void my_database_names_free(void);
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
bool my_dbopt_init(void);
void my_dbopt_cleanup(void);
void my_dbopt_free(void);
extern int creating_database; // How many database locks are made
extern int creating_table; // How many mysql_create_table() are running
/*
External variables
......@@ -1333,7 +1336,7 @@ extern FILE *bootstrap_file;
extern int bootstrap_error;
extern FILE *stderror_file;
extern pthread_key(MEM_ROOT**,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
......@@ -1364,7 +1367,7 @@ extern const char *opt_date_time_formats[];
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
extern String null_string;
extern HASH open_cache;
extern HASH open_cache, lock_db_cache;
extern TABLE *unused_tables;
extern const char* any_db;
extern struct my_option my_long_options[];
......
......@@ -1170,7 +1170,7 @@ void clean_up(bool print_message)
bitmap_free(&slave_error_mask);
#endif
my_tz_free();
my_dbopt_free();
my_database_names_free();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
acl_free(1);
grant_free();
......@@ -1283,6 +1283,7 @@ static void wait_for_signal_thread_to_end()
static void clean_up_mutexes()
{
(void) pthread_mutex_destroy(&LOCK_mysql_create_db);
(void) pthread_mutex_destroy(&LOCK_lock_db);
(void) pthread_mutex_destroy(&LOCK_Acl);
(void) rwlock_destroy(&LOCK_grant);
(void) pthread_mutex_destroy(&LOCK_open);
......@@ -2838,7 +2839,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
if (my_dbopt_init())
if (my_database_names_init())
return 1;
/*
......@@ -2892,6 +2893,7 @@ You should consider changing lower_case_table_names to 1 or 2",
static int init_thread_environment()
{
(void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_open, NULL);
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
......@@ -5232,8 +5234,8 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
*/
{"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"If equal to 0 (the default), then when --log-bin is used, creation of "
"a function is allowed only to users having the SUPER privilege and only "
"if this function may not break binary logging."
"a function (a trigger) is allowed only to users having the SUPER privilege "
"and only if this function (trigger) may not break binary logging."
#ifdef HAVE_ROW_BASED_REPLICATION
" If using --binlog-format=row, the security issues do not exist and the "
"binary logging cannot break so this option is automatically set to 1."
......
This diff is collapsed.
......@@ -67,6 +67,7 @@ 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,
......@@ -818,6 +819,7 @@ typedef struct st_lex
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, auxilliary_table_list, save_list;
create_field *last_field;
......
......@@ -3073,7 +3073,7 @@ end_with_restore_list:
}
}
query_cache_invalidate3(thd, first_table, 0);
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table))
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
goto error;
break;
}
......@@ -3663,6 +3663,48 @@ end_with_restore_list:
res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
break;
}
case SQLCOM_RENAME_DB:
{
LEX_STRING *olddb, *newdb;
List_iterator <LEX_STRING> db_list(lex->db_list);
olddb= db_list++;
newdb= db_list++;
if (end_active_trans(thd))
{
res= 1;
break;
}
#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)))
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
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)))
{
res= 1;
break;
}
if (thd->locked_tables || thd->active_transaction())
{
res= 1;
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
res= mysql_rename_db(thd, olddb, newdb);
if (!res)
send_ok(thd);
break;
}
case SQLCOM_ALTER_DB:
{
char *db= lex->name ? lex->name : thd->db;
......
......@@ -31,7 +31,7 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
second entry is the new name.
*/
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
{
bool error= 1;
TABLE_LIST *ren_table= 0;
......@@ -79,7 +79,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
}
/* Lets hope this doesn't fail as the result will be messy */
if (!error)
if (!silent && !error)
{
if (mysql_bin_log.is_open())
{
......
......@@ -28,6 +28,8 @@
#include <io.h>
#endif
int creating_table= 0; // How many mysql_create_table are running
const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
......@@ -1973,7 +1975,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
Create a table
SYNOPSIS
mysql_create_table()
mysql_create_table_internal()
thd Thread object
db Database
table_name Table name
......@@ -1996,7 +1998,8 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
TRUE error
*/
bool mysql_create_table(THD *thd,const char *db, const char *table_name,
bool mysql_create_table_internal(THD *thd,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields,
List<Key> &keys,bool internal_tmp_table,
......@@ -2009,7 +2012,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
KEY *key_info_buffer;
handler *file;
bool error= TRUE;
DBUG_ENTER("mysql_create_table");
DBUG_ENTER("mysql_create_table_internal");
/* Check for duplicate fields and check type of table to create */
if (!fields.elements)
......@@ -2289,6 +2292,49 @@ warn:
goto unlock_and_end;
}
/*
Database locking aware wrapper for mysql_create_table_internal(),
*/
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields,
List<Key> &keys,bool internal_tmp_table,
uint select_field_count)
{
bool result;
DBUG_ENTER("mysql_create_table");
/* Wait for any database locks */
pthread_mutex_lock(&LOCK_lock_db);
while (!thd->killed &&
hash_search(&lock_db_cache,(byte*) db, strlen(db)))
{
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
pthread_mutex_lock(&LOCK_lock_db);
}
if (thd->killed)
{
pthread_mutex_unlock(&LOCK_lock_db);
DBUG_RETURN(TRUE);
}
creating_table++;
pthread_mutex_unlock(&LOCK_lock_db);
result= mysql_create_table_internal(thd, db, table_name, create_info,
fields, keys, internal_tmp_table,
select_field_count);
pthread_mutex_lock(&LOCK_lock_db);
if (!--creating_table && creating_database)
pthread_cond_signal(&COND_refresh);
pthread_mutex_unlock(&LOCK_lock_db);
DBUG_RETURN(result);
}
/*
** Give the key name after the first field with an optional '_#' after
**/
......
......@@ -195,10 +195,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
/*
There is no DETERMINISTIC clause for triggers, so can't check it.
But a trigger can in theory be used to do nasty things (if it supported
DROP for example) so we do the check for privileges. For now there is
already a stronger test right above; but when this stronger test will
be removed, the test below will hold. Because triggers have the same
nature as functions regarding binlogging: their body is implicitely
DROP for example) so we do the check for privileges. Triggers have the
same nature as functions regarding binlogging: their body is implicitely
binlogged, so they share the same danger, so trust_function_creators
applies to them too.
*/
......
......@@ -863,7 +863,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
clear_privileges flush_options flush_option
equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join
table_to_table_list table_to_table opt_table_list opt_as
db_to_db 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
......@@ -5485,6 +5485,13 @@ 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;
......@@ -5520,6 +5527,17 @@ table_to_table:
YYABORT;
};
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))))
YYABORT;
};
keycache:
CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment