summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqltest.c8
-rw-r--r--include/myisam.h2
-rw-r--r--mysql-test/mysql-test-run.sh3
-rw-r--r--mysql-test/r/lowercase2.require2
-rw-r--r--mysql-test/r/lowercase_table2.result108
-rw-r--r--mysql-test/t/lowercase_table2-master.opt1
-rw-r--r--mysql-test/t/lowercase_table2.test80
-rw-r--r--sql/filesort.cc1
-rw-r--r--sql/ha_berkeley.cc34
-rw-r--r--sql/ha_berkeley.h9
-rw-r--r--sql/ha_innodb.cc2
-rw-r--r--sql/ha_isam.cc2
-rw-r--r--sql/ha_isam.h2
-rw-r--r--sql/ha_isammrg.h2
-rw-r--r--sql/ha_myisam.cc5
-rw-r--r--sql/ha_myisam.h3
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/ha_myisammrg.h2
-rw-r--r--sql/handler.cc30
-rw-r--r--sql/handler.h9
-rw-r--r--sql/mysql_priv.h9
-rw-r--r--sql/mysqld.cc36
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_db.cc29
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/sql_parse.cc42
-rw-r--r--sql/sql_rename.cc26
-rw-r--r--sql/sql_show.cc4
-rw-r--r--sql/sql_table.cc85
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)
{