Commit 376fb080 authored by unknown's avatar unknown

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
parent 1f9763c1
......@@ -440,10 +440,10 @@ static void free_used_memory()
my_free((gptr) (*q),MYF(0));
}
for (i=0; i < 10; i++)
{
if (var_reg[i].alloced_len)
my_free(var_reg[i].str_val, MYF(MY_WME));
}
{
if (var_reg[i].alloced_len)
my_free(var_reg[i].str_val, MYF(MY_WME));
}
while (embedded_server_arg_count > 1)
my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
delete_dynamic(&q_lines);
......
......@@ -91,7 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
typedef struct st_mi_create_info
{
char *index_file_name, *data_file_name; /* If using symlinks */
const char *index_file_name, *data_file_name; /* If using symlinks */
ha_rows max_rows;
ha_rows reloc_rows;
ulonglong auto_increment;
......
......@@ -182,7 +182,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
# Set LD_LIBRARY_PATH if we are using shared libraries
#
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$DYLD_LIBRARY_PATH"
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
MASTER_RUNNING=0
MASTER_MYPORT=9306
......
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,
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);
}
......
......@@ -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;
......
......@@ -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)
{
}
......
......@@ -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
......
......@@ -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++)
......
......@@ -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"; }
......
......@@ -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; }
......
......@@ -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++)
......
......@@ -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() {}
......
......@@ -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
......
......@@ -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
{
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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);
}
......@@ -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;
}
}
......
......@@ -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},
......
......@@ -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)
......
......@@ -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);
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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++)
......
......@@ -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)
{
......
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