summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <patg@govinda.patg.net>2006-08-10 14:28:39 -0700
committerunknown <patg@govinda.patg.net>2006-08-10 14:28:39 -0700
commit58590b3a53e641fab894e754298732d5cd1ed954 (patch)
tree92c83b7c1575acee956bf483c14ac7fddb177aa9
parent6c086377d8d1ea5b53a25f4dc3e1189e98c08a08 (diff)
parent375692973df6b71826a11f470cb6d521bfa16cc9 (diff)
downloadmariadb-git-58590b3a53e641fab894e754298732d5cd1ed954.tar.gz
Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.1
into govinda.patg.net:/home/patg/mysql-build/mysql-5.1-engines-merge sql/ha_myisam.cc: Auto merged sql/ha_myisammrg.cc: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_partition.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_trigger.cc: Auto merged sql/sql_view.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.cc: Auto merged storage/innobase/row/row0mysql.c: Auto merged
-rw-r--r--mysql-test/r/alter_table.result65
-rw-r--r--mysql-test/r/backup.result20
-rw-r--r--mysql-test/r/federated_transactions.result2
-rw-r--r--mysql-test/r/keywords.result16
-rw-r--r--mysql-test/r/repair.result6
-rw-r--r--mysql-test/t/alter_table.test54
-rw-r--r--mysql-test/t/backup.test19
-rw-r--r--mysql-test/t/federated_transactions-slave.opt1
-rw-r--r--mysql-test/t/federated_transactions.test4
-rw-r--r--mysql-test/t/keywords.test24
-rw-r--r--mysql-test/t/repair.test13
-rw-r--r--sql/ha_myisam.cc10
-rw-r--r--sql/ha_myisammrg.cc2
-rw-r--r--sql/ha_ndbcluster.cc14
-rw-r--r--sql/ha_ndbcluster_binlog.cc13
-rw-r--r--sql/ha_ndbcluster_binlog.h2
-rw-r--r--sql/mysql_priv.h17
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc13
-rw-r--r--sql/sql_db.cc22
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_partition.cc26
-rw-r--r--sql/sql_rename.cc8
-rw-r--r--sql/sql_show.cc11
-rw-r--r--sql/sql_table.cc286
-rw-r--r--sql/sql_trigger.cc17
-rw-r--r--sql/sql_view.cc6
-rw-r--r--sql/sql_yacc.yy3
-rw-r--r--sql/table.cc13
-rw-r--r--storage/innobase/row/row0mysql.c4
-rw-r--r--storage/myisam/mi_dynrec.c165
32 files changed, 676 insertions, 192 deletions
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index f4332ea9888..d3657d84678 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -657,3 +657,68 @@ SELECT * FROM t1;
v b
abc 5
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`;
diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result
index a65808bbdd6..a4d1b18fe61 100644
--- a/mysql-test/r/backup.result
+++ b/mysql-test/r/backup.result
@@ -101,3 +101,23 @@ test.t5 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 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`;
diff --git a/mysql-test/r/federated_transactions.result b/mysql-test/r/federated_transactions.result
index 403b65b5484..e6714210ded 100644
--- a/mysql-test/r/federated_transactions.result
+++ b/mysql-test/r/federated_transactions.result
@@ -16,7 +16,7 @@ CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
-DEFAULT CHARSET=latin1 ENGINE=BerkeleyDB;
+DEFAULT CHARSET=latin1 ENGINE=InnoDB;
DROP TABLE IF EXISTS federated.t1;
Warnings:
Note 1051 Unknown table 't1'
diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result
index 88a0ab8abd5..597983dab7e 100644
--- a/mysql-test/r/keywords.result
+++ b/mysql-test/r/keywords.result
@@ -16,3 +16,19 @@ select events.binlog from events;
binlog
1
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;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
index d8fa4dbbb72..f08dc6a8a4a 100644
--- a/mysql-test/r/repair.result
+++ b/mysql-test/r/repair.result
@@ -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 status OK
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;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index efe58579785..168d011a2ac 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -482,3 +482,57 @@ SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN v VARCHAR(4);
SELECT * FROM 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`;
+
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index 917c3f98ebb..61bde0cecb0 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -58,3 +58,22 @@ drop table t5;
--system rm $MYSQLTEST_VARDIR/tmp/t?.*
# 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`;
+
diff --git a/mysql-test/t/federated_transactions-slave.opt b/mysql-test/t/federated_transactions-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/federated_transactions-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/federated_transactions.test b/mysql-test/t/federated_transactions.test
index 5095c8ce9c3..9f3b030f462 100644
--- a/mysql-test/t/federated_transactions.test
+++ b/mysql-test/t/federated_transactions.test
@@ -1,6 +1,6 @@
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
-source include/have_bdb.inc;
+source include/have_innodb.inc;
source include/federated.inc;
connection slave;
@@ -10,7 +10,7 @@ CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
- DEFAULT CHARSET=latin1 ENGINE=BerkeleyDB;
+ DEFAULT CHARSET=latin1 ENGINE=InnoDB;
connection master;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test
index de0159a950e..1af4a1354be 100644
--- a/mysql-test/t/keywords.test
+++ b/mysql-test/t/keywords.test
@@ -19,3 +19,27 @@ select events.binlog from events;
drop table events;
# 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
diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test
index 16e1d76d460..c79768dbb46 100644
--- a/mysql-test/t/repair.test
+++ b/mysql-test/t/repair.test
@@ -35,3 +35,16 @@ repair table t1 use_frm;
drop table t1;
# 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;
+
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 565010a1889..cbb8a7a48c0 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -473,11 +473,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
HA_CHECK_OPT tmp_check_opt;
char *backup_dir= thd->lex->backup_dir;
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;
const char* errmsg;
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,
MI_NAME_DEXT))
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 src_path[FN_REFLEN], dst_path[FN_REFLEN];
- const char *table_name= table->s->table_name.str;
+ char table_name[FN_REFLEN];
int error;
const char *errmsg;
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,
reg_ext))
{
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index a15787fdcf0..3ae5406824c 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -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.
*/
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,
we use the table name without a path. This means that the
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 64f0cc0b76e..9b44573673d 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -5801,7 +5801,7 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
DBUG_RETURN(HA_ERR_NO_CONNECTION);
ndb->setDatabaseName(db);
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);
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
char full_path[FN_REFLEN];
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);
List_iterator_fast<char> it(drop_list);
@@ -6067,7 +6067,7 @@ int ndbcluster_find_all_files(THD *thd)
/* check if database exists */
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))
{
/* 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
- 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));
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 */
{
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++)
{
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);
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))
{
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;
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));
pthread_mutex_lock(&ndbcluster_mutex);
if (!(share=(NDB_SHARE*) hash_search(&ndbcluster_open_tables,
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 8e9f0077dd0..ee9e639199c 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -737,7 +737,7 @@ static int ndbcluster_create_apply_status_table(THD *thd)
*/
{
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));
}
@@ -786,7 +786,7 @@ static int ndbcluster_create_schema_table(THD *thd)
*/
{
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));
}
@@ -1247,7 +1247,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
NDB_SCHEMA_OBJECT *ndb_schema_object;
{
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);
}
@@ -1577,7 +1577,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
DBUG_PRINT("info", ("Detected frm change of table %s.%s",
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
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:
{
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);
// invalidation already handled by binlog thread
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;
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)
{
pthread_mutex_lock(&ndbcluster_mutex);
diff --git a/sql/ha_ndbcluster_binlog.h b/sql/ha_ndbcluster_binlog.h
index 58bf7517df5..4c3cd105d1d 100644
--- a/sql/ha_ndbcluster_binlog.h
+++ b/sql/ha_ndbcluster_binlog.h
@@ -23,7 +23,7 @@ typedef NdbDictionary::Index NDBINDEX;
typedef NdbDictionary::Dictionary NDBDICT;
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;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index a9ecbb23a27..2fb02f0d9b8 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -754,7 +754,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
bool if_exists, bool drop_temporary,
bool log_query);
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);
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);
@@ -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,
HA_CREATE_INFO *create_info,
Table_ident *src_table);
-bool mysql_rename_table(handlerton *base,
- const char *old_db,
- const char * old_name,
- const char *new_db,
- const char * new_name);
+bool mysql_rename_table(handlerton *base, const char *old_db,
+ const char * old_name, const char *new_db,
+ const char * new_name, uint flags);
bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
bool mysql_drop_index(THD *thd, TABLE_LIST *table_list,
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 tablename_to_filename(const char *from, char *to, uint to_length);
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 */
struct in_addr;
my_string ip_to_hostname(struct in_addr *in,uint *errors);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 966d0f88ca3..5590dd0049d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2962,7 +2962,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{
char buf[FN_REFLEN];
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 |
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
if (access(buf,F_OK))
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8629cbda062..1c733e3c12d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -254,7 +254,7 @@ uint cached_table_definitions(void)
Get TABLE_SHARE for a table.
get_table_share()
- thd Table share
+ thd Thread handle
table_list Table that should be opened
key Table cache 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];
uint key_length;
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);
for (table=thd->temporary_tables ; table ; table= table->next)
{
if (table->s->table_cache_key.length == 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];
enum legacy_db_type not_used;
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)
{
/*
@@ -3511,6 +3514,8 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
uint key_length;
TABLE_LIST table_list;
DBUG_ENTER("open_temporary_table");
+ DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'",
+ db, table_name, path));
table_list.db= (char*) db;
table_list.table_name= (char*) table_name;
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 77d99862bf0..a5ad62ccad6 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -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));
/* 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
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
"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)))
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));
- 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
del_dbopt(path); // Remove dboption hash entry
path[length]= '\0'; // Remove file name
@@ -1324,7 +1324,7 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
}
}
#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)
path[path_length-1]= '\0'; // remove ending '\'
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))
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)))
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)
path[length-1]=0; // remove ending '\'
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.
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));
- 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)
path[length-1]=0; // remove ending '\'
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 */
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,
- new_db->str, "", file->name);
+ new_db->str, "", file->name, 0);
my_rename(oldname, newname, MYF(MY_WME));
}
my_dirend(dirp);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 659695e8e73..d2517dc7613 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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,
- table_list->table_name, reg_ext);
+ table_list->table_name, reg_ext, 0);
if (!dont_send_ok)
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index e0164fa07be..5df6b1832f5 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2823,7 +2823,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
((thd->prelocked_mode == PRELOCKED) ?
MYSQL_OPEN_IGNORE_LOCKED_TABLES:0)))))
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);
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);
VOID(pthread_mutex_unlock(&LOCK_open));
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);
}
table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -3026,7 +3027,8 @@ void select_create::abort()
table->s->version= 0;
hash_delete(&open_cache,(byte*) table);
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 */
if (version != refresh_version)
broadcast_refresh();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 73091c0994e..f1c8e099441 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -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_table= table_ident->table.str;
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,
FALSE, buf))
{
@@ -4715,7 +4715,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
handler *file= lpt->table->file;
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,
&lpt->deleted, lpt->pack_frm_data,
lpt->pack_frm_len)))
@@ -4755,7 +4755,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error;
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 != 1)
@@ -4796,7 +4796,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error;
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)))
{
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");
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
- lpt->table_name, "#");
+ lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, NULL,
(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;
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,
- lpt->table_name, "#");
+ lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE))
goto error;
@@ -5249,9 +5249,9 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL;
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,
- lpt->table_name, "#");
+ lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5306,9 +5306,9 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_add_change_partition");
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,
- lpt->table_name, "#");
+ lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5363,9 +5363,9 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL;
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,
- lpt->table_name, "#");
+ lpt->table_name, "#", 0);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
lpt->alter_info->flags & ALTER_REORGANIZE_PARTITION))
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index e3468b2b5cf..73473ddd24b 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -157,14 +157,14 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
new_alias= new_table->table_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))
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
DBUG_RETURN(ren_table); // This can't be skipped
}
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);
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,
table_type),
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,
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,
table_type),
new_table->db, new_alias,
- ren_table->db, old_alias);
+ ren_table->db, old_alias, 0);
}
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index bf09f516499..13296f69e69 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -467,7 +467,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
uint col_access=thd->col_access;
#endif
TABLE_LIST table_list;
- char tbbuff[FN_REFLEN];
DBUG_ENTER("mysql_find_files");
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);
}
- VOID(tablename_to_filename(tmp_file_prefix, tbbuff, sizeof(tbbuff)));
-
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{
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.
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;
*ext=0;
VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
@@ -692,7 +689,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
}
else
{
- length= build_table_filename(path, sizeof(path), dbname, "", "");
+ length= build_table_filename(path, sizeof(path), dbname, "", "", 0);
found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR)
{
@@ -2558,7 +2555,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
else
{
- len= build_table_filename(path, sizeof(path), base_name, "", "");
+ len= build_table_filename(path, sizeof(path), base_name, "", "", 0);
end= path + len;
len= FN_LEN - len;
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)))
#endif
{
- length= build_table_filename(path, sizeof(path), file_name, "", "");
+ length= build_table_filename(path, sizeof(path), file_name, "", "", 0);
found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5325758fd12..ecbf16650b3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -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_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 errors, res= strconvert(&my_charset_filename, from,
- system_charset_info, to, to_length, &errors);
- if (errors) // Old 5.0 name
+ 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))
{
- res= strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - to;
- sql_print_error("Invalid (old?) table or database name '%s'", from);
- /*
- TODO: add a stored procedure for fix table and database names,
- and mention its name in error log.
- */
+ /* Temporary table name. */
+ res= (strnmov(to, from, to_length) - to);
+ }
+ else
+ {
+ res= strconvert(&my_charset_filename, from,
+ system_charset_info, to, to_length, &errors);
+ if (errors) // Old 5.0 name
+ {
+ res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) -
+ to);
+ sql_print_error("Invalid (old?) table or database name '%s'", from);
+ /*
+ TODO: add a stored procedure for fix table and database names,
+ 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 errors, length;
+ DBUG_ENTER("tablename_to_filename");
+ DBUG_PRINT("enter", ("from '%s'", from));
+
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
- return (uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
- to_length-1) -
- (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH));
+ DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
+ to_length-1) -
+ (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
length= strconvert(system_charset_info, from,
&my_charset_filename, to, to_length, &errors);
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);
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
build_table_filename()
- buff where to write result
- bufflen buff size
- db database name, in system_charset_info
- table table name, in system_charset_info
- ext file extension
+ buff Where to write result in my_charset_filename.
+ bufflen buff size
+ db Database name in system_charset_info.
+ table_name Table name in system_charset_info.
+ 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
Uses database and table name, and extension to create
a file name in mysql_data_dir. Database and table
names are converted from system_charset_info into "fscs".
+ Unless flags indicate a temporary table name.
+ 'db' is always 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,
- const char *table, const char *ext)
+ const char *table_name, const char *ext, uint flags)
{
uint length;
char dbbuff[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)));
- strxnmov(buff, bufflen,
- mysql_data_home, "/", dbbuff, "/", tbbuff, ext, NullS);
- length= unpack_filename(buff, buff);
- return length;
+ length= strxnmov(buff, bufflen, mysql_data_home, "/", dbbuff,
+ "/", tbbuff, ext, NullS) - buff;
+ DBUG_PRINT("exit", ("buff: '%s'", buff));
+ 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 length;
- char tbbuff[FN_REFLEN];
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),
"%s%lx_%lx_%x",
tmp_file_prefix, current_pid,
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);
- 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_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);
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_table_filename(path, sizeof(path), lpt->db,
- lpt->table_name, "");
+ lpt->table_name, "", 0);
strxmov(frm_name, path, reg_ext, NullS);
/*
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;
/* remove .frm file and engine files */
path_length= build_table_filename(path, sizeof(path),
- db, alias, reg_ext);
+ db, alias, reg_ext, 0);
}
if (drop_temporary ||
(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,
- const char *table_name)
+ const char *table_name, uint flags)
{
char path[FN_REFLEN];
bool error= 0;
DBUG_ENTER("quick_rm_table");
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)))
error= 1; /* purecov: inspected */
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;
char path[FN_REFLEN];
/* 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);
create_info->default_table_charset= db_info.default_table_charset;
}
@@ -3084,6 +3181,8 @@ bool mysql_create_table_internal(THD *thd,
handler *file;
bool error= TRUE;
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)
{
@@ -3303,7 +3402,8 @@ bool mysql_create_table_internal(THD *thd,
start++;
}
#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 */
@@ -3513,12 +3613,30 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
** 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
-mysql_rename_table(handlerton *base,
- const char *old_db,
- const char *old_name,
- const char *new_db,
- const char *new_name)
+mysql_rename_table(handlerton *base, const char *old_db,
+ const char *old_name, const char *new_db,
+ const char *new_name, uint flags)
{
THD *thd= current_thd;
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;
int error=0;
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 :
get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
- build_table_filename(from, sizeof(from), old_db, old_name, "");
- build_table_filename(to, sizeof(to), new_db, new_name, "");
+ build_table_filename(from, sizeof(from), old_db, old_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
@@ -3544,12 +3666,14 @@ mysql_rename_table(handlerton *base,
{
strmov(tmp_name, old_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;
strmov(tmp_name, new_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;
}
@@ -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))
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))
DBUG_RETURN(-1);
@@ -3762,6 +3887,15 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
table= &tmp_table;
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
@@ -4459,7 +4593,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else
{
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) */
unpack_filename(src_path, src_path);
if (lower_case_table_names)
@@ -4498,7 +4632,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else
{
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))
goto table_exists;
}
@@ -4548,7 +4682,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
else if (err)
{
(void) quick_rm_table(create_info->db_type, db,
- table_name); /* purecov: inspected */
+ table_name, 0); /* 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;
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
new_db= db;
- build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext);
- build_table_filename(path, sizeof(path), db, table_name, "");
+ build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
+ build_table_filename(path, sizeof(path), db, table_name, "", 0);
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 */
if (new_name)
{
+ DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
strmov(new_name_buff,new_name);
strmov(new_alias= new_alias_buff, new_name);
if (lower_case_table_names)
@@ -5112,11 +5247,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
else
{
- char dir_buff[FN_REFLEN];
- strxnmov(dir_buff, sizeof(dir_buff)-1,
- mysql_real_data_home, new_db, NullS);
- if (!access(fn_format(new_name_buff,new_name_buff,dir_buff,reg_ext,0),
- F_OK))
+ build_table_filename(new_name_buff, sizeof(new_name_buff),
+ new_db, new_name_buff, reg_ext, 0);
+ if (!access(new_name_buff, F_OK))
{
/* Table will be closed in do_command() */
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;
table->s->version= 0; // Force removal of table def
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;
else if (Table_triggers_list::change_table_name(thd, db, table_name,
new_db, new_alias))
{
VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
- table_name));
+ table_name, 0));
error= -1;
}
}
@@ -5834,7 +5967,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
char path[FN_REFLEN];
/* 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);
}
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));
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));
goto err;
}
@@ -6069,7 +6203,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
error=1;
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));
goto err;
}
@@ -6097,22 +6231,24 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error=0;
if (!need_copy_table)
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;
- 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,
- new_alias) ||
+ new_alias, FN_FROM_IS_TMP) ||
(new_name != table_name || new_db != db) && // we also do rename
Table_triggers_list::change_table_name(thd, db, table_name,
new_db, new_alias))
-
- { // Try to get everything back
+ {
+ /* Try to get everything back. */
error=1;
- 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,alias));
+ VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
+ 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,
+ FN_FROM_IS_TMP));
}
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
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
{
@@ -6173,7 +6309,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
/* end threads waiting on lock */
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) ||
reopen_tables(thd,1,0))
{ // This shouldn't happen
@@ -6223,7 +6359,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
*/
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);
if (table)
{
@@ -6254,7 +6390,7 @@ end_temporary:
close_temporary_table(thd, new_table, 1, 1);
}
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:
DBUG_RETURN(TRUE);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 1837372c6c4..c2806b45121 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -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,
tables->db, tables->table_name,
- triggers_file_ext);
+ triggers_file_ext, 0);
file.str= file_buff;
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
tables->db,
lex->spname->m_name.str,
- trigname_file_ext);
+ trigname_file_ext, 0);
trigname_file.str= trigname_buff;
/* 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,
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));
}
@@ -602,7 +602,8 @@ static bool rm_trigger_file(char *path, const char *db,
static bool rm_trigname_file(char *path, const char *db,
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));
}
@@ -628,7 +629,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
LEX_STRING file;
file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name,
- triggers_file_ext);
+ triggers_file_ext, 0);
file.str= file_buff;
return sql_create_definition_file(NULL, &file, &triggers_file_type,
(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");
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;
// 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,
trig->m_db.str, trig->m_name.str,
- trigname_file_ext);
+ trigname_file_ext, 0);
path.str= path_buff;
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,
db_name, trigger->str,
- trigname_file_ext);
+ trigname_file_ext, 0);
trigname_file.str= trigname_buff;
trigname.trigger_table= *new_table_name;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 201725301d6..9dd79458c66 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -662,11 +662,11 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
/* print file name */
dir.length= build_table_filename(dir_buff, sizeof(dir_buff),
- view->db, "", "");
+ view->db, "", "", 0);
dir.str= dir_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;
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;
frm_type_enum type= FRMTYPE_ERROR;
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));
if (access(path, F_OK) ||
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b8d68a91afc..1d1bf85f665 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9320,7 +9320,6 @@ user:
keyword:
keyword_sp {}
| ASCII_SYM {}
- | AUTHORS_SYM {}
| BACKUP_SYM {}
| BEGIN_SYM {}
| BYTE_SYM {}
@@ -9378,6 +9377,7 @@ keyword_sp:
| ALGORITHM_SYM {}
| ANY_SYM {}
| AT_SYM {}
+ | AUTHORS_SYM {}
| AUTO_INC {}
| AUTOEXTEND_SIZE_SYM {}
| AVG_ROW_LENGTH {}
@@ -9403,6 +9403,7 @@ keyword_sp:
| COMPRESSED_SYM {}
| CONCURRENT {}
| CONSISTENT_SYM {}
+ | CONTRIBUTORS_SYM {}
| CUBE_SYM {}
| DATA_SYM {}
| DATAFILE_SYM {}
diff --git a/sql/table.cc b/sql/table.cc
index 21dbcccedd7..ce6dbadefc7 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -68,7 +68,7 @@ static byte *get_field_name(Field **buff, uint *length,
char *fn_rext(char *name)
{
char *res= strrchr(name, '.');
- if (res && !strcmp(res, ".frm"))
+ if (res && !strcmp(res, reg_ext))
return res;
return name + strlen(name);
}
@@ -95,10 +95,13 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
TABLE_SHARE *share;
char path[FN_REFLEN];
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,
table_list->db,
- table_list->table_name, "");
+ table_list->table_name, "", 0);
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
if ((share= (TABLE_SHARE*) alloc_root(&mem_root,
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_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)
{
DBUG_ENTER("init_tmp_table_share");
+ DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name));
bzero((char*) share, sizeof(*share));
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];
MEM_ROOT **root_ptr, *old_root;
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_given= 0;
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 602e46f0998..5f4a882f4a8 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -3419,8 +3419,8 @@ row_is_mysql_tmp_table_name(
const char* name) /* in: table name in the form
'database/tablename' */
{
- /* return(strstr(name, "/#sql") != NULL); */
- return(strstr(name, "/@0023sql") != NULL);
+ return(strstr(name, "/#sql") != NULL);
+ /* return(strstr(name, "/@0023sql") != NULL); */
}
/********************************************************************
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index 0487500ad33..8d45333137e 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -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 flag;
+ int block_of_record;
uint b_type,left_length;
byte *to;
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(left_length);
file=info->dfile;
- block_info.next_filepos=filepos; /* for easyer loop */
- flag=block_info.second_read=0;
+ block_of_record= 0; /* First block of record is numbered as zero. */
+ block_info.second_read= 0;
do
{
+ /* A corrupted table can have wrong pointers. (Bug# 19835) */
+ if (filepos == HA_OFFSET_ERROR)
+ goto panic;
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))
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;
- if ((b_type=_mi_get_block_info(&block_info,file,
- block_info.next_filepos))
+ if ((b_type= _mi_get_block_info(&block_info, file, filepos))
& (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_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;
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)
goto panic;
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)
goto panic; /* Wrong linked record */
- if (info->s->file_read(info,(byte*) to,block_info.data_len,block_info.filepos,
- MYF(MY_NABP)))
- goto panic;
- left_length-=block_info.data_len;
- to+=block_info.data_len;
+ /* copy information that is already read */
+ {
+ 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;
+ left_length-=block_info.data_len;
+ to+=block_info.data_len;
+ }
+ filepos= block_info.next_filepos;
} while (left_length);
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,
register my_off_t filepos,
my_bool skip_deleted_blocks)
{
- int flag,info_read,save_errno;
+ int block_of_record, info_read, save_errno;
uint left_len,b_type;
byte *to;
MI_BLOCK_INFO block_info;
@@ -1550,7 +1641,8 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
else
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;
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,
sizeof(block_info.header),
- (!flag && skip_deleted_blocks ? READING_NEXT : 0) |
- READING_HEADER))
+ (!block_of_record && skip_deleted_blocks ?
+ READING_NEXT : 0) | READING_HEADER))
goto panic;
b_type=_mi_get_block_info(&block_info,-1,filepos);
}
else
{
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))
DBUG_RETURN(my_errno);
info->rec_cache.seek_not_done=1;
@@ -1606,7 +1698,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
}
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)
goto panic;
@@ -1639,7 +1731,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
left_len-=tmp_length;
to+=tmp_length;
filepos+=tmp_length;
- }
+ }
}
/* read rest of record from file */
if (block_info.data_len)
@@ -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,
block_info.data_len,
- (!flag && skip_deleted_blocks) ? READING_NEXT :0))
+ (!block_of_record && skip_deleted_blocks) ?
+ READING_NEXT : 0))
goto panic;
}
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))); */
if (my_read(info->dfile,(byte*) to,block_info.data_len,MYF(MY_NABP)))
{
@@ -1662,10 +1760,14 @@ 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;
- skip_deleted_blocks=0;
+ info->nextpos= block_info.filepos + block_info.block_len;
+ skip_deleted_blocks= 0;
}
left_len-=block_info.data_len;
to+=block_info.data_len;
@@ -1697,6 +1799,11 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
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)));
if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) !=
sizeof(info->header))