Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.1-runtime

into  govinda.patg.net:/home/patg/mysql-build/mysql-5.1-engines-merge
This commit is contained in:
pgalbraith/patg@govinda.patg.net 2006-08-10 15:31:44 -07:00
commit b2ce951b81
32 changed files with 676 additions and 192 deletions

View File

@ -657,3 +657,68 @@ SELECT * FROM t1;
v b v b
abc 5 abc 5
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS `t+1`, `t+2`;
CREATE TABLE `t+1` (c1 INT);
ALTER TABLE `t+1` RENAME `t+2`;
CREATE TABLE `t+1` (c1 INT);
ALTER TABLE `t+1` RENAME `t+2`;
ERROR 42S01: Table 't+2' already exists
DROP TABLE `t+1`, `t+2`;
CREATE TEMPORARY TABLE `tt+1` (c1 INT);
ALTER TABLE `tt+1` RENAME `tt+2`;
CREATE TEMPORARY TABLE `tt+1` (c1 INT);
ALTER TABLE `tt+1` RENAME `tt+2`;
ERROR 42S01: Table 'tt+2' already exists
SHOW CREATE TABLE `tt+1`;
Table Create Table
tt+1 CREATE TEMPORARY TABLE `tt+1` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE TABLE `tt+2`;
Table Create Table
tt+2 CREATE TEMPORARY TABLE `tt+2` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `tt+1`, `tt+2`;
CREATE TABLE `#sql1` (c1 INT);
CREATE TABLE `@0023sql2` (c1 INT);
SHOW TABLES;
Tables_in_test
#sql1
@0023sql2
RENAME TABLE `#sql1` TO `@0023sql1`;
RENAME TABLE `@0023sql2` TO `#sql2`;
SHOW TABLES;
Tables_in_test
#sql2
@0023sql1
ALTER TABLE `@0023sql1` RENAME `#sql-1`;
ALTER TABLE `#sql2` RENAME `@0023sql-2`;
SHOW TABLES;
Tables_in_test
#sql-1
@0023sql-2
INSERT INTO `#sql-1` VALUES (1);
INSERT INTO `@0023sql-2` VALUES (2);
DROP TABLE `#sql-1`, `@0023sql-2`;
CREATE TEMPORARY TABLE `#sql1` (c1 INT);
CREATE TEMPORARY TABLE `@0023sql2` (c1 INT);
SHOW TABLES;
Tables_in_test
ALTER TABLE `#sql1` RENAME `@0023sql1`;
ALTER TABLE `@0023sql2` RENAME `#sql2`;
SHOW TABLES;
Tables_in_test
INSERT INTO `#sql2` VALUES (1);
INSERT INTO `@0023sql1` VALUES (2);
SHOW CREATE TABLE `#sql2`;
Table Create Table
#sql2 CREATE TEMPORARY TABLE `#sql2` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE TABLE `@0023sql1`;
Table Create Table
@0023sql1 CREATE TEMPORARY TABLE `@0023sql1` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `#sql2`, `@0023sql1`;

View File

@ -101,3 +101,23 @@ test.t5 backup status OK
Warnings: Warnings:
Warning 1541 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead. Warning 1541 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead.
drop table t5; drop table t5;
DROP TABLE IF EXISTS `t+1`;
CREATE TABLE `t+1` (c1 INT);
INSERT INTO `t+1` VALUES (1), (2), (3);
BACKUP TABLE `t+1` TO '../tmp';
Table Op Msg_type Msg_text
test.t+1 backup status OK
Warnings:
Warning 1541 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead.
DROP TABLE `t+1`;
RESTORE TABLE `t+1` FROM '../tmp';
Table Op Msg_type Msg_text
test.t+1 restore status OK
Warnings:
Warning 1541 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead.
SELECT * FROM `t+1`;
c1
1
2
3
DROP TABLE `t+1`;

View File

@ -16,7 +16,7 @@ CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
DEFAULT CHARSET=latin1 ENGINE=BerkeleyDB; DEFAULT CHARSET=latin1 ENGINE=InnoDB;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
Warnings: Warnings:
Note 1051 Unknown table 't1' Note 1051 Unknown table 't1'

View File

@ -16,3 +16,19 @@ select events.binlog from events;
binlog binlog
1 1
drop table events; drop table events;
create procedure p1()
begin
declare n int default 2;
authors: while n > 0 do
set n = n -1;
end while authors;
end|
create procedure p2()
begin
declare n int default 2;
contributors: while n > 0 do
set n = n -1;
end while contributors;
end|
drop procedure p1;
drop procedure p2;

View File

@ -41,3 +41,9 @@ Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1 test.t1 repair warning Number of rows changed from 0 to 1
test.t1 repair status OK test.t1 repair status OK
drop table t1; drop table t1;
DROP TABLE IF EXISTS tt1;
CREATE TEMPORARY TABLE tt1 (c1 INT);
REPAIR TABLE tt1 USE_FRM;
Table Op Msg_type Msg_text
tt1 repair error Cannot repair temporary table from .frm file
DROP TABLE tt1;

View File

@ -482,3 +482,57 @@ SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN v VARCHAR(4); ALTER TABLE t1 MODIFY COLUMN v VARCHAR(4);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# End of 5.0 tests
#
# Bug#18775 - Temporary table from alter table visible to other threads
#
# Check if special characters work and duplicates are detected.
--disable_warnings
DROP TABLE IF EXISTS `t+1`, `t+2`;
--enable_warnings
CREATE TABLE `t+1` (c1 INT);
ALTER TABLE `t+1` RENAME `t+2`;
CREATE TABLE `t+1` (c1 INT);
--error ER_TABLE_EXISTS_ERROR
ALTER TABLE `t+1` RENAME `t+2`;
DROP TABLE `t+1`, `t+2`;
#
# Same for temporary tables though these names do not become file names.
CREATE TEMPORARY TABLE `tt+1` (c1 INT);
ALTER TABLE `tt+1` RENAME `tt+2`;
CREATE TEMPORARY TABLE `tt+1` (c1 INT);
--error ER_TABLE_EXISTS_ERROR
ALTER TABLE `tt+1` RENAME `tt+2`;
SHOW CREATE TABLE `tt+1`;
SHOW CREATE TABLE `tt+2`;
DROP TABLE `tt+1`, `tt+2`;
#
# Check if special characters as in tmp_file_prefix work.
CREATE TABLE `#sql1` (c1 INT);
CREATE TABLE `@0023sql2` (c1 INT);
SHOW TABLES;
RENAME TABLE `#sql1` TO `@0023sql1`;
RENAME TABLE `@0023sql2` TO `#sql2`;
SHOW TABLES;
ALTER TABLE `@0023sql1` RENAME `#sql-1`;
ALTER TABLE `#sql2` RENAME `@0023sql-2`;
SHOW TABLES;
INSERT INTO `#sql-1` VALUES (1);
INSERT INTO `@0023sql-2` VALUES (2);
DROP TABLE `#sql-1`, `@0023sql-2`;
#
# Same for temporary tables though these names do not become file names.
CREATE TEMPORARY TABLE `#sql1` (c1 INT);
CREATE TEMPORARY TABLE `@0023sql2` (c1 INT);
SHOW TABLES;
ALTER TABLE `#sql1` RENAME `@0023sql1`;
ALTER TABLE `@0023sql2` RENAME `#sql2`;
SHOW TABLES;
INSERT INTO `#sql2` VALUES (1);
INSERT INTO `@0023sql1` VALUES (2);
SHOW CREATE TABLE `#sql2`;
SHOW CREATE TABLE `@0023sql1`;
DROP TABLE `#sql2`, `@0023sql1`;

View File

@ -58,3 +58,22 @@ drop table t5;
--system rm $MYSQLTEST_VARDIR/tmp/t?.* --system rm $MYSQLTEST_VARDIR/tmp/t?.*
# End of 4.1 tests # End of 4.1 tests
# End of 5.0 tests
#
# Bug#18775 - Temporary table from alter table visible to other threads
#
# Backup did not encode table names.
--disable_warnings
DROP TABLE IF EXISTS `t+1`;
--enable_warnings
CREATE TABLE `t+1` (c1 INT);
INSERT INTO `t+1` VALUES (1), (2), (3);
BACKUP TABLE `t+1` TO '../tmp';
DROP TABLE `t+1`;
#
# Same for restore.
RESTORE TABLE `t+1` FROM '../tmp';
SELECT * FROM `t+1`;
DROP TABLE `t+1`;

View File

@ -0,0 +1 @@
--innodb

View File

@ -1,6 +1,6 @@
# should work with embedded server after mysqltest is fixed # should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc -- source include/not_embedded.inc
source include/have_bdb.inc; source include/have_innodb.inc;
source include/federated.inc; source include/federated.inc;
connection slave; connection slave;
@ -10,7 +10,7 @@ CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
DEFAULT CHARSET=latin1 ENGINE=BerkeleyDB; DEFAULT CHARSET=latin1 ENGINE=InnoDB;
connection master; connection master;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;

View File

@ -19,3 +19,27 @@ select events.binlog from events;
drop table events; drop table events;
# End of 4.1 tests # End of 4.1 tests
#
# Bug#19939 "AUTHORS is not a keyword"
#
delimiter |;
create procedure p1()
begin
declare n int default 2;
authors: while n > 0 do
set n = n -1;
end while authors;
end|
create procedure p2()
begin
declare n int default 2;
contributors: while n > 0 do
set n = n -1;
end while contributors;
end|
delimiter ;|
drop procedure p1;
drop procedure p2;
# End of 5.1 tests

View File

@ -35,3 +35,16 @@ repair table t1 use_frm;
drop table t1; drop table t1;
# End of 4.1 tests # End of 4.1 tests
# End of 5.0 tests
#
# Bug#18775 - Temporary table from alter table visible to other threads
#
# REPAIR TABLE ... USE_FRM on temporary table crashed the table or server.
--disable_warnings
DROP TABLE IF EXISTS tt1;
--enable_warnings
CREATE TEMPORARY TABLE tt1 (c1 INT);
REPAIR TABLE tt1 USE_FRM;
DROP TABLE tt1;

View File

@ -473,11 +473,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
HA_CHECK_OPT tmp_check_opt; HA_CHECK_OPT tmp_check_opt;
char *backup_dir= thd->lex->backup_dir; char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char src_path[FN_REFLEN], dst_path[FN_REFLEN];
const char *table_name= table->s->table_name.str; char table_name[FN_REFLEN];
int error; int error;
const char* errmsg; const char* errmsg;
DBUG_ENTER("restore"); DBUG_ENTER("restore");
VOID(tablename_to_filename(table->s->table_name.str, table_name,
sizeof(table_name)));
if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
MI_NAME_DEXT)) MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID); DBUG_RETURN(HA_ADMIN_INVALID);
@ -513,11 +516,14 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
{ {
char *backup_dir= thd->lex->backup_dir; char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char src_path[FN_REFLEN], dst_path[FN_REFLEN];
const char *table_name= table->s->table_name.str; char table_name[FN_REFLEN];
int error; int error;
const char *errmsg; const char *errmsg;
DBUG_ENTER("ha_myisam::backup"); DBUG_ENTER("ha_myisam::backup");
VOID(tablename_to_filename(table->s->table_name.str, table_name,
sizeof(table_name)));
if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
reg_ext)) reg_ext))
{ {

View File

@ -477,7 +477,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
an embedded server without changing the paths in the .MRG file. an embedded server without changing the paths in the .MRG file.
*/ */
uint length= build_table_filename(buff, sizeof(buff), uint length= build_table_filename(buff, sizeof(buff),
tables->db, tables->table_name, ""); tables->db, tables->table_name, "", 0);
/* /*
If a MyISAM table is in the same directory as the MERGE table, If a MyISAM table is in the same directory as the MERGE table,
we use the table name without a path. This means that the we use the table name without a path. This means that the

View File

@ -5801,7 +5801,7 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
DBUG_RETURN(HA_ERR_NO_CONNECTION); DBUG_RETURN(HA_ERR_NO_CONNECTION);
ndb->setDatabaseName(db); ndb->setDatabaseName(db);
NDBDICT* dict= ndb->getDictionary(); NDBDICT* dict= ndb->getDictionary();
build_table_filename(key, sizeof(key), db, name, ""); build_table_filename(key, sizeof(key), db, name, "", 0);
NDB_SHARE *share= get_share(key, 0, false); NDB_SHARE *share= get_share(key, 0, false);
if (share && get_ndb_share_state(share) == NSS_ALTERED) if (share && get_ndb_share_state(share) == NSS_ALTERED)
{ {
@ -5944,7 +5944,7 @@ int ndbcluster_drop_database_impl(const char *path)
// Drop any tables belonging to database // Drop any tables belonging to database
char full_path[FN_REFLEN]; char full_path[FN_REFLEN];
char *tmp= full_path + char *tmp= full_path +
build_table_filename(full_path, sizeof(full_path), dbname, "", ""); build_table_filename(full_path, sizeof(full_path), dbname, "", "", 0);
ndb->setDatabaseName(dbname); ndb->setDatabaseName(dbname);
List_iterator_fast<char> it(drop_list); List_iterator_fast<char> it(drop_list);
@ -6067,7 +6067,7 @@ int ndbcluster_find_all_files(THD *thd)
/* check if database exists */ /* check if database exists */
char *end= key + char *end= key +
build_table_filename(key, sizeof(key), elmt.database, "", ""); build_table_filename(key, sizeof(key), elmt.database, "", "", 0);
if (my_access(key, F_OK)) if (my_access(key, F_OK))
{ {
/* no such database defined, skip table */ /* no such database defined, skip table */
@ -6210,7 +6210,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
} }
// File is not in NDB, check for .ndb file with this name // File is not in NDB, check for .ndb file with this name
build_table_filename(name, sizeof(name), db, file_name, ha_ndb_ext); build_table_filename(name, sizeof(name), db, file_name, ha_ndb_ext, 0);
DBUG_PRINT("info", ("Check access for %s", name)); DBUG_PRINT("info", ("Check access for %s", name));
if (my_access(name, F_OK)) if (my_access(name, F_OK))
{ {
@ -6235,7 +6235,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
/* setup logging to binlog for all discovered tables */ /* setup logging to binlog for all discovered tables */
{ {
char *end, *end1= name + char *end, *end1= name +
build_table_filename(name, sizeof(name), db, "", ""); build_table_filename(name, sizeof(name), db, "", "", 0);
for (i= 0; i < ok_tables.records; i++) for (i= 0; i < ok_tables.records; i++)
{ {
file_name= (char*)hash_element(&ok_tables, i); file_name= (char*)hash_element(&ok_tables, i);
@ -6257,7 +6257,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
file_name= hash_element(&ndb_tables, i); file_name= hash_element(&ndb_tables, i);
if (!hash_search(&ok_tables, file_name, strlen(file_name))) if (!hash_search(&ok_tables, file_name, strlen(file_name)))
{ {
build_table_filename(name, sizeof(name), db, file_name, reg_ext); build_table_filename(name, sizeof(name), db, file_name, reg_ext, 0);
if (my_access(name, F_OK)) if (my_access(name, F_OK))
{ {
DBUG_PRINT("info", ("%s must be discovered", file_name)); DBUG_PRINT("info", ("%s must be discovered", file_name));
@ -6808,7 +6808,7 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
NDB_SHARE *share; NDB_SHARE *share;
DBUG_ENTER("ndb_get_commitcount"); DBUG_ENTER("ndb_get_commitcount");
build_table_filename(name, sizeof(name), dbname, tabname, ""); build_table_filename(name, sizeof(name), dbname, tabname, "", 0);
DBUG_PRINT("enter", ("name: %s", name)); DBUG_PRINT("enter", ("name: %s", name));
pthread_mutex_lock(&ndbcluster_mutex); pthread_mutex_lock(&ndbcluster_mutex);
if (!(share=(NDB_SHARE*) hash_search(&ndbcluster_open_tables, if (!(share=(NDB_SHARE*) hash_search(&ndbcluster_open_tables,

View File

@ -737,7 +737,7 @@ static int ndbcluster_create_apply_status_table(THD *thd)
*/ */
{ {
build_table_filename(buf, sizeof(buf), build_table_filename(buf, sizeof(buf),
NDB_REP_DB, NDB_APPLY_TABLE, reg_ext); NDB_REP_DB, NDB_APPLY_TABLE, reg_ext, 0);
my_delete(buf, MYF(0)); my_delete(buf, MYF(0));
} }
@ -786,7 +786,7 @@ static int ndbcluster_create_schema_table(THD *thd)
*/ */
{ {
build_table_filename(buf, sizeof(buf), build_table_filename(buf, sizeof(buf),
NDB_REP_DB, NDB_SCHEMA_TABLE, reg_ext); NDB_REP_DB, NDB_SCHEMA_TABLE, reg_ext, 0);
my_delete(buf, MYF(0)); my_delete(buf, MYF(0));
} }
@ -1247,7 +1247,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
NDB_SCHEMA_OBJECT *ndb_schema_object; NDB_SCHEMA_OBJECT *ndb_schema_object;
{ {
char key[FN_REFLEN]; char key[FN_REFLEN];
build_table_filename(key, sizeof(key), db, table_name, ""); build_table_filename(key, sizeof(key), db, table_name, "", 0);
ndb_schema_object= ndb_get_schema_object(key, TRUE, FALSE); ndb_schema_object= ndb_get_schema_object(key, TRUE, FALSE);
} }
@ -1577,7 +1577,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
DBUG_PRINT("info", ("Detected frm change of table %s.%s", DBUG_PRINT("info", ("Detected frm change of table %s.%s",
dbname, tabname)); dbname, tabname));
build_table_filename(key, FN_LEN-1, dbname, tabname, NullS); build_table_filename(key, FN_LEN-1, dbname, tabname, NullS, 0);
/* /*
If the frm of the altered table is different than the one on If the frm of the altered table is different than the one on
disk then overwrite it with the new table definition disk then overwrite it with the new table definition
@ -1775,7 +1775,8 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
case SOT_TRUNCATE_TABLE: case SOT_TRUNCATE_TABLE:
{ {
char key[FN_REFLEN]; char key[FN_REFLEN];
build_table_filename(key, sizeof(key), schema->db, schema->name, ""); build_table_filename(key, sizeof(key),
schema->db, schema->name, "", 0);
NDB_SHARE *share= get_share(key, 0, FALSE, FALSE); NDB_SHARE *share= get_share(key, 0, FALSE, FALSE);
// invalidation already handled by binlog thread // invalidation already handled by binlog thread
if (!share || !share->op) if (!share || !share->op)
@ -1979,7 +1980,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
{ {
enum SCHEMA_OP_TYPE schema_type= (enum SCHEMA_OP_TYPE)schema->type; enum SCHEMA_OP_TYPE schema_type= (enum SCHEMA_OP_TYPE)schema->type;
char key[FN_REFLEN]; char key[FN_REFLEN];
build_table_filename(key, sizeof(key), schema->db, schema->name, ""); build_table_filename(key, sizeof(key), schema->db, schema->name, "", 0);
if (schema_type == SOT_CLEAR_SLOCK) if (schema_type == SOT_CLEAR_SLOCK)
{ {
pthread_mutex_lock(&ndbcluster_mutex); pthread_mutex_lock(&ndbcluster_mutex);

View File

@ -23,7 +23,7 @@ typedef NdbDictionary::Index NDBINDEX;
typedef NdbDictionary::Dictionary NDBDICT; typedef NdbDictionary::Dictionary NDBDICT;
typedef NdbDictionary::Event NDBEVENT; typedef NdbDictionary::Event NDBEVENT;
#define IS_TMP_PREFIX(A) (is_prefix(A, tmp_file_prefix) || is_prefix(A, "@0023sql")) #define IS_TMP_PREFIX(A) (is_prefix(A, tmp_file_prefix))
extern ulong ndb_extra_logging; extern ulong ndb_extra_logging;

View File

@ -754,7 +754,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
bool if_exists, bool drop_temporary, bool if_exists, bool drop_temporary,
bool log_query); bool log_query);
bool quick_rm_table(handlerton *base,const char *db, bool quick_rm_table(handlerton *base,const char *db,
const char *table_name); const char *table_name, uint flags);
void close_cached_table(THD *thd, TABLE *table); void close_cached_table(THD *thd, TABLE *table);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
bool mysql_change_db(THD *thd,const char *name,bool no_access_check); bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
@ -899,11 +899,9 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table, bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
Table_ident *src_table); Table_ident *src_table);
bool mysql_rename_table(handlerton *base, bool mysql_rename_table(handlerton *base, const char *old_db,
const char *old_db, const char * old_name, const char *new_db,
const char * old_name, const char * new_name, uint flags);
const char *new_db,
const char * new_name);
bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, bool mysql_drop_index(THD *thd, TABLE_LIST *table_list,
ALTER_INFO *alter_info); ALTER_INFO *alter_info);
@ -1850,7 +1848,12 @@ uint strconvert(CHARSET_INFO *from_cs, const char *from,
uint filename_to_tablename(const char *from, char *to, uint to_length); uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length);
uint build_table_filename(char *buff, size_t bufflen, const char *db, uint build_table_filename(char *buff, size_t bufflen, const char *db,
const char *table, const char *ext); const char *table, const char *ext, uint flags);
/* Flags for conversion functions. */
#define FN_FROM_IS_TMP (1 << 0)
#define FN_TO_IS_TMP (1 << 1)
#define FN_IS_TMP (FN_FROM_IS_TMP | FN_TO_IS_TMP)
/* from hostname.cc */ /* from hostname.cc */
struct in_addr; struct in_addr;
my_string ip_to_hostname(struct in_addr *in,uint *errors); my_string ip_to_hostname(struct in_addr *in,uint *errors);

View File

@ -2962,7 +2962,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{ {
char buf[FN_REFLEN]; char buf[FN_REFLEN];
build_table_filename(buf, sizeof(buf), table_list->db, build_table_filename(buf, sizeof(buf), table_list->db,
table_list->table_name, reg_ext); table_list->table_name, reg_ext, 0);
fn_format(buf, buf, "", "", MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS | fn_format(buf, buf, "", "", MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS |
MY_RETURN_REAL_PATH | MY_APPEND_EXT); MY_RETURN_REAL_PATH | MY_APPEND_EXT);
if (access(buf,F_OK)) if (access(buf,F_OK))

View File

@ -254,7 +254,7 @@ uint cached_table_definitions(void)
Get TABLE_SHARE for a table. Get TABLE_SHARE for a table.
get_table_share() get_table_share()
thd Table share thd Thread handle
table_list Table that should be opened table_list Table that should be opened
key Table cache key key Table cache key
key_length Length of key key_length Length of key
@ -1500,15 +1500,18 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
TABLE *table; TABLE *table;
DBUG_ENTER("find_temporary_table");
DBUG_PRINT("enter", ("table: '%s'.'%s'",
table_list->db, table_list->table_name));
key_length= create_table_def_key(thd, key, table_list, 1); key_length= create_table_def_key(thd, key, table_list, 1);
for (table=thd->temporary_tables ; table ; table= table->next) for (table=thd->temporary_tables ; table ; table= table->next)
{ {
if (table->s->table_cache_key.length == key_length && if (table->s->table_cache_key.length == key_length &&
!memcmp(table->s->table_cache_key.str, key, key_length)) !memcmp(table->s->table_cache_key.str, key, key_length))
return table; DBUG_RETURN(table);
} }
return 0; // Not a temporary table DBUG_RETURN(0); // Not a temporary table
} }
@ -1949,7 +1952,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
char path[FN_REFLEN]; char path[FN_REFLEN];
enum legacy_db_type not_used; enum legacy_db_type not_used;
build_table_filename(path, sizeof(path) - 1, build_table_filename(path, sizeof(path) - 1,
table_list->db, table_list->table_name, reg_ext); table_list->db, table_list->table_name, reg_ext, 0);
if (mysql_frm_type(thd, path, &not_used) == FRMTYPE_VIEW) if (mysql_frm_type(thd, path, &not_used) == FRMTYPE_VIEW)
{ {
/* /*
@ -3511,6 +3514,8 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
uint key_length; uint key_length;
TABLE_LIST table_list; TABLE_LIST table_list;
DBUG_ENTER("open_temporary_table"); DBUG_ENTER("open_temporary_table");
DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'",
db, table_name, path));
table_list.db= (char*) db; table_list.db= (char*) db;
table_list.table_name= (char*) table_name; table_list.table_name= (char*) table_name;

View File

@ -560,7 +560,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* Check directory */ /* Check directory */
path_len= build_table_filename(path, sizeof(path), db, "", ""); path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
path[path_len-1]= 0; // Remove last '/' from path path[path_len-1]= 0; // Remove last '/' from path
if (my_stat(path,&stat_info,MYF(0))) if (my_stat(path,&stat_info,MYF(0)))
@ -704,7 +704,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
We pass MY_DB_OPT_FILE as "extension" to avoid We pass MY_DB_OPT_FILE as "extension" to avoid
"table name to file name" encoding. "table name to file name" encoding.
*/ */
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE); build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
if ((error=write_db_opt(thd, path, create_info))) if ((error=write_db_opt(thd, path, create_info)))
goto exit; goto exit;
@ -797,7 +797,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
length= build_table_filename(path, sizeof(path), db, "", ""); length= build_table_filename(path, sizeof(path), db, "", "", 0);
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
del_dbopt(path); // Remove dboption hash entry del_dbopt(path); // Remove dboption hash entry
path[length]= '\0'; // Remove file name path[length]= '\0'; // Remove file name
@ -1324,7 +1324,7 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
} }
} }
#endif #endif
path_length= build_table_filename(path, sizeof(path), db_name, "", ""); path_length= build_table_filename(path, sizeof(path), db_name, "", "", 0);
if (path_length && path[path_length-1] == FN_LIBCHAR) if (path_length && path[path_length-1] == FN_LIBCHAR)
path[path_length-1]= '\0'; // remove ending '\' path[path_length-1]= '\0'; // remove ending '\'
if (my_access(path,F_OK)) if (my_access(path,F_OK))
@ -1469,11 +1469,12 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
if (thd->db && !strcmp(thd->db, old_db->str)) if (thd->db && !strcmp(thd->db, old_db->str))
change_to_newdb= 1; change_to_newdb= 1;
build_table_filename(path, sizeof(path)-1, old_db->str, "", MY_DB_OPT_FILE); build_table_filename(path, sizeof(path)-1,
old_db->str, "", MY_DB_OPT_FILE, 0);
if ((load_db_opt(thd, path, &create_info))) if ((load_db_opt(thd, path, &create_info)))
create_info.default_table_charset= thd->variables.collation_server; create_info.default_table_charset= thd->variables.collation_server;
length= build_table_filename(path, sizeof(path)-1, old_db->str, "", ""); length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
if (length && path[length-1] == FN_LIBCHAR) if (length && path[length-1] == FN_LIBCHAR)
path[length-1]=0; // remove ending '\' path[length-1]=0; // remove ending '\'
if ((error= my_access(path,F_OK))) if ((error= my_access(path,F_OK)))
@ -1538,9 +1539,10 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
If some tables were left in the new directory, rmdir() will fail. If some tables were left in the new directory, rmdir() will fail.
It garantees we never loose any tables. It garantees we never loose any tables.
*/ */
build_table_filename(path, sizeof(path)-1, new_db->str,"",MY_DB_OPT_FILE); build_table_filename(path, sizeof(path)-1,
new_db->str,"",MY_DB_OPT_FILE, 0);
my_delete(path, MYF(MY_WME)); my_delete(path, MYF(MY_WME));
length= build_table_filename(path, sizeof(path)-1, new_db->str, "", ""); length= build_table_filename(path, sizeof(path)-1, new_db->str, "", "", 0);
if (length && path[length-1] == FN_LIBCHAR) if (length && path[length-1] == FN_LIBCHAR)
path[length-1]=0; // remove ending '\' path[length-1]=0; // remove ending '\'
rmdir(path); rmdir(path);
@ -1592,9 +1594,9 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* pass empty file name, and file->name as extension to avoid encoding */ /* pass empty file name, and file->name as extension to avoid encoding */
build_table_filename(oldname, sizeof(oldname)-1, build_table_filename(oldname, sizeof(oldname)-1,
old_db->str, "", file->name); old_db->str, "", file->name, 0);
build_table_filename(newname, sizeof(newname)-1, build_table_filename(newname, sizeof(newname)-1,
new_db->str, "", file->name); new_db->str, "", file->name, 0);
my_rename(oldname, newname, MYF(MY_WME)); my_rename(oldname, newname, MYF(MY_WME));
} }
my_dirend(dirp); my_dirend(dirp);

View File

@ -888,7 +888,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
} }
path_length= build_table_filename(path, sizeof(path), table_list->db, path_length= build_table_filename(path, sizeof(path), table_list->db,
table_list->table_name, reg_ext); table_list->table_name, reg_ext, 0);
if (!dont_send_ok) if (!dont_send_ok)
{ {

View File

@ -2823,7 +2823,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
((thd->prelocked_mode == PRELOCKED) ? ((thd->prelocked_mode == PRELOCKED) ?
MYSQL_OPEN_IGNORE_LOCKED_TABLES:0))))) MYSQL_OPEN_IGNORE_LOCKED_TABLES:0)))))
quick_rm_table(create_info->db_type, create_table->db, quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->table_name)); table_case_name(create_info, create_table->table_name),
0);
} }
reenable_binlog(thd); reenable_binlog(thd);
if (!table) // open failed if (!table) // open failed
@ -2845,7 +2846,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
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, create_table->db, quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->table_name)); table_case_name(create_info, create_table->table_name), 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
@ -3026,7 +3027,8 @@ void select_create::abort()
table->s->version= 0; table->s->version= 0;
hash_delete(&open_cache,(byte*) table); hash_delete(&open_cache,(byte*) table);
if (!create_info->table_existed) if (!create_info->table_existed)
quick_rm_table(table_type, create_table->db, create_table->table_name); quick_rm_table(table_type, create_table->db,
create_table->table_name, 0);
/* Tell threads waiting for refresh that something has happened */ /* Tell threads waiting for refresh that something has happened */
if (version != refresh_version) if (version != refresh_version)
broadcast_refresh(); broadcast_refresh();

View File

@ -3441,7 +3441,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
char *src_db= table_ident->db.str ? table_ident->db.str : thd->db; char *src_db= table_ident->db.str ? table_ident->db.str : thd->db;
char *src_table= table_ident->table.str; char *src_table= table_ident->table.str;
char buf[FN_REFLEN]; char buf[FN_REFLEN];
build_table_filename(buf, sizeof(buf), src_db, src_table, ""); build_table_filename(buf, sizeof(buf), src_db, src_table, "", 0);
if (partition_default_handling(table, part_info, if (partition_default_handling(table, part_info,
FALSE, buf)) FALSE, buf))
{ {
@ -4715,7 +4715,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
handler *file= lpt->table->file; handler *file= lpt->table->file;
DBUG_ENTER("mysql_change_partitions"); DBUG_ENTER("mysql_change_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= file->change_partitions(lpt->create_info, path, &lpt->copied, if ((error= file->change_partitions(lpt->create_info, path, &lpt->copied,
&lpt->deleted, lpt->pack_frm_data, &lpt->deleted, lpt->pack_frm_data,
lpt->pack_frm_len))) lpt->pack_frm_len)))
@ -4755,7 +4755,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error; int error;
DBUG_ENTER("mysql_rename_partitions"); DBUG_ENTER("mysql_rename_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= lpt->table->file->rename_partitions(path))) if ((error= lpt->table->file->rename_partitions(path)))
{ {
if (error != 1) if (error != 1)
@ -4796,7 +4796,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error; int error;
DBUG_ENTER("mysql_drop_partitions"); DBUG_ENTER("mysql_drop_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= lpt->table->file->drop_partitions(path))) if ((error= lpt->table->file->drop_partitions(path)))
{ {
lpt->table->file->print_error(error, MYF(0)); lpt->table->file->print_error(error, MYF(0));
@ -5147,7 +5147,7 @@ static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_drop_shadow_frm"); DBUG_ENTER("write_log_drop_shadow_frm");
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl); pthread_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, NULL, if (write_log_replace_delete_frm(lpt, 0UL, NULL,
(const char*)shadow_path, FALSE)) (const char*)shadow_path, FALSE))
@ -5195,9 +5195,9 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path), lpt->db, build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, ""); lpt->table_name, "", 0);
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl); pthread_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE)) if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE))
goto error; goto error;
@ -5249,9 +5249,9 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path), lpt->db, build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, ""); lpt->table_name, "", 0);
build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, build_table_filename(tmp_path, sizeof(tmp_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl); pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE)) FALSE))
@ -5306,9 +5306,9 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_add_change_partition"); DBUG_ENTER("write_log_add_change_partition");
build_table_filename(path, sizeof(path), lpt->db, build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, ""); lpt->table_name, "", 0);
build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, build_table_filename(tmp_path, sizeof(tmp_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl); pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE)) FALSE))
@ -5363,9 +5363,9 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path), lpt->db, build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, ""); lpt->table_name, "", 0);
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl); pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
lpt->alter_info->flags & ALTER_REORGANIZE_PARTITION)) lpt->alter_info->flags & ALTER_REORGANIZE_PARTITION))

View File

@ -157,14 +157,14 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
new_alias= new_table->table_name; new_alias= new_table->table_name;
} }
build_table_filename(name, sizeof(name), build_table_filename(name, sizeof(name),
new_table->db, new_alias, reg_ext); new_table->db, new_alias, reg_ext, 0);
if (!access(name,F_OK)) if (!access(name,F_OK))
{ {
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); 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
} }
build_table_filename(name, sizeof(name), build_table_filename(name, sizeof(name),
ren_table->db, old_alias, reg_ext); ren_table->db, old_alias, reg_ext, 0);
frm_type= mysql_frm_type(thd, name, &table_type); frm_type= mysql_frm_type(thd, name, &table_type);
switch (frm_type) switch (frm_type)
@ -178,7 +178,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd, if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
table_type), table_type),
ren_table->db, old_alias, ren_table->db, old_alias,
new_table->db, new_alias))) new_table->db, new_alias, 0)))
{ {
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
old_alias, old_alias,
@ -194,7 +194,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
(void) mysql_rename_table(ha_resolve_by_legacy_type(thd, (void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
table_type), table_type),
new_table->db, new_alias, new_table->db, new_alias,
ren_table->db, old_alias); ren_table->db, old_alias, 0);
} }
} }
} }

View File

@ -467,7 +467,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
uint col_access=thd->col_access; uint col_access=thd->col_access;
#endif #endif
TABLE_LIST table_list; TABLE_LIST table_list;
char tbbuff[FN_REFLEN];
DBUG_ENTER("mysql_find_files"); DBUG_ENTER("mysql_find_files");
if (wild && !wild[0]) if (wild && !wild[0])
@ -484,8 +483,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
VOID(tablename_to_filename(tmp_file_prefix, tbbuff, sizeof(tbbuff)));
for (i=0 ; i < (uint) dirp->number_off_files ; i++) for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{ {
char uname[NAME_LEN*3+1]; /* Unencoded name */ char uname[NAME_LEN*3+1]; /* Unencoded name */
@ -523,7 +520,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
{ {
// Return only .frm files which aren't temp files. // Return only .frm files which aren't temp files.
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) || if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
is_prefix(file->name,tbbuff)) is_prefix(file->name, tmp_file_prefix))
continue; continue;
*ext=0; *ext=0;
VOID(filename_to_tablename(file->name, uname, sizeof(uname))); VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
@ -692,7 +689,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
} }
else else
{ {
length= build_table_filename(path, sizeof(path), dbname, "", ""); length= build_table_filename(path, sizeof(path), dbname, "", "", 0);
found_libchar= 0; found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR) if (length && path[length-1] == FN_LIBCHAR)
{ {
@ -2558,7 +2555,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
} }
else else
{ {
len= build_table_filename(path, sizeof(path), base_name, "", ""); len= build_table_filename(path, sizeof(path), base_name, "", "", 0);
end= path + len; end= path + len;
len= FN_LEN - len; len= FN_LEN - len;
if (mysql_find_files(thd, &files, base_name, if (mysql_find_files(thd, &files, base_name,
@ -2712,7 +2709,7 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
(grant_option && !check_grant_db(thd, file_name))) (grant_option && !check_grant_db(thd, file_name)))
#endif #endif
{ {
length= build_table_filename(path, sizeof(path), file_name, "", ""); length= build_table_filename(path, sizeof(path), file_name, "", "", 0);
found_libchar= 0; found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR) if (length && path[length-1] == FN_LIBCHAR)
{ {

View File

@ -51,31 +51,77 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" #define MYSQL50_TABLE_NAME_PREFIX "#mysql50#"
#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 #define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9
/*
Translate a file name to a table name (WL #1324).
SYNOPSIS
filename_to_tablename()
from The file name in my_charset_filename.
to OUT The table name in system_charset_info.
to_length The size of the table name buffer.
RETURN
Table name length.
*/
uint filename_to_tablename(const char *from, char *to, uint to_length) uint filename_to_tablename(const char *from, char *to, uint to_length)
{ {
uint errors, res= strconvert(&my_charset_filename, from, uint errors;
uint res;
DBUG_ENTER("filename_to_tablename");
DBUG_PRINT("enter", ("from '%s'", from));
if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
{
/* Temporary table name. */
res= (strnmov(to, from, to_length) - to);
}
else
{
res= strconvert(&my_charset_filename, from,
system_charset_info, to, to_length, &errors); system_charset_info, to, to_length, &errors);
if (errors) // Old 5.0 name if (errors) // Old 5.0 name
{ {
res= strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - to; res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) -
to);
sql_print_error("Invalid (old?) table or database name '%s'", from); sql_print_error("Invalid (old?) table or database name '%s'", from);
/* /*
TODO: add a stored procedure for fix table and database names, TODO: add a stored procedure for fix table and database names,
and mention its name in error log. and mention its name in error log.
*/ */
} }
return res;
} }
DBUG_PRINT("exit", ("to '%s'", to));
DBUG_RETURN(res);
}
/*
Translate a table name to a file name (WL #1324).
SYNOPSIS
tablename_to_filename()
from The table name in system_charset_info.
to OUT The file name in my_charset_filename.
to_length The size of the file name buffer.
RETURN
File name length.
*/
uint tablename_to_filename(const char *from, char *to, uint to_length) uint tablename_to_filename(const char *from, char *to, uint to_length)
{ {
uint errors, length; uint errors, length;
DBUG_ENTER("tablename_to_filename");
DBUG_PRINT("enter", ("from '%s'", from));
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX, if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH)) MYSQL50_TABLE_NAME_PREFIX_LENGTH))
return (uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH, DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
to_length-1) - to_length-1) -
(from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)); (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
length= strconvert(system_charset_info, from, length= strconvert(system_charset_info, from,
&my_charset_filename, to, to_length, &errors); &my_charset_filename, to, to_length, &errors);
if (check_if_legal_tablename(to) && if (check_if_legal_tablename(to) &&
@ -84,7 +130,8 @@ uint tablename_to_filename(const char *from, char *to, uint to_length)
memcpy(to + length, "@@@", 4); memcpy(to + length, "@@@", 4);
length+= 3; length+= 3;
} }
return length; DBUG_PRINT("exit", ("to '%s'", to));
DBUG_RETURN(length);
} }
@ -93,52 +140,87 @@ uint tablename_to_filename(const char *from, char *to, uint to_length)
SYNOPSIS SYNOPSIS
build_table_filename() build_table_filename()
buff where to write result buff Where to write result in my_charset_filename.
bufflen buff size bufflen buff size
db database name, in system_charset_info db Database name in system_charset_info.
table table name, in system_charset_info table_name Table name in system_charset_info.
ext file extension ext File extension.
flags FN_FROM_IS_TMP or FN_TO_IS_TMP or FN_IS_TMP
table_name is temporary, do not change.
NOTES NOTES
Uses database and table name, and extension to create Uses database and table name, and extension to create
a file name in mysql_data_dir. Database and table a file name in mysql_data_dir. Database and table
names are converted from system_charset_info into "fscs". names are converted from system_charset_info into "fscs".
Unless flags indicate a temporary table name.
'db' is always converted.
'ext' is not converted. 'ext' is not converted.
RETURN The conversion suppression is required for ALTER TABLE. This
statement creates intermediate tables. These are regular
(non-temporary) tables with a temporary name. Their path names must
be derivable from the table name. So we cannot use
build_tmptable_filename() for them.
RETURN
path length
*/ */
uint build_table_filename(char *buff, size_t bufflen, const char *db, uint build_table_filename(char *buff, size_t bufflen, const char *db,
const char *table, const char *ext) const char *table_name, const char *ext, uint flags)
{ {
uint length; uint length;
char dbbuff[FN_REFLEN]; char dbbuff[FN_REFLEN];
char tbbuff[FN_REFLEN]; char tbbuff[FN_REFLEN];
VOID(tablename_to_filename(table, tbbuff, sizeof(tbbuff))); DBUG_ENTER("build_table_filename");
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
strnmov(tbbuff, table_name, sizeof(tbbuff));
else
VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff))); VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
strxnmov(buff, bufflen, length= strxnmov(buff, bufflen, mysql_data_home, "/", dbbuff,
mysql_data_home, "/", dbbuff, "/", tbbuff, ext, NullS); "/", tbbuff, ext, NullS) - buff;
length= unpack_filename(buff, buff); DBUG_PRINT("exit", ("buff: '%s'", buff));
return length; DBUG_RETURN(length);
} }
/*
Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
SYNOPSIS
build_tmptable_filename()
thd The thread handle.
buff Where to write result in my_charset_filename.
bufflen buff size
NOTES
Uses current_pid, thread_id, and tmp_table counter to create
a file name in mysql_tmpdir.
RETURN
path length
*/
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen) uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
{ {
uint length; uint length;
char tbbuff[FN_REFLEN];
char tmp_table_name[tmp_file_prefix_length+22+22+22+3]; char tmp_table_name[tmp_file_prefix_length+22+22+22+3];
DBUG_ENTER("build_tmptable_filename");
my_snprintf(tmp_table_name, sizeof(tmp_table_name), my_snprintf(tmp_table_name, sizeof(tmp_table_name),
"%s%lx_%lx_%x", "%s%lx_%lx_%x",
tmp_file_prefix, current_pid, tmp_file_prefix, current_pid,
thd->thread_id, thd->tmp_table++); thd->thread_id, thd->tmp_table++);
VOID(tablename_to_filename(tmp_table_name, tbbuff, sizeof(tbbuff)));
strxnmov(buff, bufflen, mysql_tmpdir, "/", tbbuff, reg_ext, NullS); strxnmov(buff, bufflen, mysql_tmpdir, "/", tmp_table_name, reg_ext, NullS);
length= unpack_filename(buff, buff); length= unpack_filename(buff, buff);
return length; DBUG_PRINT("exit", ("buff: '%s'", buff));
DBUG_RETURN(length);
} }
/* /*
@ -1201,7 +1283,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
Build shadow frm file name Build shadow frm file name
*/ */
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#", 0);
strxmov(shadow_frm_name, shadow_path, reg_ext, NullS); strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
if (flags & WFRM_WRITE_SHADOW) if (flags & WFRM_WRITE_SHADOW)
{ {
@ -1285,7 +1367,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
Build frm file name Build frm file name
*/ */
build_table_filename(path, sizeof(path), lpt->db, build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, ""); lpt->table_name, "", 0);
strxmov(frm_name, path, reg_ext, NullS); strxmov(frm_name, path, reg_ext, NullS);
/* /*
When we are changing to use new frm file we need to ensure that we When we are changing to use new frm file we need to ensure that we
@ -1618,7 +1700,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
alias= (lower_case_table_names == 2) ? table->alias : table->table_name; alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
/* remove .frm file and engine files */ /* remove .frm file and engine files */
path_length= build_table_filename(path, sizeof(path), path_length= build_table_filename(path, sizeof(path),
db, alias, reg_ext); db, alias, reg_ext, 0);
} }
if (drop_temporary || if (drop_temporary ||
(table_type == NULL && (table_type == NULL &&
@ -1742,15 +1824,30 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
} }
/*
Quickly remove a table.
SYNOPSIS
quick_rm_table()
base The handlerton handle.
db The database name.
table_name The table name.
flags flags for build_table_filename().
RETURN
0 OK
!= 0 Error
*/
bool quick_rm_table(handlerton *base,const char *db, bool quick_rm_table(handlerton *base,const char *db,
const char *table_name) const char *table_name, uint flags)
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
bool error= 0; bool error= 0;
DBUG_ENTER("quick_rm_table"); DBUG_ENTER("quick_rm_table");
uint path_length= build_table_filename(path, sizeof(path), uint path_length= build_table_filename(path, sizeof(path),
db, table_name, reg_ext); db, table_name, reg_ext, flags);
if (my_delete(path,MYF(0))) if (my_delete(path,MYF(0)))
error= 1; /* purecov: inspected */ error= 1; /* purecov: inspected */
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
@ -2901,7 +2998,7 @@ static void set_table_default_charset(THD *thd,
HA_CREATE_INFO db_info; HA_CREATE_INFO db_info;
char path[FN_REFLEN]; char path[FN_REFLEN];
/* Abuse build_table_filename() to build the path to the db.opt file */ /* Abuse build_table_filename() to build the path to the db.opt file */
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE); build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
load_db_opt(thd, path, &db_info); load_db_opt(thd, path, &db_info);
create_info->default_table_charset= db_info.default_table_charset; create_info->default_table_charset= db_info.default_table_charset;
} }
@ -3084,6 +3181,8 @@ bool mysql_create_table_internal(THD *thd,
handler *file; handler *file;
bool error= TRUE; bool error= TRUE;
DBUG_ENTER("mysql_create_table_internal"); DBUG_ENTER("mysql_create_table_internal");
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
db, table_name, internal_tmp_table));
if (use_copy_create_info) if (use_copy_create_info)
{ {
@ -3303,7 +3402,8 @@ bool mysql_create_table_internal(THD *thd,
start++; start++;
} }
#endif #endif
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext); path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
internal_tmp_table ? FN_IS_TMP : 0);
} }
/* Check if table already exists */ /* Check if table already exists */
@ -3513,12 +3613,30 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
** Alter a table definition ** Alter a table definition
****************************************************************************/ ****************************************************************************/
/*
Rename a table.
SYNOPSIS
mysql_rename_table()
base The handlerton handle.
old_db The old database name.
old_name The old table name.
new_db The new database name.
new_name The new table name.
flags flags for build_table_filename().
FN_FROM_IS_TMP old_name is temporary.
FN_TO_IS_TMP new_name is temporary.
RETURN
0 OK
!= 0 Error
*/
bool bool
mysql_rename_table(handlerton *base, mysql_rename_table(handlerton *base, const char *old_db,
const char *old_db, const char *old_name, const char *new_db,
const char *old_name, const char *new_name, uint flags)
const char *new_db,
const char *new_name)
{ {
THD *thd= current_thd; THD *thd= current_thd;
char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN]; char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
@ -3527,12 +3645,16 @@ mysql_rename_table(handlerton *base,
handler *file; handler *file;
int error=0; int error=0;
DBUG_ENTER("mysql_rename_table"); DBUG_ENTER("mysql_rename_table");
DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
old_db, old_name, new_db, new_name));
file= (base == NULL ? 0 : file= (base == NULL ? 0 :
get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base)); get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
build_table_filename(from, sizeof(from), old_db, old_name, ""); build_table_filename(from, sizeof(from), old_db, old_name, "",
build_table_filename(to, sizeof(to), new_db, new_name, ""); flags & FN_FROM_IS_TMP);
build_table_filename(to, sizeof(to), new_db, new_name, "",
flags & FN_TO_IS_TMP);
/* /*
If lower_case_table_names == 2 (case-preserving but case-insensitive If lower_case_table_names == 2 (case-preserving but case-insensitive
@ -3544,12 +3666,14 @@ mysql_rename_table(handlerton *base,
{ {
strmov(tmp_name, old_name); strmov(tmp_name, old_name);
my_casedn_str(files_charset_info, tmp_name); my_casedn_str(files_charset_info, tmp_name);
build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, ""); build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
flags & FN_FROM_IS_TMP);
from_base= lc_from; from_base= lc_from;
strmov(tmp_name, new_name); strmov(tmp_name, new_name);
my_casedn_str(files_charset_info, tmp_name); my_casedn_str(files_charset_info, tmp_name);
build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, ""); build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
flags & FN_TO_IS_TMP);
to_base= lc_to; to_base= lc_to;
} }
@ -3685,7 +3809,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
if (fn_format_relative_to_data_home(src_path, uname, backup_dir, reg_ext)) if (fn_format_relative_to_data_home(src_path, uname, backup_dir, reg_ext))
DBUG_RETURN(-1); // protect buffer overflow DBUG_RETURN(-1); // protect buffer overflow
build_table_filename(dst_path, sizeof(dst_path), db, table_name, reg_ext); build_table_filename(dst_path, sizeof(dst_path),
db, table_name, reg_ext, 0);
if (lock_and_wait_for_table_name(thd,table)) if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1); DBUG_RETURN(-1);
@ -3762,6 +3887,15 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
table= &tmp_table; table= &tmp_table;
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
} }
/*
REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
*/
if (table->s->tmp_table)
{
error= send_check_errmsg(thd, table_list, "repair",
"Cannot repair temporary table from .frm file");
goto end;
}
/* /*
User gave us USE_FRM which means that the header in the index file is User gave us USE_FRM which means that the header in the index file is
@ -4459,7 +4593,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else else
{ {
build_table_filename(src_path, sizeof(src_path), build_table_filename(src_path, sizeof(src_path),
src_db, src_table, reg_ext); src_db, src_table, reg_ext, 0);
/* Resolve symlinks (for windows) */ /* Resolve symlinks (for windows) */
unpack_filename(src_path, src_path); unpack_filename(src_path, src_path);
if (lower_case_table_names) if (lower_case_table_names)
@ -4498,7 +4632,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else else
{ {
dst_path_length= build_table_filename(dst_path, sizeof(dst_path), dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
db, table_name, reg_ext); db, table_name, reg_ext, 0);
if (!access(dst_path, F_OK)) if (!access(dst_path, F_OK))
goto table_exists; goto table_exists;
} }
@ -4548,7 +4682,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else if (err) else if (err)
{ {
(void) quick_rm_table(create_info->db_type, db, (void) quick_rm_table(create_info->db_type, db,
table_name); /* purecov: inspected */ table_name, 0); /* purecov: inspected */
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
} }
@ -5062,8 +5196,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
db=table_list->db; db=table_list->db;
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
new_db= db; new_db= db;
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext); build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
build_table_filename(path, sizeof(path), db, table_name, ""); build_table_filename(path, sizeof(path), db, table_name, "", 0);
used_fields=create_info->used_fields; used_fields=create_info->used_fields;
@ -5080,6 +5214,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
/* Check that we are not trying to rename to an existing table */ /* Check that we are not trying to rename to an existing table */
if (new_name) if (new_name)
{ {
DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
strmov(new_name_buff,new_name); strmov(new_name_buff,new_name);
strmov(new_alias= new_alias_buff, new_name); strmov(new_alias= new_alias_buff, new_name);
if (lower_case_table_names) if (lower_case_table_names)
@ -5112,11 +5247,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
} }
else else
{ {
char dir_buff[FN_REFLEN]; build_table_filename(new_name_buff, sizeof(new_name_buff),
strxnmov(dir_buff, sizeof(dir_buff)-1, new_db, new_name_buff, reg_ext, 0);
mysql_real_data_home, new_db, NullS); if (!access(new_name_buff, F_OK))
if (!access(fn_format(new_name_buff,new_name_buff,dir_buff,reg_ext,0),
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_alias); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
@ -5197,13 +5330,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
*fn_ext(new_name)=0; *fn_ext(new_name)=0;
table->s->version= 0; // Force removal of table def table->s->version= 0; // Force removal of table def
close_cached_table(thd, table); close_cached_table(thd, table);
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
error= -1; error= -1;
else if (Table_triggers_list::change_table_name(thd, db, table_name, else if (Table_triggers_list::change_table_name(thd, db, table_name,
new_db, new_alias)) new_db, new_alias))
{ {
VOID(mysql_rename_table(old_db_type, new_db, new_alias, db, VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
table_name)); table_name, 0));
error= -1; error= -1;
} }
} }
@ -5834,7 +5967,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
/* table is a normal table: Create temporary table in same directory */ /* table is a normal table: Create temporary table in same directory */
build_table_filename(path, sizeof(path), new_db, tmp_name, ""); build_table_filename(path, sizeof(path), new_db, tmp_name, "",
FN_IS_TMP);
new_table=open_temporary_table(thd, path, new_db, tmp_name,0); new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
} }
if (!new_table) if (!new_table)
@ -6047,7 +6181,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (error) if (error)
{ {
VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
goto err; goto err;
} }
@ -6069,7 +6203,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{ {
error=1; error=1;
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
goto err; goto err;
} }
@ -6097,22 +6231,24 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error=0; error=0;
if (!need_copy_table) if (!need_copy_table)
new_db_type=old_db_type= NULL; // this type cannot happen in regular ALTER new_db_type=old_db_type= NULL; // this type cannot happen in regular ALTER
if (mysql_rename_table(old_db_type,db,table_name,db,old_name)) if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
FN_TO_IS_TMP))
{ {
error=1; error=1;
VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
} }
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_alias) || new_alias, FN_FROM_IS_TMP) ||
(new_name != table_name || new_db != db) && // we also do rename (new_name != table_name || new_db != db) && // we also do rename
Table_triggers_list::change_table_name(thd, db, table_name, Table_triggers_list::change_table_name(thd, db, table_name,
new_db, new_alias)) new_db, 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_alias)); VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
VOID(mysql_rename_table(old_db_type,db,old_name,db,alias)); VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
FN_FROM_IS_TMP));
} }
if (error) if (error)
{ {
@ -6156,7 +6292,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
table->s->version= 0; // Force removal of table def table->s->version= 0; // Force removal of table def
close_cached_table(thd,table); close_cached_table(thd,table);
} }
VOID(quick_rm_table(old_db_type,db,old_name)); VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
} }
else else
{ {
@ -6173,7 +6309,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
/* end threads waiting on lock */ /* end threads waiting on lock */
mysql_lock_abort(thd,table, TRUE); mysql_lock_abort(thd,table, TRUE);
} }
VOID(quick_rm_table(old_db_type,db,old_name)); VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
if (close_data_tables(thd,db,table_name) || if (close_data_tables(thd,db,table_name) ||
reopen_tables(thd,1,0)) reopen_tables(thd,1,0))
{ // This shouldn't happen { // This shouldn't happen
@ -6223,7 +6359,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
shutdown. shutdown.
*/ */
char path[FN_REFLEN]; char path[FN_REFLEN];
build_table_filename(path, sizeof(path), new_db, table_name, ""); build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
table=open_temporary_table(thd, path, new_db, tmp_name,0); table=open_temporary_table(thd, path, new_db, tmp_name,0);
if (table) if (table)
{ {
@ -6254,7 +6390,7 @@ end_temporary:
close_temporary_table(thd, new_table, 1, 1); close_temporary_table(thd, new_table, 1, 1);
} }
else else
VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
err: err:
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);

View File

@ -468,12 +468,12 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*/ */
file.length= build_table_filename(file_buff, FN_REFLEN-1, file.length= build_table_filename(file_buff, FN_REFLEN-1,
tables->db, tables->table_name, tables->db, tables->table_name,
triggers_file_ext); triggers_file_ext, 0);
file.str= file_buff; file.str= file_buff;
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
tables->db, tables->db,
lex->spname->m_name.str, lex->spname->m_name.str,
trigname_file_ext); trigname_file_ext, 0);
trigname_file.str= trigname_buff; trigname_file.str= trigname_buff;
/* Use the filesystem to enforce trigger namespace constraints. */ /* Use the filesystem to enforce trigger namespace constraints. */
@ -579,7 +579,7 @@ err_with_cleanup:
static bool rm_trigger_file(char *path, const char *db, static bool rm_trigger_file(char *path, const char *db,
const char *table_name) const char *table_name)
{ {
build_table_filename(path, FN_REFLEN-1, db, table_name, triggers_file_ext); build_table_filename(path, FN_REFLEN-1, db, table_name, triggers_file_ext, 0);
return my_delete(path, MYF(MY_WME)); return my_delete(path, MYF(MY_WME));
} }
@ -602,7 +602,8 @@ static bool rm_trigger_file(char *path, const char *db,
static bool rm_trigname_file(char *path, const char *db, static bool rm_trigname_file(char *path, const char *db,
const char *trigger_name) const char *trigger_name)
{ {
build_table_filename(path, FN_REFLEN-1, db, trigger_name, trigname_file_ext); build_table_filename(path, FN_REFLEN-1,
db, trigger_name, trigname_file_ext, 0);
return my_delete(path, MYF(MY_WME)); return my_delete(path, MYF(MY_WME));
} }
@ -628,7 +629,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
LEX_STRING file; LEX_STRING file;
file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name, file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name,
triggers_file_ext); triggers_file_ext, 0);
file.str= file_buff; file.str= file_buff;
return sql_create_definition_file(NULL, &file, &triggers_file_type, return sql_create_definition_file(NULL, &file, &triggers_file_type,
(gptr)triggers, triggers_file_parameters, (gptr)triggers, triggers_file_parameters,
@ -803,7 +804,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
DBUG_ENTER("Table_triggers_list::check_n_load"); DBUG_ENTER("Table_triggers_list::check_n_load");
path.length= build_table_filename(path_buff, FN_REFLEN-1, path.length= build_table_filename(path_buff, FN_REFLEN-1,
db, table_name, triggers_file_ext); db, table_name, triggers_file_ext, 0);
path.str= path_buff; path.str= path_buff;
// QQ: should we analyze errno somehow ? // QQ: should we analyze errno somehow ?
@ -1159,7 +1160,7 @@ static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig)
path.length= build_table_filename(path_buff, FN_REFLEN-1, path.length= build_table_filename(path_buff, FN_REFLEN-1,
trig->m_db.str, trig->m_name.str, trig->m_db.str, trig->m_name.str,
trigname_file_ext); trigname_file_ext, 0);
path.str= path_buff; path.str= path_buff;
if (access(path_buff, F_OK)) if (access(path_buff, F_OK))
@ -1366,7 +1367,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
{ {
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
db_name, trigger->str, db_name, trigger->str,
trigname_file_ext); trigname_file_ext, 0);
trigname_file.str= trigname_buff; trigname_file.str= trigname_buff;
trigname.trigger_table= *new_table_name; trigname.trigger_table= *new_table_name;

View File

@ -662,11 +662,11 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
/* print file name */ /* print file name */
dir.length= build_table_filename(dir_buff, sizeof(dir_buff), dir.length= build_table_filename(dir_buff, sizeof(dir_buff),
view->db, "", ""); view->db, "", "", 0);
dir.str= dir_buff; dir.str= dir_buff;
path.length= build_table_filename(path_buff, sizeof(path_buff), path.length= build_table_filename(path_buff, sizeof(path_buff),
view->db, view->table_name, reg_ext); view->db, view->table_name, reg_ext, 0);
path.str= path_buff; path.str= path_buff;
file.str= path.str + dir.length; file.str= path.str + dir.length;
@ -1311,7 +1311,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
TABLE_SHARE *share; TABLE_SHARE *share;
frm_type_enum type= FRMTYPE_ERROR; frm_type_enum type= FRMTYPE_ERROR;
build_table_filename(path, sizeof(path), build_table_filename(path, sizeof(path),
view->db, view->table_name, reg_ext); view->db, view->table_name, reg_ext, 0);
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (access(path, F_OK) || if (access(path, F_OK) ||

View File

@ -9331,7 +9331,6 @@ user:
keyword: keyword:
keyword_sp {} keyword_sp {}
| ASCII_SYM {} | ASCII_SYM {}
| AUTHORS_SYM {}
| BACKUP_SYM {} | BACKUP_SYM {}
| BEGIN_SYM {} | BEGIN_SYM {}
| BYTE_SYM {} | BYTE_SYM {}
@ -9389,6 +9388,7 @@ keyword_sp:
| ALGORITHM_SYM {} | ALGORITHM_SYM {}
| ANY_SYM {} | ANY_SYM {}
| AT_SYM {} | AT_SYM {}
| AUTHORS_SYM {}
| AUTO_INC {} | AUTO_INC {}
| AUTOEXTEND_SIZE_SYM {} | AUTOEXTEND_SIZE_SYM {}
| AVG_ROW_LENGTH {} | AVG_ROW_LENGTH {}
@ -9414,6 +9414,7 @@ keyword_sp:
| COMPRESSED_SYM {} | COMPRESSED_SYM {}
| CONCURRENT {} | CONCURRENT {}
| CONSISTENT_SYM {} | CONSISTENT_SYM {}
| CONTRIBUTORS_SYM {}
| CUBE_SYM {} | CUBE_SYM {}
| DATA_SYM {} | DATA_SYM {}
| DATAFILE_SYM {} | DATAFILE_SYM {}

View File

@ -68,7 +68,7 @@ static byte *get_field_name(Field **buff, uint *length,
char *fn_rext(char *name) char *fn_rext(char *name)
{ {
char *res= strrchr(name, '.'); char *res= strrchr(name, '.');
if (res && !strcmp(res, ".frm")) if (res && !strcmp(res, reg_ext))
return res; return res;
return name + strlen(name); return name + strlen(name);
} }
@ -95,10 +95,13 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
TABLE_SHARE *share; TABLE_SHARE *share;
char path[FN_REFLEN]; char path[FN_REFLEN];
uint path_length; uint path_length;
DBUG_ENTER("alloc_table_share");
DBUG_PRINT("enter", ("table: '%s'.'%s'",
table_list->db, table_list->table_name));
path_length= build_table_filename(path, sizeof(path) - 1, path_length= build_table_filename(path, sizeof(path) - 1,
table_list->db, table_list->db,
table_list->table_name, ""); table_list->table_name, "", 0);
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
if ((share= (TABLE_SHARE*) alloc_root(&mem_root, if ((share= (TABLE_SHARE*) alloc_root(&mem_root,
sizeof(*share) + key_length + sizeof(*share) + key_length +
@ -148,7 +151,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&share->cond, NULL); pthread_cond_init(&share->cond, NULL);
} }
return share; DBUG_RETURN(share);
} }
@ -179,6 +182,7 @@ void init_tmp_table_share(TABLE_SHARE *share, const char *key,
const char *path) const char *path)
{ {
DBUG_ENTER("init_tmp_table_share"); DBUG_ENTER("init_tmp_table_share");
DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name));
bzero((char*) share, sizeof(*share)); bzero((char*) share, sizeof(*share));
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
@ -286,7 +290,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
char path[FN_REFLEN]; char path[FN_REFLEN];
MEM_ROOT **root_ptr, *old_root; MEM_ROOT **root_ptr, *old_root;
DBUG_ENTER("open_table_def"); DBUG_ENTER("open_table_def");
DBUG_PRINT("enter", ("name: '%s.%s'",share->db.str, share->table_name.str)); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str,
share->table_name.str, share->normalized_path.str));
error= 1; error= 1;
error_given= 0; error_given= 0;

View File

@ -3419,8 +3419,8 @@ row_is_mysql_tmp_table_name(
const char* name) /* in: table name in the form const char* name) /* in: table name in the form
'database/tablename' */ 'database/tablename' */
{ {
/* return(strstr(name, "/#sql") != NULL); */ return(strstr(name, "/#sql") != NULL);
return(strstr(name, "/@0023sql") != NULL); /* return(strstr(name, "/@0023sql") != NULL); */
} }
/******************************************************************** /********************************************************************

View File

@ -1304,12 +1304,41 @@ void _my_store_blob_length(byte *pos,uint pack_length,uint length)
} }
/* Read record from datafile */ /*
/* Returns 0 if ok, -1 if error */ Read record from datafile.
SYNOPSIS
_mi_read_dynamic_record()
info MI_INFO pointer to table.
filepos From where to read the record.
buf Destination for record.
NOTE
If a write buffer is active, it needs to be flushed if its contents
intersects with the record to read. We always check if the position
of the first byte of the write buffer is lower than the position
past the last byte to read. In theory this is also true if the write
buffer is completely below the read segment. That is, if there is no
intersection. But this case is unusual. We flush anyway. Only if the
first byte in the write buffer is above the last byte to read, we do
not flush.
A dynamic record may need several reads. So this check must be done
before every read. Reading a dynamic record starts with reading the
block header. If the record does not fit into the free space of the
header, the block may be longer than the header. In this case a
second read is necessary. These one or two reads repeat for every
part of the record.
RETURN
0 OK
-1 Error
*/
int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
{ {
int flag; int block_of_record;
uint b_type,left_length; uint b_type,left_length;
byte *to; byte *to;
MI_BLOCK_INFO block_info; MI_BLOCK_INFO block_info;
@ -1321,20 +1350,19 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
LINT_INIT(to); LINT_INIT(to);
LINT_INIT(left_length); LINT_INIT(left_length);
file=info->dfile; file=info->dfile;
block_info.next_filepos=filepos; /* for easyer loop */ block_of_record= 0; /* First block of record is numbered as zero. */
flag=block_info.second_read=0; block_info.second_read= 0;
do do
{ {
/* A corrupted table can have wrong pointers. (Bug# 19835) */
if (filepos == HA_OFFSET_ERROR)
goto panic;
if (info->opt_flag & WRITE_CACHE_USED && if (info->opt_flag & WRITE_CACHE_USED &&
info->rec_cache.pos_in_file <= block_info.next_filepos && info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
flush_io_cache(&info->rec_cache)) flush_io_cache(&info->rec_cache))
goto err; goto err;
/* A corrupted table can have wrong pointers. (Bug# 19835) */
if (block_info.next_filepos == HA_OFFSET_ERROR)
goto panic;
info->rec_cache.seek_not_done=1; info->rec_cache.seek_not_done=1;
if ((b_type=_mi_get_block_info(&block_info,file, if ((b_type= _mi_get_block_info(&block_info, file, filepos))
block_info.next_filepos))
& (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
BLOCK_FATAL_ERROR)) BLOCK_FATAL_ERROR))
{ {
@ -1342,9 +1370,8 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
my_errno=HA_ERR_RECORD_DELETED; my_errno=HA_ERR_RECORD_DELETED;
goto err; goto err;
} }
if (flag == 0) /* First block */ if (block_of_record++ == 0) /* First block */
{ {
flag=1;
if (block_info.rec_len > (uint) info->s->base.max_pack_length) if (block_info.rec_len > (uint) info->s->base.max_pack_length)
goto panic; goto panic;
if (info->s->base.blobs) if (info->s->base.blobs)
@ -1359,11 +1386,41 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
} }
if (left_length < block_info.data_len || ! block_info.data_len) if (left_length < block_info.data_len || ! block_info.data_len)
goto panic; /* Wrong linked record */ goto panic; /* Wrong linked record */
if (info->s->file_read(info,(byte*) to,block_info.data_len,block_info.filepos, /* copy information that is already read */
MYF(MY_NABP))) {
uint offset= (uint) (block_info.filepos - filepos);
uint prefetch_len= (sizeof(block_info.header) - offset);
filepos+= sizeof(block_info.header);
if (prefetch_len > block_info.data_len)
prefetch_len= block_info.data_len;
if (prefetch_len)
{
memcpy((byte*) to, block_info.header + offset, prefetch_len);
block_info.data_len-= prefetch_len;
left_length-= prefetch_len;
to+= prefetch_len;
}
}
/* read rest of record from file */
if (block_info.data_len)
{
if (info->opt_flag & WRITE_CACHE_USED &&
info->rec_cache.pos_in_file < filepos + block_info.data_len &&
flush_io_cache(&info->rec_cache))
goto err;
/*
What a pity that this method is not called 'file_pread' and that
there is no equivalent without seeking. We are at the right
position already. :(
*/
if (info->s->file_read(info, (byte*) to, block_info.data_len,
filepos, MYF(MY_NABP)))
goto panic; goto panic;
left_length-=block_info.data_len; left_length-=block_info.data_len;
to+=block_info.data_len; to+=block_info.data_len;
}
filepos= block_info.next_filepos;
} while (left_length); } while (left_length);
info->update|= HA_STATE_AKTIV; /* We have a aktive record */ info->update|= HA_STATE_AKTIV; /* We have a aktive record */
@ -1520,11 +1577,45 @@ err:
} }
/*
Read record from datafile.
SYNOPSIS
_mi_read_rnd_dynamic_record()
info MI_INFO pointer to table.
buf Destination for record.
filepos From where to read the record.
skip_deleted_blocks If to repeat reading until a non-deleted
record is found.
NOTE
If a write buffer is active, it needs to be flushed if its contents
intersects with the record to read. We always check if the position
of the first byte of the write buffer is lower than the position
past the last byte to read. In theory this is also true if the write
buffer is completely below the read segment. That is, if there is no
intersection. But this case is unusual. We flush anyway. Only if the
first byte in the write buffer is above the last byte to read, we do
not flush.
A dynamic record may need several reads. So this check must be done
before every read. Reading a dynamic record starts with reading the
block header. If the record does not fit into the free space of the
header, the block may be longer than the header. In this case a
second read is necessary. These one or two reads repeat for every
part of the record.
RETURN
0 OK
!= 0 Error
*/
int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
register my_off_t filepos, register my_off_t filepos,
my_bool skip_deleted_blocks) my_bool skip_deleted_blocks)
{ {
int flag,info_read,save_errno; int block_of_record, info_read, save_errno;
uint left_len,b_type; uint left_len,b_type;
byte *to; byte *to;
MI_BLOCK_INFO block_info; MI_BLOCK_INFO block_info;
@ -1550,7 +1641,8 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
else else
info_read=1; /* memory-keyinfoblock is ok */ info_read=1; /* memory-keyinfoblock is ok */
flag=block_info.second_read=0; block_of_record= 0; /* First block of record is numbered as zero. */
block_info.second_read= 0;
left_len=1; left_len=1;
do do
{ {
@ -1573,15 +1665,15 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
{ {
if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos,
sizeof(block_info.header), sizeof(block_info.header),
(!flag && skip_deleted_blocks ? READING_NEXT : 0) | (!block_of_record && skip_deleted_blocks ?
READING_HEADER)) READING_NEXT : 0) | READING_HEADER))
goto panic; goto panic;
b_type=_mi_get_block_info(&block_info,-1,filepos); b_type=_mi_get_block_info(&block_info,-1,filepos);
} }
else else
{ {
if (info->opt_flag & WRITE_CACHE_USED && if (info->opt_flag & WRITE_CACHE_USED &&
info->rec_cache.pos_in_file <= filepos && info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
flush_io_cache(&info->rec_cache)) flush_io_cache(&info->rec_cache))
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
info->rec_cache.seek_not_done=1; info->rec_cache.seek_not_done=1;
@ -1606,7 +1698,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
} }
goto err; goto err;
} }
if (flag == 0) /* First block */ if (block_of_record == 0) /* First block */
{ {
if (block_info.rec_len > (uint) share->base.max_pack_length) if (block_info.rec_len > (uint) share->base.max_pack_length)
goto panic; goto panic;
@ -1648,11 +1740,17 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
{ {
if (_mi_read_cache(&info->rec_cache,(byte*) to,filepos, if (_mi_read_cache(&info->rec_cache,(byte*) to,filepos,
block_info.data_len, block_info.data_len,
(!flag && skip_deleted_blocks) ? READING_NEXT :0)) (!block_of_record && skip_deleted_blocks) ?
READING_NEXT : 0))
goto panic; goto panic;
} }
else else
{ {
if (info->opt_flag & WRITE_CACHE_USED &&
info->rec_cache.pos_in_file <
block_info.filepos + block_info.data_len &&
flush_io_cache(&info->rec_cache))
goto err;
/* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */ /* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */
if (my_read(info->dfile,(byte*) to,block_info.data_len,MYF(MY_NABP))) if (my_read(info->dfile,(byte*) to,block_info.data_len,MYF(MY_NABP)))
{ {
@ -1662,7 +1760,11 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
} }
} }
} }
if (flag++ == 0) /*
Increment block-of-record counter. If it was the first block,
remember the position behind the block for the next call.
*/
if (block_of_record++ == 0)
{ {
info->nextpos= block_info.filepos + block_info.block_len; info->nextpos= block_info.filepos + block_info.block_len;
skip_deleted_blocks= 0; skip_deleted_blocks= 0;
@ -1697,6 +1799,11 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
if (file >= 0) if (file >= 0)
{ {
/*
We do not use my_pread() here because we want to have the file
pointer set to the end of the header after this function.
my_pread() may leave the file pointer untouched.
*/
VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) != if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) !=
sizeof(info->header)) sizeof(info->header))