diff options
-rw-r--r-- | client/mysqltest.c | 8 | ||||
-rw-r--r-- | include/myisam.h | 2 | ||||
-rw-r--r-- | mysql-test/mysql-test-run.sh | 3 | ||||
-rw-r--r-- | mysql-test/r/lowercase2.require | 2 | ||||
-rw-r--r-- | mysql-test/r/lowercase_table2.result | 108 | ||||
-rw-r--r-- | mysql-test/t/lowercase_table2-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/lowercase_table2.test | 80 | ||||
-rw-r--r-- | sql/filesort.cc | 1 | ||||
-rw-r--r-- | sql/ha_berkeley.cc | 34 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 9 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 2 | ||||
-rw-r--r-- | sql/ha_isam.cc | 2 | ||||
-rw-r--r-- | sql/ha_isam.h | 2 | ||||
-rw-r--r-- | sql/ha_isammrg.h | 2 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 5 | ||||
-rw-r--r-- | sql/ha_myisam.h | 3 | ||||
-rw-r--r-- | sql/ha_myisammrg.cc | 4 | ||||
-rw-r--r-- | sql/ha_myisammrg.h | 2 | ||||
-rw-r--r-- | sql/handler.cc | 30 | ||||
-rw-r--r-- | sql/handler.h | 9 | ||||
-rw-r--r-- | sql/mysql_priv.h | 9 | ||||
-rw-r--r-- | sql/mysqld.cc | 36 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 10 | ||||
-rw-r--r-- | sql/sql_db.cc | 29 | ||||
-rw-r--r-- | sql/sql_insert.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 42 | ||||
-rw-r--r-- | sql/sql_rename.cc | 26 | ||||
-rw-r--r-- | sql/sql_show.cc | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 85 |
30 files changed, 421 insertions, 135 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index e3aa78c05df..13f575eaf0a 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -440,10 +440,10 @@ static void free_used_memory() my_free((gptr) (*q),MYF(0)); } for (i=0; i < 10; i++) - { - if (var_reg[i].alloced_len) - my_free(var_reg[i].str_val, MYF(MY_WME)); - } + { + if (var_reg[i].alloced_len) + my_free(var_reg[i].str_val, MYF(MY_WME)); + } while (embedded_server_arg_count > 1) my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); delete_dynamic(&q_lines); diff --git a/include/myisam.h b/include/myisam.h index 11dae5f59ba..87a40b50c73 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -91,7 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */ typedef struct st_mi_create_info { - char *index_file_name, *data_file_name; /* If using symlinks */ + const char *index_file_name, *data_file_name; /* If using symlinks */ ha_rows max_rows; ha_rows reloc_rows; ulonglong auto_increment; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index a298701dc7f..5b39b167d7d 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -182,7 +182,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log" # Set LD_LIBRARY_PATH if we are using shared libraries # LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH" -export LD_LIBRARY_PATH +DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$DYLD_LIBRARY_PATH" +export LD_LIBRARY_PATH DYLD_LIBRARY_PATH MASTER_RUNNING=0 MASTER_MYPORT=9306 diff --git a/mysql-test/r/lowercase2.require b/mysql-test/r/lowercase2.require new file mode 100644 index 00000000000..522eac63e81 --- /dev/null +++ b/mysql-test/r/lowercase2.require @@ -0,0 +1,2 @@ +Variable_name Value +lower_case_table_names 2 diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result new file mode 100644 index 00000000000..e582978c126 --- /dev/null +++ b/mysql-test/r/lowercase_table2.result @@ -0,0 +1,108 @@ +DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3; +DROP DATABASE IF EXISTS `TEST_$1`; +DROP DATABASE IF EXISTS `test_$1`; +CREATE TABLE T1 (a int); +INSERT INTO T1 VALUES (1); +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +T1 +SHOW TABLES LIKE "t1"; +Tables_in_test (t1) +T1 +SHOW CREATE TABLE T1; +Table Create Table +T1 CREATE TABLE `T1` ( + `a` int(11) default NULL +) TYPE=MyISAM +RENAME TABLE T1 TO T2; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +T2 +SELECT * FROM t2; +a +1 +RENAME TABLE T2 TO t3; +SHOW TABLES LIKE "T3"; +Tables_in_test (T3) +t3 +RENAME TABLE T3 TO T1; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +T1 +ALTER TABLE T1 add b int; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +t1 +ALTER TABLE T1 RENAME T2; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +T2 +LOCK TABLE T2 WRITE; +ALTER TABLE T2 drop b; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +t2 +UNLOCK TABLES; +RENAME TABLE T2 TO T1; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +T1 +SELECT * from T1; +a +1 +DROP TABLE T1; +CREATE DATABASE `TEST_$1`; +SHOW DATABASES LIKE "TEST%"; +Database (TEST%) +TEST_$1 +DROP DATABASE `test_$1`; +CREATE TABLE T1 (a int) engine=innodb; +INSERT INTO T1 VALUES (1); +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +T1 +SHOW TABLES LIKE "t1"; +Tables_in_test (t1) +T1 +SHOW CREATE TABLE T1; +Table Create Table +T1 CREATE TABLE `T1` ( + `a` int(11) default NULL +) TYPE=InnoDB +RENAME TABLE T1 TO T2; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +t2 +SELECT * FROM t2; +a +1 +RENAME TABLE T2 TO t3; +SHOW TABLES LIKE "T3"; +Tables_in_test (T3) +t3 +RENAME TABLE T3 TO T1; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +t1 +ALTER TABLE T1 add b int; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +t1 +ALTER TABLE T1 RENAME T2; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +t2 +LOCK TABLE T2 WRITE; +ALTER TABLE T2 drop b; +SHOW TABLES LIKE "T2"; +Tables_in_test (T2) +t2 +UNLOCK TABLES; +RENAME TABLE T2 TO T1; +SHOW TABLES LIKE "T1"; +Tables_in_test (T1) +t1 +SELECT * from T1; +a +1 +DROP TABLE T1; diff --git a/mysql-test/t/lowercase_table2-master.opt b/mysql-test/t/lowercase_table2-master.opt new file mode 100644 index 00000000000..9b27aef9bf8 --- /dev/null +++ b/mysql-test/t/lowercase_table2-master.opt @@ -0,0 +1 @@ +--lower_case_table_names=0 diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test new file mode 100644 index 00000000000..86bb26f0cf9 --- /dev/null +++ b/mysql-test/t/lowercase_table2.test @@ -0,0 +1,80 @@ +# +# Test of --lower-case-table-names=2 +# (User has case insensitive file system and want's to preserve case of +# table names) +# +--source include/have_innodb.inc +--require r/lowercase2.require +disable_query_log; +show variables like "lower_case_table_names"; +enable_query_log; + +--disable_warnings +DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3; +DROP DATABASE IF EXISTS `TEST_$1`; +DROP DATABASE IF EXISTS `test_$1`; +--enable_warnings + +CREATE TABLE T1 (a int); +INSERT INTO T1 VALUES (1); +SHOW TABLES LIKE "T1"; +SHOW TABLES LIKE "t1"; +SHOW CREATE TABLE T1; +RENAME TABLE T1 TO T2; +SHOW TABLES LIKE "T2"; +SELECT * FROM t2; +RENAME TABLE T2 TO t3; +SHOW TABLES LIKE "T3"; +RENAME TABLE T3 TO T1; +SHOW TABLES LIKE "T1"; +ALTER TABLE T1 add b int; +SHOW TABLES LIKE "T1"; +ALTER TABLE T1 RENAME T2; +SHOW TABLES LIKE "T2"; + +LOCK TABLE T2 WRITE; +ALTER TABLE T2 drop b; +SHOW TABLES LIKE "T2"; +UNLOCK TABLES; +RENAME TABLE T2 TO T1; +SHOW TABLES LIKE "T1"; +SELECT * from T1; +DROP TABLE T1; + +# +# Test database level +# + +CREATE DATABASE `TEST_$1`; +SHOW DATABASES LIKE "TEST%"; +DROP DATABASE `test_$1`; + +# +# Test of innodb tables with lower_case_table_names=2 +# + +CREATE TABLE T1 (a int) engine=innodb; +INSERT INTO T1 VALUES (1); +SHOW TABLES LIKE "T1"; +SHOW TABLES LIKE "t1"; +SHOW CREATE TABLE T1; +RENAME TABLE T1 TO T2; +SHOW TABLES LIKE "T2"; +SELECT * FROM t2; +RENAME TABLE T2 TO t3; +SHOW TABLES LIKE "T3"; +RENAME TABLE T3 TO T1; +SHOW TABLES LIKE "T1"; +ALTER TABLE T1 add b int; +SHOW TABLES LIKE "T1"; +ALTER TABLE T1 RENAME T2; +SHOW TABLES LIKE "T2"; + +LOCK TABLE T2 WRITE; +ALTER TABLE T2 drop b; +SHOW TABLES LIKE "T2"; +UNLOCK TABLES; +RENAME TABLE T2 TO T1; +SHOW TABLES LIKE "T1"; +SELECT * from T1; +DROP TABLE T1; diff --git a/sql/filesort.cc b/sql/filesort.cc index 439a72c42e4..ae6895b26b9 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -759,6 +759,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, sort_length)); if (error == -1) goto err; /* purecov: inspected */ + buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected queue_insert(&queue,(byte*) buffpek); } diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 6796a9c3306..15eb7fc72c6 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -544,7 +544,10 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) (*ptr)->set_bt_compare(*ptr, berkeley_cmp_packed_key); (*ptr)->app_private= (void*) (table->key_info+i); if (!(table->key_info[i].flags & HA_NOSAME)) + { + DBUG_PRINT("bdb",("Setting DB_DUP for key %u", i)); (*ptr)->set_flags(*ptr, DB_DUP); + } if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE, open_mode, 0)))) { @@ -1635,8 +1638,9 @@ void ha_berkeley::info(uint flag) share->rec_per_key[i]; } } - else if (flag & HA_STATUS_ERRKEY) - errkey=last_dup_key; + /* Don't return key if we got an error for the internal primary key */ + if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys) + errkey= last_dup_key; DBUG_VOID_RETURN; } @@ -1834,7 +1838,7 @@ static int create_sub_table(const char *table_name, const char *sub_name, int error; DB *file; DBUG_ENTER("create_sub_table"); - DBUG_PRINT("enter",("sub_name: %s",sub_name)); + DBUG_PRINT("enter",("sub_name: %s flags: %d",sub_name, flags)); if (!(error=db_create(&file, db_env, 0))) { @@ -1866,14 +1870,14 @@ int ha_berkeley::create(const char *name, register TABLE *form, char name_buff[FN_REFLEN]; char part[7]; uint index=1; - int error=1; + int error; DBUG_ENTER("ha_berkeley::create"); fn_format(name_buff,name,"", ha_berkeley_ext,2 | 4); /* Create the main table that will hold the real rows */ - if (create_sub_table(name_buff,"main",DB_BTREE,0)) - DBUG_RETURN(1); /* purecov: inspected */ + if ((error= create_sub_table(name_buff,"main",DB_BTREE,0))) + DBUG_RETURN(error); /* purecov: inspected */ primary_key=table->primary_key; /* Create the keys */ @@ -1882,10 +1886,10 @@ int ha_berkeley::create(const char *name, register TABLE *form, if (i != primary_key) { sprintf(part,"key%02d",index++); - if (create_sub_table(name_buff, part, DB_BTREE, - (table->key_info[i].flags & HA_NOSAME) ? 0 : - DB_DUP)) - DBUG_RETURN(1); /* purecov: inspected */ + if ((error= create_sub_table(name_buff, part, DB_BTREE, + (table->key_info[i].flags & HA_NOSAME) ? 0 : + DB_DUP))) + DBUG_RETURN(error); /* purecov: inspected */ } } @@ -1893,16 +1897,15 @@ int ha_berkeley::create(const char *name, register TABLE *form, /* Is DB_BTREE the best option here ? (QUEUE can't be used in sub tables) */ DB *status_block; - if (!db_create(&status_block, db_env, 0)) + if (!(error=(db_create(&status_block, db_env, 0)))) { - if (!status_block->open(status_block, name_buff, - "status", DB_BTREE, DB_CREATE, 0)) + if (!(error=(status_block->open(status_block, name_buff, + "status", DB_BTREE, DB_CREATE, 0)))) { char rec_buff[4+MAX_KEY*4]; uint length= 4+ table->keys*4; bzero(rec_buff, length); - if (!write_status(status_block, rec_buff, length)) - error=0; + error= write_status(status_block, rec_buff, length); status_block->close(status_block,0); } } @@ -1910,6 +1913,7 @@ int ha_berkeley::create(const char *name, register TABLE *form, } + int ha_berkeley::delete_table(const char *name) { int error; diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index d2dc5e3216d..285bb575699 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -88,10 +88,11 @@ class ha_berkeley: public handler public: ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), int_table_flags(HA_REC_NOT_IN_SEQ | - HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | - HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | - HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), + HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | + HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | + HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX | + HA_FILE_BASED), changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) { } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index beff8c1f515..bcd1130dcdb 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3394,7 +3394,7 @@ ha_innobase::create( /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, but we play safe here */ - return(HA_ERR_TO_BIG_ROW); + DBUG_RETURN(HA_ERR_TO_BIG_ROW); } /* Get the transaction associated with the current thd, or create one diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 7371628890f..a93bb25eb77 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -278,7 +278,7 @@ int ha_isam::create(const char *name, register TABLE *form, type=HA_KEYTYPE_BINARY; // Keep compiler happy if (!(recinfo= (N_RECINFO*) my_malloc((form->fields*2+2)*sizeof(N_RECINFO), MYF(MY_WME)))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); pos=form->key_info; for (i=0; i < form->keys ; i++, pos++) diff --git a/sql/ha_isam.h b/sql/ha_isam.h index 82a243ef5c0..b573d4b295c 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -34,7 +34,7 @@ class ha_isam: public handler :handler(table), file(0), int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_KEY_READ_WRONG_STR | HA_DUPP_POS | - HA_NOT_DELETE_WITH_CACHE) + HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED) {} ~ha_isam() {} const char *table_type() const { return "ISAM"; } diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h index c936a15164a..e5846d20212 100644 --- a/sql/ha_isammrg.h +++ b/sql/ha_isammrg.h @@ -33,7 +33,7 @@ class ha_isammrg: public handler const char *table_type() const { return "MRG_ISAM"; } const char **bas_ext() const; ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | - HA_REC_NOT_IN_SEQ); } + HA_REC_NOT_IN_SEQ | HA_FILE_BASED); } ulong index_flags(uint idx) const { return HA_NOT_READ_PREFIX_LAST; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 97c002cee52..d630e9774a5 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1054,9 +1054,10 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, &recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF), &keydef, table_arg->keys*sizeof(MI_KEYDEF), &keyseg, - ((table_arg->key_parts + table_arg->keys) * sizeof(MI_KEYSEG)), + ((table_arg->key_parts + table_arg->keys) * + sizeof(MI_KEYSEG)), NullS))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); pos=table_arg->key_info; for (i=0; i < table_arg->keys ; i++, pos++) diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 215608f8f0a..212850d8f28 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -46,7 +46,8 @@ class ha_myisam: public handler ha_myisam(TABLE *table): handler(table), file(0), int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | - HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY), + HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY | + HA_FILE_BASED), enable_activate_all_index(1) {} ~ha_myisam() {} diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 616248b2cf3..f65c9afc786 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -343,7 +343,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, if (!(table_names= (char**) sql_alloc((create_info->merge_list.elements+1)* sizeof(char*)))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); for (pos=table_names ; tables ; tables=tables->next) { char *table_name; @@ -357,7 +357,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, my_snprintf(buff,FN_REFLEN,"%s/%s/%s",mysql_real_data_home, tables->db, tables->real_name)); if (!table_name) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); strcpy(table_name, buff); } else diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index dd649fe8fcb..db3c20bede2 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -36,7 +36,7 @@ class ha_myisammrg: public handler { return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_BLOB_KEY); + HA_NULL_KEY | HA_BLOB_KEY | HA_FILE_BASED); } ulong index_flags(uint inx) const { diff --git a/sql/handler.cc b/sql/handler.cc index 56cbddff66b..f0756aceadb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -584,14 +584,23 @@ bool ha_flush_logs() int ha_delete_table(enum db_type table_type, const char *path) { + char tmp_path[FN_REFLEN]; handler *file=get_new_handler((TABLE*) 0, table_type); if (!file) return ENOENT; + if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) + { + /* Ensure that table handler get path in lower case */ + strmov(tmp_path, path); + casedn_str(tmp_path); + path= tmp_path; + } int error=file->delete_table(path); delete file; return error; } + void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos) { switch (pack_length) { @@ -1043,6 +1052,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, { int error; TABLE table; + char name_buff[FN_REFLEN]; DBUG_ENTER("ha_create_table"); if (openfrm(name,"",0,(uint) READ_ALL, 0, &table)) @@ -1053,19 +1063,19 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, if (table.file->table_flags() & HA_DROP_BEFORE_CREATE) table.file->delete_table(name); // Needed for BDB tables } + if (lower_case_table_names == 2 && + !(table.file->table_flags() & HA_FILE_BASED)) + { + /* Ensure that handler gets name in lower case */ + strmov(name_buff, name); + casedn_str(name_buff); + name= name_buff; + } + error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) - { - if (table.db_type == DB_TYPE_INNODB) - { - /* Creation of InnoDB table cannot fail because of an OS error: - put error as the number */ - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); - } - else - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno); - } + my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); DBUG_RETURN(error != 0); } diff --git a/sql/handler.h b/sql/handler.h index 03568e2e070..8e72267c337 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -67,12 +67,14 @@ #define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2) #define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2) #define HA_NO_AUTO_INCREMENT (HA_CAN_SQL_HANDLER*2) +/* Table data are stored in separate files */ +#define HA_FILE_BASED (HA_NO_AUTO_INCREMENT*2) /* Next record gives next record according last record read (even if database is updated after read). Not used at this point. */ -#define HA_LASTKEY_ORDER (HA_NO_AUTO_INCREMENT*2) +#define HA_LASTKEY_ORDER (HA_FILE_BASED*2) /* bits in index_flags(index_number) for what you can do with index */ @@ -149,8 +151,9 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { - char *comment,*password; - char *data_file_name, *index_file_name; + const char *comment,*password; + const char *data_file_name, *index_file_name; + const char *alias; ulonglong max_rows,min_rows; ulonglong auto_increment_value; ulong table_options; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d0e0e6992fa..acb7005c26c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -696,7 +696,7 @@ extern ulong specialflag, current_pid; extern uint test_flags,select_errors,ha_open_options; extern uint protocol_version,dropping_tables; -extern uint delay_key_write_options; +extern uint delay_key_write_options, lower_case_table_names; extern bool opt_endinfo, using_udf_functions, locked_in_memory; extern bool opt_using_transactions, mysql_embedded; extern bool using_update_log, opt_large_files; @@ -705,7 +705,7 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool volatile abort_loop, shutdown_in_progress, grant_option; extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; -extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names; +extern my_bool opt_safe_show_db, opt_local_infile; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern my_bool opt_readonly; extern my_bool opt_enable_named_pipe; @@ -894,3 +894,8 @@ inline void table_case_convert(char * name, uint length) if (lower_case_table_names) casedn(name, length); } + +inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) +{ + return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); +} diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a58f3b973ac..e1c7ecd3e4b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -290,6 +290,7 @@ bool opt_disable_networking=0, opt_skip_show_db=0; my_bool opt_enable_named_pipe= 0, opt_debugging= 0; my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; uint delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; +uint lower_case_table_names; static my_bool opt_do_pstack = 0; static ulong opt_specialflag=SPECIAL_ENGLISH; @@ -305,7 +306,7 @@ char* log_error_file_ptr= log_error_file; static pthread_t select_thread; static my_bool opt_noacl=0, opt_bootstrap=0, opt_myisam_log=0; my_bool opt_safe_user_create = 0, opt_no_mix_types = 0; -my_bool lower_case_table_names, opt_old_rpl_compat; +my_bool opt_old_rpl_compat; my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; my_bool opt_log_slave_updates= 0, opt_console= 0; my_bool opt_readonly = 0; @@ -2097,6 +2098,18 @@ int main(int argc, char **argv) exit(1); charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); + /* + Ensure that lower_case_table_names is set on system where we have case + insensitive names. If this is not done the users MyISAM tables will + get corrupted if accesses with names of different case. + */ + if (!lower_case_table_names && + test_if_case_insensitive(mysql_real_data_home) == 1) + { + sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); + lower_case_table_names= 2; + } + #ifdef HAVE_OPENSSL if (opt_use_ssl) { @@ -3841,15 +3854,15 @@ replicating a LOAD DATA INFILE command", (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG, REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, - "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.", + "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system", (gptr*) &lower_case_table_names, - (gptr*) &lower_case_table_names, 0, GET_BOOL, NO_ARG, + (gptr*) &lower_case_table_names, 0, GET_UINT, OPT_ARG, #ifdef FN_NO_CASE_SENCE 1 #else 0 #endif - , 0, 1, 0, 1, 0}, + , 0, 2, 0, 1, 0}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "Max packetlength to send/receive from to server.", (gptr*) &global_system_variables.max_allowed_packet, @@ -4814,6 +4827,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), sf_malloc_quick=1; #endif break; + case OPT_LOWER_CASE_TABLE_NAMES: + lower_case_table_names= argument ? atoi(argument) : 1; + break; } return 0; } @@ -4946,18 +4962,6 @@ static void fix_paths(void) if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) exit(1); } - - /* - Ensure that lower_case_table_names is set on system where we have case - insensitive names. If this is not done the users MyISAM tables will - get corrupted if accesses with names of different case. - */ - if (!lower_case_table_names && - test_if_case_insensitive(mysql_real_data_home) == 1) - { - sql_print_error("Warning: Setting lower_case_table_names=1 becasue file system %s is case insensitive", mysql_real_data_home); - lower_case_table_names= 1; - } } diff --git a/sql/set_var.cc b/sql/set_var.cc index 4aea611e401..70e56825467 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -514,7 +514,7 @@ struct show_var_st init_vars[]= { {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS}, {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS}, {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS}, - {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_MY_BOOL}, + {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_INT}, {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet, SHOW_SYS}, {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS}, {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 632e7b49d9f..f4fc7b4770f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -732,11 +732,11 @@ class select_create: public select_insert { MYSQL_LOCK *lock; Field **field; public: - select_create (const char *db_name, const char *table_name, - HA_CREATE_INFO *create_info_par, - List<create_field> &fields_par, - List<Key> &keys_par, - List<Item> &select_fields,enum_duplicates duplic) + select_create(const char *db_name, const char *table_name, + HA_CREATE_INFO *create_info_par, + List<create_field> &fields_par, + List<Key> &keys_par, + List<Item> &select_fields,enum_duplicates duplic) :select_insert (NULL, &select_fields, duplic), db(db_name), name(table_name), extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), lock(0) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6c11067ac8f..3fa3f5b0907 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -116,12 +116,21 @@ const char *known_exts[]= static TYPELIB known_extentions= {array_elements(known_exts)-1,"known_exts", known_exts}; -/* - Drop all tables in a database. - db-name is already validated when we come here - If thd == 0, do not write any messages; This is useful in replication - when we want to remove a stale database before replacing it with the new one +/* + Drop all tables in a database and the database itself + + SYNOPSIS + mysql_rm_db() + thd Thread handle + db Database name in the case given by user + It's already validated when we come here + if_exists Don't give error if database doesn't exists + silent Don't generate errors + + RETURN + 0 ok (Database dropped) + -1 Error generated */ @@ -129,7 +138,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { long deleted=0; int error = 0; - char path[FN_REFLEN+16]; + char path[FN_REFLEN+16], tmp_db[NAME_LEN+1]; MY_DIR *dirp; DBUG_ENTER("mysql_rm_db"); @@ -156,6 +165,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) send_ok(&thd->net,0); goto exit; } + if (lower_case_table_names) + { + /* Convert database to lower case */ + strmov(tmp_db, db); + casedn_str(tmp_db); + db= tmp_db; + } + pthread_mutex_lock(&LOCK_open); remove_db_from_cache(db); pthread_mutex_unlock(&LOCK_open); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 75a37e4035c..97b7c1db03d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1434,8 +1434,8 @@ select_create::prepare(List<Item> &values) { DBUG_ENTER("select_create::prepare"); - table=create_table_from_items(thd, create_info, db, name, - extra_fields, keys, &values, &lock); + table= create_table_from_items(thd, create_info, db, name, + extra_fields, keys, &values, &lock); if (!table) DBUG_RETURN(-1); // abort() deletes table diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5c08127bfdc..608cdd23282 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -59,8 +59,8 @@ static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static void mysql_init_query(THD *thd); static void remove_escape(char *name); static void refresh_status(void); -static bool append_file_to_dir(THD *thd, char **filename_ptr, - char *table_name); +static bool append_file_to_dir(THD *thd, const char **filename_ptr, + const char *table_name); static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result, bool skip_first); @@ -1121,10 +1121,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CREATE_DB: // QQ: To be removed { + char *db=thd->strdup(packet), *alias; + statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); - char *db=thd->strdup(packet); // null test to handle EOM - if (!db || !strip_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) || + check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1132,15 +1134,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(thd,command,packet); - mysql_create_db(thd,db,0,0); + mysql_create_db(thd,(lower_case_table_names == 2 ? alias : db),0,0); break; } case COM_DROP_DB: // QQ: To be removed { statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); - char *db=thd->strdup(packet); + char *db=thd->strdup(packet), *alias; // null test to handle EOM - if (!db || !strip_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) || + check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1153,7 +1156,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } mysql_log.write(thd,command,db); - mysql_rm_db(thd,db,0,0); + mysql_rm_db(thd,alias,0,0); break; } case COM_BINLOG_DUMP: @@ -1599,6 +1602,7 @@ mysql_execute_command(void) CREATE_TMP_ACL : CREATE_ACL); if (!tables->db) tables->db=thd->db; + lex->create_info.alias= tables->alias; if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) || check_merge_table_access(thd, tables->db, (TABLE_LIST *) @@ -1664,7 +1668,8 @@ mysql_execute_command(void) if (!(res=open_and_lock_tables(thd,tables->next))) { if ((result=new select_create(tables->db ? tables->db : thd->db, - tables->real_name, &lex->create_info, + tables->real_name, + &lex->create_info, lex->create_list, lex->key_list, select_lex->item_list,lex->duplicates))) @@ -1676,7 +1681,8 @@ mysql_execute_command(void) else // regular create { res = mysql_create_table(thd,tables->db ? tables->db : thd->db, - tables->real_name, &lex->create_info, + tables->real_name, + &lex->create_info, lex->create_list, lex->key_list,0, 0); // do logging if (!res) @@ -2341,7 +2347,9 @@ mysql_execute_command(void) break; case SQLCOM_CREATE_DB: { - if (!strip_sp(lex->name) || check_db_name(lex->name)) + char *alias; + if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) || + check_db_name(lex->name)) { net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; @@ -2363,12 +2371,15 @@ mysql_execute_command(void) if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; - res=mysql_create_db(thd,lex->name,lex->create_info.options,0); + res=mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name), + lex->create_info.options,0); break; } case SQLCOM_DROP_DB: { - if (!strip_sp(lex->name) || check_db_name(lex->name)) + char *alias; + if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) || + check_db_name(lex->name)) { net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; @@ -2394,7 +2405,7 @@ mysql_execute_command(void) send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } - res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0); + res=mysql_rm_db(thd,alias,lex->drop_if_exists,0); break; } case SQLCOM_CREATE_FUNCTION: @@ -3779,7 +3790,8 @@ static void refresh_status(void) /* If pointer is not a null pointer, append filename to it */ -static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) +static bool append_file_to_dir(THD *thd, const char **filename_ptr, + const char *table_name) { char buff[FN_REFLEN],*ptr, *end; if (!*filename_ptr) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 05d31c173d3..c560b96a615 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -112,19 +112,31 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { db_type table_type; char name[FN_REFLEN]; - new_table=ren_table->next; + const char *new_alias, *old_alias; + new_table=ren_table->next; + if (lower_case_table_names == 2) + { + old_alias= ren_table->alias; + new_alias= new_table->alias; + } + else + { + old_alias= ren_table->real_name; + new_alias= new_table->real_name; + } sprintf(name,"%s/%s/%s%s",mysql_data_home, - new_table->db,new_table->real_name, - reg_ext); + new_table->db, new_alias, reg_ext); + unpack_filename(name, name); if (!access(name,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_alias); DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, - ren_table->db,ren_table->real_name, + ren_table->db, old_alias, reg_ext); + unpack_filename(name, name); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN) { my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); @@ -132,8 +144,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) DBUG_RETURN(ren_table); } else if (mysql_rename_table(table_type, - ren_table->db, ren_table->real_name, - new_table->db, new_table->real_name)) + ren_table->db, old_alias, + new_table->db, new_alias)) { if (!skip_error) DBUG_RETURN(ren_table); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1a2f900eb7e..d34e2e68067 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -865,7 +865,9 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append("CREATE TEMPORARY TABLE ", 23); else packet->append("CREATE TABLE ", 13); - append_identifier(thd,packet,table->real_name); + append_identifier(thd,packet, + (lower_case_table_names == 2 ? table->table_name : + table->real_name)); packet->append(" (\n", 3); for (ptr=table->field ; (field= *ptr); ptr++) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2833946fe3b..7fa973eb60f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -163,7 +163,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN]; + char path[FN_REFLEN], *alias; String wrong_tables; db_type table_type; int error; @@ -193,15 +193,12 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, drop_locked_tables(thd,db,table->real_name); if (thd->killed) DBUG_RETURN(-1); - + alias= (lower_case_table_names == 2) ? table->alias : table->real_name; /* remove form file and isam files */ - strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext, - NullS); + strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS); (void) unpack_filename(path,path); error=0; - table_type=get_table_type(path); - if (access(path,F_OK)) { if (!if_exists) @@ -210,7 +207,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; - *(end=fn_ext(path))=0; // Remove extension + table_type= get_table_type(path); + *(end=fn_ext(path))=0; // Remove extension for delete error=ha_delete_table(table_type, path); if (error == ENOENT && if_exists) error = 0; @@ -350,7 +348,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, List<Key> &keys,bool tmp_table,bool no_log) { char path[FN_REFLEN]; - const char *key_name; + const char *key_name, *alias; create_field *sql_field,*dup_field; int error= -1; uint db_options,field,null_fields,blob_columns; @@ -361,10 +359,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, handler *file; DBUG_ENTER("mysql_create_table"); - /* - ** Check for duplicate fields and check type of table to create - */ - + /* Check for duplicate fields and check type of table to create */ if (!fields.elements) { my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); @@ -375,6 +370,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, db_options=create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) db_options|=HA_OPTION_PACK_RECORD; + alias= table_case_name(create_info, table_name); file=get_new_handler((TABLE*) 0, create_info->db_type); if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && @@ -722,7 +718,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; } else - (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext); + (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,alias,reg_ext); unpack_filename(path,path); /* Check if table already exists */ if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) @@ -747,7 +743,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); } - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0), alias); DBUG_RETURN(-1); } } @@ -873,7 +869,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(0); if (!(table=open_table(thd,db,name,name,(bool*) 0))) { - quick_rm_table(create_info->db_type,db,name); + quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); DBUG_RETURN(0); } table->reginfo.lock_type=TL_WRITE; @@ -882,7 +878,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, VOID(pthread_mutex_lock(&LOCK_open)); hash_delete(&open_cache,(byte*) table); VOID(pthread_mutex_unlock(&LOCK_open)); - quick_rm_table(create_info->db_type,db,name); + quick_rm_table(create_info->db_type,db,table_case_name(create_info, name)); DBUG_RETURN(0); } table->file->extra(HA_EXTRA_WRITE_CACHE); @@ -897,18 +893,32 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, bool mysql_rename_table(enum db_type base, const char *old_db, - const char * old_name, + const char *old_name, const char *new_db, - const char * new_name) + const char *new_name) { - char from[FN_REFLEN],to[FN_REFLEN]; + char from[FN_REFLEN], to[FN_REFLEN]; + char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1]; handler *file=get_new_handler((TABLE*) 0, base); int error=0; DBUG_ENTER("mysql_rename_table"); + + if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) + { + /* Table handler expects to get all file names as lower case */ + strmov(tmp_from, old_name); + casedn_str(tmp_from); + old_name= tmp_from; + + strmov(tmp_to, new_name); + casedn_str(tmp_to); + new_name= tmp_to; + } (void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name); (void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name); fn_format(from,from,"","",4); fn_format(to,to, "","",4); + if (!(error=file->rename_table((const char*) from,(const char *) to))) { if (rename_file_ext(from,to,reg_ext)) @@ -924,6 +934,7 @@ mysql_rename_table(enum db_type base, DBUG_RETURN(error != 0); } + /* Force all other threads to stop using the table @@ -968,7 +979,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, Close a cached table SYNOPSIS - clsoe_cached_table() + close_cached_table() thd Thread handler table Table to remove from cache @@ -1446,8 +1457,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { TABLE *table,*new_table; int error; - char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN], - *table_name,*db; + char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; + char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; bool use_timestamp=0; ha_rows copied,deleted; @@ -1458,11 +1469,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->proc_info="init"; table_name=table_list->real_name; + alias= (lower_case_table_names == 2) ? table_list->alias : table_name; + db=table_list->db; if (!new_db || !strcmp(new_db,db)) new_db=db; used_fields=create_info->used_fields; - + mysql_ha_closeall(thd, table_list); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -1471,21 +1484,29 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (new_name) { strmov(new_name_buff,new_name); + strmov(new_alias= new_alias_buff, new_name); fn_same(new_name_buff,table_name,3); if (lower_case_table_names) + { + if (lower_case_table_names != 2) + { + casedn_str(new_name_buff); + new_alias= new_name; // Create lower case table name + } casedn_str(new_name); + } if ((lower_case_table_names && !my_strcasecmp(new_name_buff,table_name)) || (!lower_case_table_names && !strcmp(new_name_buff,table_name))) - new_name=table_name; // No. Make later check easier + new_alias= new_name= table_name; // No change. Make later check easier else { if (table->tmp_table) { if (find_temporary_table(thd,new_db,new_name_buff)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); DBUG_RETURN(-1); } } @@ -1495,14 +1516,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, F_OK)) { /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); DBUG_RETURN(-1); } } } } else - new_name=table_name; + new_alias= new_name= table_name; old_db_type=table->db_type; if (create_info->db_type == DB_TYPE_DEFAULT) @@ -1532,7 +1553,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { *fn_ext(new_name)=0; close_cached_table(thd, table); - if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name)) + if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) error= -1; } VOID(pthread_mutex_unlock(&LOCK_open)); @@ -1925,7 +1946,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* Remove link to old table and rename the new one */ close_temporary_table(thd,table->table_cache_key,table_name); - if (rename_temporary_table(thd, new_table, new_db, new_name)) + if (rename_temporary_table(thd, new_table, new_db, new_alias)) { // Fatal error close_temporary_table(thd,new_db,tmp_name); my_free((gptr) new_table,MYF(0)); @@ -2001,12 +2022,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, VOID(quick_rm_table(new_db_type,new_db,tmp_name)); } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, - new_name)) + new_alias)) { // Try to get everything back error=1; - VOID(quick_rm_table(new_db_type,new_db,new_name)); + VOID(quick_rm_table(new_db_type,new_db,new_alias)); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); - VOID(mysql_rename_table(old_db_type,db,old_name,db,table_name)); + VOID(mysql_rename_table(old_db_type,db,old_name,db,alias)); } if (error) { |