summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2003-12-30 13:14:21 +0200
committerunknown <monty@mysql.com>2003-12-30 13:14:21 +0200
commit376fb08072e00c6be932b5c38ff6e23288e81e50 (patch)
treefd8d2c5fbe95830a7705bcaa0f893bd209830ffb /sql
parent1f9763c169a5c15da350f18a9a2d494fa14a8d98 (diff)
downloadmariadb-git-376fb08072e00c6be932b5c38ff6e23288e81e50.tar.gz
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) client/mysqltest.c: Indentation cleanup include/myisam.h: Made some pointers 'const' mysql-test/mysql-test-run.sh: Portability fix for OSX sql/filesort.cc: Safety fix (not needed for current code but needed for 5.0) sql/ha_berkeley.cc: More debugging Changed 'create' to return error number sql/ha_berkeley.h: Added HA_FILE_BASED sql/ha_innodb.cc: Added missing DBUG_RETURN sql/ha_isam.cc: Changed create to return error number sql/ha_isam.h: Added HA_FILE_BASED sql/ha_isammrg.h: Added HA_FILE_BASED sql/ha_myisam.cc: Changed create to return error number sql/ha_myisam.h: Added HA_FILE_BASED sql/ha_myisammrg.cc: Changed create to return error number sql/ha_myisammrg.h: Added HA_FILE_BASED sql/handler.cc: Ensure that table engines gets table names in lower case even if we are using lower_case_table_names Removed test for DB_TYPE_INNODB by ensuring that create method returns error number. sql/handler.h: Added HA_FILE_BASED Made some struct entries 'const' Added 'alias' for create to be able to create tables in mixed case on case insensitive file systems sql/mysql_priv.h: Support for lower_case_table_names=2 sql/mysqld.cc: Support for lower_case_table_names=2 Moved test of case insenstive file system after all mutex are created sql/set_var.cc: Support for lower_case_table_names=2 sql/sql_class.h: Indentation change sql/sql_db.cc: Support for lower_case_table_names=2 sql/sql_insert.cc: Indentation change sql/sql_parse.cc: Support for lower_case_table_names=2 sql/sql_rename.cc: Support for lower_case_table_names=2 Added missing 'unpack_filename' to RENAME which may fix a bug in RENAME TABLE on windows sql/sql_show.cc: If lower_case_table_name=2 is given, show original case in SHOW CREATE TABLE sql/sql_table.cc: Support for lower_case_table_names=2 for DROP TABLE, RENAME TABLE, ALTER TABLE and CREATE TABLE
Diffstat (limited to 'sql')
-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
23 files changed, 223 insertions, 129 deletions
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)
{