Commit c1dd070b authored by monty@mysql.com's avatar monty@mysql.com

Some small portability fixes.

Added support for lower_case_table_names=2, which is to be used on case insensitive file systems.
This tells MySQL to preserve the used case of filenames and database names to make it esier to move files between cases sensitive can case insensitive file systems (like Windows and Linux)
parent 57d48132
...@@ -440,10 +440,10 @@ static void free_used_memory() ...@@ -440,10 +440,10 @@ static void free_used_memory()
my_free((gptr) (*q),MYF(0)); my_free((gptr) (*q),MYF(0));
} }
for (i=0; i < 10; i++) for (i=0; i < 10; i++)
{ {
if (var_reg[i].alloced_len) if (var_reg[i].alloced_len)
my_free(var_reg[i].str_val, MYF(MY_WME)); my_free(var_reg[i].str_val, MYF(MY_WME));
} }
while (embedded_server_arg_count > 1) while (embedded_server_arg_count > 1)
my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
delete_dynamic(&q_lines); delete_dynamic(&q_lines);
......
...@@ -91,7 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */ ...@@ -91,7 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
typedef struct st_mi_create_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 max_rows;
ha_rows reloc_rows; ha_rows reloc_rows;
ulonglong auto_increment; ulonglong auto_increment;
......
...@@ -182,7 +182,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log" ...@@ -182,7 +182,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
# Set LD_LIBRARY_PATH if we are using shared libraries # Set LD_LIBRARY_PATH if we are using shared libraries
# #
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH" 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_RUNNING=0
MASTER_MYPORT=9306 MASTER_MYPORT=9306
......
Variable_name Value
lower_case_table_names 2
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;
#
# 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;
...@@ -759,6 +759,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, ...@@ -759,6 +759,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
sort_length)); sort_length));
if (error == -1) if (error == -1)
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
queue_insert(&queue,(byte*) buffpek); queue_insert(&queue,(byte*) buffpek);
} }
......
...@@ -544,7 +544,10 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) ...@@ -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)->set_bt_compare(*ptr, berkeley_cmp_packed_key);
(*ptr)->app_private= (void*) (table->key_info+i); (*ptr)->app_private= (void*) (table->key_info+i);
if (!(table->key_info[i].flags & HA_NOSAME)) if (!(table->key_info[i].flags & HA_NOSAME))
{
DBUG_PRINT("bdb",("Setting DB_DUP for key %u", i));
(*ptr)->set_flags(*ptr, DB_DUP); (*ptr)->set_flags(*ptr, DB_DUP);
}
if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE, if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE,
open_mode, 0)))) open_mode, 0))))
{ {
...@@ -1635,8 +1638,9 @@ void ha_berkeley::info(uint flag) ...@@ -1635,8 +1638,9 @@ void ha_berkeley::info(uint flag)
share->rec_per_key[i]; share->rec_per_key[i];
} }
} }
else if (flag & HA_STATUS_ERRKEY) /* Don't return key if we got an error for the internal primary key */
errkey=last_dup_key; if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys)
errkey= last_dup_key;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1834,7 +1838,7 @@ static int create_sub_table(const char *table_name, const char *sub_name, ...@@ -1834,7 +1838,7 @@ static int create_sub_table(const char *table_name, const char *sub_name,
int error; int error;
DB *file; DB *file;
DBUG_ENTER("create_sub_table"); 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))) if (!(error=db_create(&file, db_env, 0)))
{ {
...@@ -1866,14 +1870,14 @@ int ha_berkeley::create(const char *name, register TABLE *form, ...@@ -1866,14 +1870,14 @@ int ha_berkeley::create(const char *name, register TABLE *form,
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
char part[7]; char part[7];
uint index=1; uint index=1;
int error=1; int error;
DBUG_ENTER("ha_berkeley::create"); DBUG_ENTER("ha_berkeley::create");
fn_format(name_buff,name,"", ha_berkeley_ext,2 | 4); fn_format(name_buff,name,"", ha_berkeley_ext,2 | 4);
/* Create the main table that will hold the real rows */ /* Create the main table that will hold the real rows */
if (create_sub_table(name_buff,"main",DB_BTREE,0)) if ((error= create_sub_table(name_buff,"main",DB_BTREE,0)))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(error); /* purecov: inspected */
primary_key=table->primary_key; primary_key=table->primary_key;
/* Create the keys */ /* Create the keys */
...@@ -1882,10 +1886,10 @@ int ha_berkeley::create(const char *name, register TABLE *form, ...@@ -1882,10 +1886,10 @@ int ha_berkeley::create(const char *name, register TABLE *form,
if (i != primary_key) if (i != primary_key)
{ {
sprintf(part,"key%02d",index++); sprintf(part,"key%02d",index++);
if (create_sub_table(name_buff, part, DB_BTREE, if ((error= create_sub_table(name_buff, part, DB_BTREE,
(table->key_info[i].flags & HA_NOSAME) ? 0 : (table->key_info[i].flags & HA_NOSAME) ? 0 :
DB_DUP)) DB_DUP)))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(error); /* purecov: inspected */
} }
} }
...@@ -1893,16 +1897,15 @@ int ha_berkeley::create(const char *name, register TABLE *form, ...@@ -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) */ /* Is DB_BTREE the best option here ? (QUEUE can't be used in sub tables) */
DB *status_block; 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, if (!(error=(status_block->open(status_block, name_buff,
"status", DB_BTREE, DB_CREATE, 0)) "status", DB_BTREE, DB_CREATE, 0))))
{ {
char rec_buff[4+MAX_KEY*4]; char rec_buff[4+MAX_KEY*4];
uint length= 4+ table->keys*4; uint length= 4+ table->keys*4;
bzero(rec_buff, length); bzero(rec_buff, length);
if (!write_status(status_block, rec_buff, length)) error= write_status(status_block, rec_buff, length);
error=0;
status_block->close(status_block,0); status_block->close(status_block,0);
} }
} }
...@@ -1910,6 +1913,7 @@ int ha_berkeley::create(const char *name, register TABLE *form, ...@@ -1910,6 +1913,7 @@ int ha_berkeley::create(const char *name, register TABLE *form,
} }
int ha_berkeley::delete_table(const char *name) int ha_berkeley::delete_table(const char *name)
{ {
int error; int error;
......
...@@ -88,10 +88,11 @@ class ha_berkeley: public handler ...@@ -88,10 +88,11 @@ class ha_berkeley: public handler
public: public:
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
int_table_flags(HA_REC_NOT_IN_SEQ | int_table_flags(HA_REC_NOT_IN_SEQ |
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), 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) changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
{ {
} }
......
...@@ -3394,7 +3394,7 @@ ha_innobase::create( ...@@ -3394,7 +3394,7 @@ ha_innobase::create(
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
but we play safe here */ 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 /* Get the transaction associated with the current thd, or create one
......
...@@ -278,7 +278,7 @@ int ha_isam::create(const char *name, register TABLE *form, ...@@ -278,7 +278,7 @@ int ha_isam::create(const char *name, register TABLE *form,
type=HA_KEYTYPE_BINARY; // Keep compiler happy type=HA_KEYTYPE_BINARY; // Keep compiler happy
if (!(recinfo= (N_RECINFO*) my_malloc((form->fields*2+2)*sizeof(N_RECINFO), if (!(recinfo= (N_RECINFO*) my_malloc((form->fields*2+2)*sizeof(N_RECINFO),
MYF(MY_WME)))) MYF(MY_WME))))
DBUG_RETURN(1); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
pos=form->key_info; pos=form->key_info;
for (i=0; i < form->keys ; i++, pos++) for (i=0; i < form->keys ; i++, pos++)
......
...@@ -34,7 +34,7 @@ class ha_isam: public handler ...@@ -34,7 +34,7 @@ class ha_isam: public handler
:handler(table), file(0), :handler(table), file(0),
int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
HA_KEY_READ_WRONG_STR | HA_DUPP_POS | HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
HA_NOT_DELETE_WITH_CACHE) HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED)
{} {}
~ha_isam() {} ~ha_isam() {}
const char *table_type() const { return "ISAM"; } const char *table_type() const { return "ISAM"; }
......
...@@ -33,7 +33,7 @@ class ha_isammrg: public handler ...@@ -33,7 +33,7 @@ class ha_isammrg: public handler
const char *table_type() const { return "MRG_ISAM"; } const char *table_type() const { return "MRG_ISAM"; }
const char **bas_ext() const; const char **bas_ext() const;
ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | 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; } ulong index_flags(uint idx) const { return HA_NOT_READ_PREFIX_LAST; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_record_length() const { return HA_MAX_REC_LENGTH; }
......
...@@ -1054,9 +1054,10 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, ...@@ -1054,9 +1054,10 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
&recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF), &recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF),
&keydef, table_arg->keys*sizeof(MI_KEYDEF), &keydef, table_arg->keys*sizeof(MI_KEYDEF),
&keyseg, &keyseg,
((table_arg->key_parts + table_arg->keys) * sizeof(MI_KEYSEG)), ((table_arg->key_parts + table_arg->keys) *
sizeof(MI_KEYSEG)),
NullS))) NullS)))
DBUG_RETURN(1); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
pos=table_arg->key_info; pos=table_arg->key_info;
for (i=0; i < table_arg->keys ; i++, pos++) for (i=0; i < table_arg->keys ; i++, pos++)
......
...@@ -46,7 +46,8 @@ class ha_myisam: public handler ...@@ -46,7 +46,8 @@ class ha_myisam: public handler
ha_myisam(TABLE *table): handler(table), file(0), ha_myisam(TABLE *table): handler(table), file(0),
int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | 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_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) enable_activate_all_index(1)
{} {}
~ha_myisam() {} ~ha_myisam() {}
......
...@@ -343,7 +343,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, ...@@ -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)* if (!(table_names= (char**) sql_alloc((create_info->merge_list.elements+1)*
sizeof(char*)))) sizeof(char*))))
DBUG_RETURN(1); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
for (pos=table_names ; tables ; tables=tables->next) for (pos=table_names ; tables ; tables=tables->next)
{ {
char *table_name; char *table_name;
...@@ -357,7 +357,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, ...@@ -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, my_snprintf(buff,FN_REFLEN,"%s/%s/%s",mysql_real_data_home,
tables->db, tables->real_name)); tables->db, tables->real_name));
if (!table_name) if (!table_name)
DBUG_RETURN(1); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
strcpy(table_name, buff); strcpy(table_name, buff);
} }
else else
......
...@@ -36,7 +36,7 @@ class ha_myisammrg: public handler ...@@ -36,7 +36,7 @@ class ha_myisammrg: public handler
{ {
return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY | return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY |
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | 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 ulong index_flags(uint inx) const
{ {
......
...@@ -584,14 +584,23 @@ bool ha_flush_logs() ...@@ -584,14 +584,23 @@ bool ha_flush_logs()
int ha_delete_table(enum db_type table_type, const char *path) 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); handler *file=get_new_handler((TABLE*) 0, table_type);
if (!file) if (!file)
return ENOENT; 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); int error=file->delete_table(path);
delete file; delete file;
return error; return error;
} }
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos) void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos)
{ {
switch (pack_length) { switch (pack_length) {
...@@ -1043,6 +1052,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, ...@@ -1043,6 +1052,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
{ {
int error; int error;
TABLE table; TABLE table;
char name_buff[FN_REFLEN];
DBUG_ENTER("ha_create_table"); DBUG_ENTER("ha_create_table");
if (openfrm(name,"",0,(uint) READ_ALL, 0, &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, ...@@ -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) if (table.file->table_flags() & HA_DROP_BEFORE_CREATE)
table.file->delete_table(name); // Needed for BDB tables 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); error=table.file->create(name,&table,create_info);
VOID(closefrm(&table)); VOID(closefrm(&table));
if (error) if (error)
{ my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,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);
}
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);
} }
......
...@@ -67,12 +67,14 @@ ...@@ -67,12 +67,14 @@
#define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2) #define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2)
#define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2) #define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2)
#define HA_NO_AUTO_INCREMENT (HA_CAN_SQL_HANDLER*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 Next record gives next record according last record read (even
if database is updated after read). Not used at this point. 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 */ /* 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, ...@@ -149,8 +151,9 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
typedef struct st_ha_create_information typedef struct st_ha_create_information
{ {
char *comment,*password; const char *comment,*password;
char *data_file_name, *index_file_name; const char *data_file_name, *index_file_name;
const char *alias;
ulonglong max_rows,min_rows; ulonglong max_rows,min_rows;
ulonglong auto_increment_value; ulonglong auto_increment_value;
ulong table_options; ulong table_options;
......
...@@ -696,7 +696,7 @@ extern ulong specialflag, current_pid; ...@@ -696,7 +696,7 @@ extern ulong specialflag, current_pid;
extern uint test_flags,select_errors,ha_open_options; extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version,dropping_tables; 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_endinfo, using_udf_functions, locked_in_memory;
extern bool opt_using_transactions, mysql_embedded; extern bool opt_using_transactions, mysql_embedded;
extern bool using_update_log, opt_large_files; extern bool using_update_log, opt_large_files;
...@@ -705,7 +705,7 @@ extern bool opt_disable_networking, opt_skip_show_db; ...@@ -705,7 +705,7 @@ extern bool opt_disable_networking, opt_skip_show_db;
extern bool volatile abort_loop, shutdown_in_progress, grant_option; extern bool volatile abort_loop, shutdown_in_progress, grant_option;
extern uint volatile thread_count, thread_running, global_read_lock; 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_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_slave_compressed_protocol, use_temp_pool;
extern my_bool opt_readonly; extern my_bool opt_readonly;
extern my_bool opt_enable_named_pipe; extern my_bool opt_enable_named_pipe;
...@@ -894,3 +894,8 @@ inline void table_case_convert(char * name, uint length) ...@@ -894,3 +894,8 @@ inline void table_case_convert(char * name, uint length)
if (lower_case_table_names) if (lower_case_table_names)
casedn(name, length); 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);
}
...@@ -290,6 +290,7 @@ bool opt_disable_networking=0, opt_skip_show_db=0; ...@@ -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_enable_named_pipe= 0, opt_debugging= 0;
my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol;
uint delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; uint delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
uint lower_case_table_names;
static my_bool opt_do_pstack = 0; static my_bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH; static ulong opt_specialflag=SPECIAL_ENGLISH;
...@@ -305,7 +306,7 @@ char* log_error_file_ptr= log_error_file; ...@@ -305,7 +306,7 @@ char* log_error_file_ptr= log_error_file;
static pthread_t select_thread; static pthread_t select_thread;
static my_bool opt_noacl=0, opt_bootstrap=0, opt_myisam_log=0; 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 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_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0, opt_console= 0; my_bool opt_log_slave_updates= 0, opt_console= 0;
my_bool opt_readonly = 0; my_bool opt_readonly = 0;
...@@ -2097,6 +2098,18 @@ int main(int argc, char **argv) ...@@ -2097,6 +2098,18 @@ int main(int argc, char **argv)
exit(1); exit(1);
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); 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 #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
{ {
...@@ -3841,15 +3854,15 @@ replicating a LOAD DATA INFILE command", ...@@ -3841,15 +3854,15 @@ replicating a LOAD DATA INFILE command",
(gptr*) &max_system_variables.long_query_time, 0, GET_ULONG, (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG,
REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
{"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, {"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,
(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 #ifdef FN_NO_CASE_SENCE
1 1
#else #else
0 0
#endif #endif
, 0, 1, 0, 1, 0}, , 0, 2, 0, 1, 0},
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
"Max packetlength to send/receive from to server.", "Max packetlength to send/receive from to server.",
(gptr*) &global_system_variables.max_allowed_packet, (gptr*) &global_system_variables.max_allowed_packet,
...@@ -4814,6 +4827,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -4814,6 +4827,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
sf_malloc_quick=1; sf_malloc_quick=1;
#endif #endif
break; break;
case OPT_LOWER_CASE_TABLE_NAMES:
lower_case_table_names= argument ? atoi(argument) : 1;
break;
} }
return 0; return 0;
} }
...@@ -4946,18 +4962,6 @@ static void fix_paths(void) ...@@ -4946,18 +4962,6 @@ static void fix_paths(void)
if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
exit(1); 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;
}
} }
......
...@@ -514,7 +514,7 @@ struct show_var_st init_vars[]= { ...@@ -514,7 +514,7 @@ struct show_var_st init_vars[]= {
{sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS}, {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
{sys_long_query_time.name, (char*) &sys_long_query_time, 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}, {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_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_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
{sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS}, {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS},
......
...@@ -732,11 +732,11 @@ class select_create: public select_insert { ...@@ -732,11 +732,11 @@ class select_create: public select_insert {
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
Field **field; Field **field;
public: public:
select_create (const char *db_name, const char *table_name, select_create(const char *db_name, const char *table_name,
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par, List<create_field> &fields_par,
List<Key> &keys_par, List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic) List<Item> &select_fields,enum_duplicates duplic)
:select_insert (NULL, &select_fields, duplic), db(db_name), :select_insert (NULL, &select_fields, duplic), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par), name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par), lock(0) create_info(create_info_par), lock(0)
......
...@@ -116,12 +116,21 @@ const char *known_exts[]= ...@@ -116,12 +116,21 @@ const char *known_exts[]=
static TYPELIB known_extentions= static TYPELIB known_extentions=
{array_elements(known_exts)-1,"known_exts", known_exts}; {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 Drop all tables in a database and the database itself
when we want to remove a stale database before replacing it with the new one
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) ...@@ -129,7 +138,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{ {
long deleted=0; long deleted=0;
int error = 0; int error = 0;
char path[FN_REFLEN+16]; char path[FN_REFLEN+16], tmp_db[NAME_LEN+1];
MY_DIR *dirp; MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db"); DBUG_ENTER("mysql_rm_db");
...@@ -156,6 +165,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -156,6 +165,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
send_ok(&thd->net,0); send_ok(&thd->net,0);
goto exit; 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); pthread_mutex_lock(&LOCK_open);
remove_db_from_cache(db); remove_db_from_cache(db);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
......
...@@ -1434,8 +1434,8 @@ select_create::prepare(List<Item> &values) ...@@ -1434,8 +1434,8 @@ select_create::prepare(List<Item> &values)
{ {
DBUG_ENTER("select_create::prepare"); DBUG_ENTER("select_create::prepare");
table=create_table_from_items(thd, create_info, db, name, table= create_table_from_items(thd, create_info, db, name,
extra_fields, keys, &values, &lock); extra_fields, keys, &values, &lock);
if (!table) if (!table)
DBUG_RETURN(-1); // abort() deletes table DBUG_RETURN(-1); // abort() deletes table
......
...@@ -59,8 +59,8 @@ static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); ...@@ -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 mysql_init_query(THD *thd);
static void remove_escape(char *name); static void remove_escape(char *name);
static void refresh_status(void); static void refresh_status(void);
static bool append_file_to_dir(THD *thd, char **filename_ptr, static bool append_file_to_dir(THD *thd, const char **filename_ptr,
char *table_name); const char *table_name);
static bool create_total_list(THD *thd, LEX *lex, static bool create_total_list(THD *thd, LEX *lex,
TABLE_LIST **result, bool skip_first); TABLE_LIST **result, bool skip_first);
...@@ -1121,10 +1121,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1121,10 +1121,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_CREATE_DB: // QQ: To be removed case COM_CREATE_DB: // QQ: To be removed
{ {
char *db=thd->strdup(packet), *alias;
statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status);
char *db=thd->strdup(packet);
// null test to handle EOM // 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"); net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break; break;
...@@ -1132,15 +1134,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1132,15 +1134,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (check_access(thd,CREATE_ACL,db,0,1)) if (check_access(thd,CREATE_ACL,db,0,1))
break; break;
mysql_log.write(thd,command,packet); 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; break;
} }
case COM_DROP_DB: // QQ: To be removed case COM_DROP_DB: // QQ: To be removed
{ {
statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); 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 // 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"); net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break; break;
...@@ -1153,7 +1156,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1153,7 +1156,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; break;
} }
mysql_log.write(thd,command,db); mysql_log.write(thd,command,db);
mysql_rm_db(thd,db,0,0); mysql_rm_db(thd,alias,0,0);
break; break;
} }
case COM_BINLOG_DUMP: case COM_BINLOG_DUMP:
...@@ -1599,6 +1602,7 @@ mysql_execute_command(void) ...@@ -1599,6 +1602,7 @@ mysql_execute_command(void)
CREATE_TMP_ACL : CREATE_ACL); CREATE_TMP_ACL : CREATE_ACL);
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
lex->create_info.alias= tables->alias;
if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) || if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) ||
check_merge_table_access(thd, tables->db, check_merge_table_access(thd, tables->db,
(TABLE_LIST *) (TABLE_LIST *)
...@@ -1664,7 +1668,8 @@ mysql_execute_command(void) ...@@ -1664,7 +1668,8 @@ mysql_execute_command(void)
if (!(res=open_and_lock_tables(thd,tables->next))) if (!(res=open_and_lock_tables(thd,tables->next)))
{ {
if ((result=new select_create(tables->db ? tables->db : thd->db, 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->create_list,
lex->key_list, lex->key_list,
select_lex->item_list,lex->duplicates))) select_lex->item_list,lex->duplicates)))
...@@ -1676,7 +1681,8 @@ mysql_execute_command(void) ...@@ -1676,7 +1681,8 @@ mysql_execute_command(void)
else // regular create else // regular create
{ {
res = mysql_create_table(thd,tables->db ? tables->db : thd->db, 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->create_list,
lex->key_list,0, 0); // do logging lex->key_list,0, 0); // do logging
if (!res) if (!res)
...@@ -2341,7 +2347,9 @@ mysql_execute_command(void) ...@@ -2341,7 +2347,9 @@ mysql_execute_command(void)
break; break;
case SQLCOM_CREATE_DB: 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); net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break; break;
...@@ -2363,12 +2371,15 @@ mysql_execute_command(void) ...@@ -2363,12 +2371,15 @@ mysql_execute_command(void)
if (check_access(thd,CREATE_ACL,lex->name,0,1)) if (check_access(thd,CREATE_ACL,lex->name,0,1))
break; 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; break;
} }
case SQLCOM_DROP_DB: 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); net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break; break;
...@@ -2394,7 +2405,7 @@ mysql_execute_command(void) ...@@ -2394,7 +2405,7 @@ mysql_execute_command(void)
send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
goto error; 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; break;
} }
case SQLCOM_CREATE_FUNCTION: case SQLCOM_CREATE_FUNCTION:
...@@ -3779,7 +3790,8 @@ static void refresh_status(void) ...@@ -3779,7 +3790,8 @@ static void refresh_status(void)
/* If pointer is not a null pointer, append filename to it */ /* 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; char buff[FN_REFLEN],*ptr, *end;
if (!*filename_ptr) if (!*filename_ptr)
......
...@@ -112,19 +112,31 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) ...@@ -112,19 +112,31 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{ {
db_type table_type; db_type table_type;
char name[FN_REFLEN]; 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, sprintf(name,"%s/%s/%s%s",mysql_data_home,
new_table->db,new_table->real_name, new_table->db, new_alias, reg_ext);
reg_ext); unpack_filename(name, name);
if (!access(name,F_OK)) 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 DBUG_RETURN(ren_table); // This can't be skipped
} }
sprintf(name,"%s/%s/%s%s",mysql_data_home, sprintf(name,"%s/%s/%s%s",mysql_data_home,
ren_table->db,ren_table->real_name, ren_table->db, old_alias,
reg_ext); reg_ext);
unpack_filename(name, name);
if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN) if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN)
{ {
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); 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) ...@@ -132,8 +144,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
DBUG_RETURN(ren_table); DBUG_RETURN(ren_table);
} }
else if (mysql_rename_table(table_type, else if (mysql_rename_table(table_type,
ren_table->db, ren_table->real_name, ren_table->db, old_alias,
new_table->db, new_table->real_name)) new_table->db, new_alias))
{ {
if (!skip_error) if (!skip_error)
DBUG_RETURN(ren_table); DBUG_RETURN(ren_table);
......
...@@ -865,7 +865,9 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -865,7 +865,9 @@ store_create_info(THD *thd, TABLE *table, String *packet)
packet->append("CREATE TEMPORARY TABLE ", 23); packet->append("CREATE TEMPORARY TABLE ", 23);
else else
packet->append("CREATE TABLE ", 13); 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); packet->append(" (\n", 3);
for (ptr=table->field ; (field= *ptr); ptr++) for (ptr=table->field ; (field= *ptr); ptr++)
......
...@@ -163,7 +163,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -163,7 +163,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
bool dont_log_query) bool dont_log_query)
{ {
TABLE_LIST *table; TABLE_LIST *table;
char path[FN_REFLEN]; char path[FN_REFLEN], *alias;
String wrong_tables; String wrong_tables;
db_type table_type; db_type table_type;
int error; int error;
...@@ -193,15 +193,12 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -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); drop_locked_tables(thd,db,table->real_name);
if (thd->killed) if (thd->killed)
DBUG_RETURN(-1); DBUG_RETURN(-1);
alias= (lower_case_table_names == 2) ? table->alias : table->real_name;
/* remove form file and isam files */ /* remove form file and isam files */
strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext, strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
NullS);
(void) unpack_filename(path,path); (void) unpack_filename(path,path);
error=0; error=0;
table_type=get_table_type(path);
if (access(path,F_OK)) if (access(path,F_OK))
{ {
if (!if_exists) if (!if_exists)
...@@ -210,7 +207,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -210,7 +207,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
else else
{ {
char *end; 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); error=ha_delete_table(table_type, path);
if (error == ENOENT && if_exists) if (error == ENOENT && if_exists)
error = 0; error = 0;
...@@ -350,7 +348,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -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) List<Key> &keys,bool tmp_table,bool no_log)
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
const char *key_name; const char *key_name, *alias;
create_field *sql_field,*dup_field; create_field *sql_field,*dup_field;
int error= -1; int error= -1;
uint db_options,field,null_fields,blob_columns; 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, ...@@ -361,10 +359,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
handler *file; handler *file;
DBUG_ENTER("mysql_create_table"); 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) if (!fields.elements)
{ {
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); 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, ...@@ -375,6 +370,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
db_options=create_info->table_options; db_options=create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC) if (create_info->row_type == ROW_TYPE_DYNAMIC)
db_options|=HA_OPTION_PACK_RECORD; db_options|=HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
file=get_new_handler((TABLE*) 0, create_info->db_type); file=get_new_handler((TABLE*) 0, create_info->db_type);
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && 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, ...@@ -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; create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
} }
else 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); unpack_filename(path,path);
/* Check if table already exists */ /* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) 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, ...@@ -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 create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0); 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); DBUG_RETURN(-1);
} }
} }
...@@ -873,7 +869,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, ...@@ -873,7 +869,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(0); DBUG_RETURN(0);
if (!(table=open_table(thd,db,name,name,(bool*) 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); DBUG_RETURN(0);
} }
table->reginfo.lock_type=TL_WRITE; table->reginfo.lock_type=TL_WRITE;
...@@ -882,7 +878,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, ...@@ -882,7 +878,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
hash_delete(&open_cache,(byte*) table); hash_delete(&open_cache,(byte*) table);
VOID(pthread_mutex_unlock(&LOCK_open)); 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); DBUG_RETURN(0);
} }
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
...@@ -897,18 +893,32 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, ...@@ -897,18 +893,32 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
bool bool
mysql_rename_table(enum db_type base, mysql_rename_table(enum db_type base,
const char *old_db, const char *old_db,
const char * old_name, const char *old_name,
const char *new_db, 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); handler *file=get_new_handler((TABLE*) 0, base);
int error=0; int error=0;
DBUG_ENTER("mysql_rename_table"); 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(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
(void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name); (void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name);
fn_format(from,from,"","",4); fn_format(from,from,"","",4);
fn_format(to,to, "","",4); fn_format(to,to, "","",4);
if (!(error=file->rename_table((const char*) from,(const char *) to))) if (!(error=file->rename_table((const char*) from,(const char *) to)))
{ {
if (rename_file_ext(from,to,reg_ext)) if (rename_file_ext(from,to,reg_ext))
...@@ -924,6 +934,7 @@ mysql_rename_table(enum db_type base, ...@@ -924,6 +934,7 @@ mysql_rename_table(enum db_type base,
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);
} }
/* /*
Force all other threads to stop using the table Force all other threads to stop using the table
...@@ -968,7 +979,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, ...@@ -968,7 +979,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
Close a cached table Close a cached table
SYNOPSIS SYNOPSIS
clsoe_cached_table() close_cached_table()
thd Thread handler thd Thread handler
table Table to remove from cache table Table to remove from cache
...@@ -1446,8 +1457,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1446,8 +1457,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{ {
TABLE *table,*new_table; TABLE *table,*new_table;
int error; int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN], char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
*table_name,*db; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN]; char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0; bool use_timestamp=0;
ha_rows copied,deleted; ha_rows copied,deleted;
...@@ -1458,11 +1469,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1458,11 +1469,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->proc_info="init"; thd->proc_info="init";
table_name=table_list->real_name; table_name=table_list->real_name;
alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
db=table_list->db; db=table_list->db;
if (!new_db || !strcmp(new_db,db)) if (!new_db || !strcmp(new_db,db))
new_db=db; new_db=db;
used_fields=create_info->used_fields; used_fields=create_info->used_fields;
mysql_ha_closeall(thd, table_list); mysql_ha_closeall(thd, table_list);
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -1471,21 +1484,29 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1471,21 +1484,29 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (new_name) if (new_name)
{ {
strmov(new_name_buff,new_name); strmov(new_name_buff,new_name);
strmov(new_alias= new_alias_buff, new_name);
fn_same(new_name_buff,table_name,3); fn_same(new_name_buff,table_name,3);
if (lower_case_table_names) 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); casedn_str(new_name);
}
if ((lower_case_table_names && if ((lower_case_table_names &&
!my_strcasecmp(new_name_buff,table_name)) || !my_strcasecmp(new_name_buff,table_name)) ||
(!lower_case_table_names && (!lower_case_table_names &&
!strcmp(new_name_buff,table_name))) !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 else
{ {
if (table->tmp_table) if (table->tmp_table)
{ {
if (find_temporary_table(thd,new_db,new_name_buff)) 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); DBUG_RETURN(-1);
} }
} }
...@@ -1495,14 +1516,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1495,14 +1516,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
F_OK)) F_OK))
{ {
/* Table will be closed in do_command() */ /* 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); DBUG_RETURN(-1);
} }
} }
} }
} }
else else
new_name=table_name; new_alias= new_name= table_name;
old_db_type=table->db_type; old_db_type=table->db_type;
if (create_info->db_type == DB_TYPE_DEFAULT) if (create_info->db_type == DB_TYPE_DEFAULT)
...@@ -1532,7 +1553,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1532,7 +1553,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{ {
*fn_ext(new_name)=0; *fn_ext(new_name)=0;
close_cached_table(thd, table); 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; error= -1;
} }
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
...@@ -1925,7 +1946,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -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 */ /* Remove link to old table and rename the new one */
close_temporary_table(thd,table->table_cache_key,table_name); 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 { // Fatal error
close_temporary_table(thd,new_db,tmp_name); close_temporary_table(thd,new_db,tmp_name);
my_free((gptr) new_table,MYF(0)); my_free((gptr) new_table,MYF(0));
...@@ -2001,12 +2022,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -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)); 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, else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
new_name)) new_alias))
{ // Try to get everything back { // Try to get everything back
error=1; 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(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) if (error)
{ {
......
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