remove dd_frm_type(), dd_frm_storage_engine(), dd_check_storage_engine_flag()
from everywhere - now RENAME, SHOW FULL TABLES, and TRUNCATE work with discovery. improve error messages in truncate
This commit is contained in:
parent
15c936e4b3
commit
cdc01e29d3
@ -2850,7 +2850,7 @@ SET DEBUG_SYNC= 'now SIGNAL blocked';
|
|||||||
# Reaping: DROP DATABASE db1
|
# Reaping: DROP DATABASE db1
|
||||||
# Connection con2
|
# Connection con2
|
||||||
# Reaping: RENAME TABLE db1.t1 TO test.t1
|
# Reaping: RENAME TABLE db1.t1 TO test.t1
|
||||||
Got one of the listed errors
|
ERROR 42S02: Table 'db1.t1' doesn't exist
|
||||||
# Connection default
|
# Connection default
|
||||||
CREATE DATABASE db1;
|
CREATE DATABASE db1;
|
||||||
CREATE TABLE test.t2 (a INT);
|
CREATE TABLE test.t2 (a INT);
|
||||||
|
@ -533,7 +533,7 @@ drop table t2;
|
|||||||
prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ;
|
prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ;
|
||||||
create table t5 (a int) ;
|
create table t5 (a int) ;
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
ERROR HY000: Can't find file: './test/t7' (errno: 2 "No such file or directory")
|
ERROR 42S02: Table 'test.t7' doesn't exist
|
||||||
create table t7 (a int) ;
|
create table t7 (a int) ;
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
|
@ -14,20 +14,20 @@ select * from t1;
|
|||||||
1 table 1
|
1 table 1
|
||||||
1 table 1
|
1 table 1
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
Got one of the listed errors
|
ERROR 42S01: Table 't2' already exists
|
||||||
rename table t1 to t1;
|
rename table t1 to t1;
|
||||||
Got one of the listed errors
|
ERROR 42S01: Table 't1' already exists
|
||||||
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
|
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
|
||||||
Got one of the listed errors
|
ERROR 42S01: Table 't2' already exists
|
||||||
show tables like "t_";
|
show tables like "t_";
|
||||||
Tables_in_test (t_)
|
Tables_in_test (t_)
|
||||||
t1
|
t1
|
||||||
t2
|
t2
|
||||||
t3
|
t3
|
||||||
rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
|
rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
|
||||||
Got one of the listed errors
|
ERROR 42S01: Table 't1' already exists
|
||||||
rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
|
rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
|
||||||
Got one of the listed errors
|
ERROR 42S02: Table 'test.t5' doesn't exist
|
||||||
select * from t1;
|
select * from t1;
|
||||||
1 table 1
|
1 table 1
|
||||||
1 table 1
|
1 table 1
|
||||||
|
13
mysql-test/r/truncate_badse.result
Normal file
13
mysql-test/r/truncate_badse.result
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
install plugin example soname 'ha_example';
|
||||||
|
create table t1 (a int) engine=example;
|
||||||
|
select 1;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
uninstall plugin example;
|
||||||
|
flush tables;
|
||||||
|
select count(*) from information_schema.plugins where plugin_name='example';
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
truncate table t1;
|
||||||
|
ERROR 42000: Unknown storage engine 'EXAMPLE'
|
||||||
|
drop table t1;
|
@ -12749,16 +12749,6 @@ SELECT * FROM t1;
|
|||||||
col1 col2
|
col1 col2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# BUG#48757 - missing .ARZ file causes server crash
|
|
||||||
#
|
|
||||||
CREATE TABLE t1(a INT) ENGINE=ARCHIVE;
|
|
||||||
FLUSH TABLE t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
ERROR HY000: Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory")
|
|
||||||
DROP TABLE t1;
|
|
||||||
Warnings:
|
|
||||||
Warning 2 Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory")
|
|
||||||
#
|
|
||||||
# Ensure that TRUNCATE fails for non-empty archive tables.
|
# Ensure that TRUNCATE fails for non-empty archive tables.
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a INT) ENGINE=ARCHIVE;
|
CREATE TABLE t1 (a INT) ENGINE=ARCHIVE;
|
||||||
|
@ -1668,16 +1668,6 @@ SELECT * FROM t1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
remove_file $MYSQLD_DATADIR/test/t1.ARM;
|
remove_file $MYSQLD_DATADIR/test/t1.ARM;
|
||||||
|
|
||||||
--echo #
|
|
||||||
--echo # BUG#48757 - missing .ARZ file causes server crash
|
|
||||||
--echo #
|
|
||||||
CREATE TABLE t1(a INT) ENGINE=ARCHIVE;
|
|
||||||
FLUSH TABLE t1;
|
|
||||||
--remove_file $MYSQLD_DATADIR/test/t1.ARZ
|
|
||||||
--error ER_FILE_NOT_FOUND
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Ensure that TRUNCATE fails for non-empty archive tables.
|
--echo # Ensure that TRUNCATE fails for non-empty archive tables.
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -18,19 +18,50 @@ a
|
|||||||
1
|
1
|
||||||
2
|
2
|
||||||
#
|
#
|
||||||
# list tables
|
# show tables
|
||||||
#
|
#
|
||||||
create table t0 (a int) engine=archive;
|
create table t2 (a int) engine=archive;
|
||||||
flush tables;
|
flush tables;
|
||||||
show tables;
|
show tables;
|
||||||
Tables_in_test
|
Tables_in_test
|
||||||
t0
|
|
||||||
t1
|
t1
|
||||||
|
t2
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
#
|
#
|
||||||
|
# show full tables
|
||||||
|
#
|
||||||
|
flush tables;
|
||||||
|
show full tables;
|
||||||
|
Tables_in_test Table_type
|
||||||
|
t1 BASE TABLE
|
||||||
|
t2 BASE TABLE
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
#
|
||||||
|
# discover on truncate
|
||||||
|
#
|
||||||
|
flush tables;
|
||||||
|
truncate table t1;
|
||||||
|
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||||
|
show tables;
|
||||||
|
Tables_in_test
|
||||||
|
t1
|
||||||
|
t2
|
||||||
|
#
|
||||||
|
# discover on rename
|
||||||
|
#
|
||||||
|
flush tables;
|
||||||
|
rename table t2 to t0;
|
||||||
|
show tables;
|
||||||
|
Tables_in_test
|
||||||
|
t0
|
||||||
|
t1
|
||||||
|
#
|
||||||
# discover on drop
|
# discover on drop
|
||||||
#
|
#
|
||||||
flush tables;
|
flush tables;
|
||||||
|
@ -15,14 +15,39 @@ insert t1 values (2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # list tables
|
--echo # show tables
|
||||||
--echo #
|
--echo #
|
||||||
create table t0 (a int) engine=archive;
|
create table t2 (a int) engine=archive;
|
||||||
remove_file $mysqld_datadir/test/t1.frm;
|
remove_file $mysqld_datadir/test/t1.frm;
|
||||||
flush tables;
|
flush tables;
|
||||||
show tables;
|
show tables;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # show full tables
|
||||||
|
--echo #
|
||||||
|
remove_file $mysqld_datadir/test/t1.frm;
|
||||||
|
flush tables;
|
||||||
|
show full tables;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # discover on truncate
|
||||||
|
--echo #
|
||||||
|
remove_file $mysqld_datadir/test/t1.frm;
|
||||||
|
flush tables;
|
||||||
|
--error ER_ILLEGAL_HA
|
||||||
|
truncate table t1;
|
||||||
|
show tables;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # discover on rename
|
||||||
|
--echo #
|
||||||
|
remove_file $mysqld_datadir/test/t2.frm;
|
||||||
|
flush tables;
|
||||||
|
rename table t2 to t0;
|
||||||
|
show tables;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # discover on drop
|
--echo # discover on drop
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -4382,7 +4382,7 @@ connection default;
|
|||||||
--echo # Connection con2
|
--echo # Connection con2
|
||||||
connection con2;
|
connection con2;
|
||||||
--echo # Reaping: RENAME TABLE db1.t1 TO test.t1
|
--echo # Reaping: RENAME TABLE db1.t1 TO test.t1
|
||||||
--error ER_FILE_NOT_FOUND, ER_FILE_NOT_FOUND
|
--error ER_NO_SUCH_TABLE
|
||||||
--reap
|
--reap
|
||||||
|
|
||||||
--echo # Connection default
|
--echo # Connection default
|
||||||
|
@ -9,16 +9,21 @@ drop table if exists t1,t2;
|
|||||||
create table t1 (a int) engine=myisam;
|
create table t1 (a int) engine=myisam;
|
||||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||||
--remove_file $MYSQLD_DATADIR/test/t1.MYI
|
--remove_file $MYSQLD_DATADIR/test/t1.MYI
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
create table t1 (a int) engine=myisam;
|
create table t1 (a int) engine=myisam;
|
||||||
--remove_file $MYSQLD_DATADIR/test/t1.MYI
|
--remove_file $MYSQLD_DATADIR/test/t1.MYI
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
--error ER_FILE_NOT_FOUND
|
--error ER_FILE_NOT_FOUND
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int) engine=myisam;
|
create table t1 (a int) engine=myisam;
|
||||||
--remove_file $MYSQLD_DATADIR/test/t1.MYD
|
--remove_file $MYSQLD_DATADIR/test/t1.MYD
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
--error 29
|
--error 29
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
drop table t1;
|
drop table t1;
|
||||||
--error ER_BAD_TABLE_ERROR
|
--error ER_BAD_TABLE_ERROR
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -582,10 +582,7 @@ drop table t2;
|
|||||||
# cases derived from client_test.c: test_rename()
|
# cases derived from client_test.c: test_rename()
|
||||||
prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ;
|
prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ;
|
||||||
create table t5 (a int) ;
|
create table t5 (a int) ;
|
||||||
# rename must fail, t7 does not exist
|
--error ER_NO_SUCH_TABLE
|
||||||
# Clean up the filename here because embedded server reports whole path
|
|
||||||
--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' t7.frm t7
|
|
||||||
--error ER_FILE_NOT_FOUND
|
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
create table t7 (a int) ;
|
create table t7 (a int) ;
|
||||||
# rename, t5 -> t6 and t7 -> t8
|
# rename, t5 -> t6 and t7 -> t8
|
||||||
|
@ -21,16 +21,16 @@ rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
|
|
||||||
# The following should give errors
|
# The following should give errors
|
||||||
--error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
--error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
rename table t1 to t1;
|
rename table t1 to t1;
|
||||||
--error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
|
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
|
||||||
show tables like "t_";
|
show tables like "t_";
|
||||||
--error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
|
rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
|
||||||
--error ER_FILE_NOT_FOUND,ER_FILE_NOT_FOUND
|
--error ER_NO_SUCH_TABLE
|
||||||
rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
|
rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
|
||||||
|
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
15
mysql-test/t/truncate_badse.test
Normal file
15
mysql-test/t/truncate_badse.test
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# test what TRUNCATE TABLE does, if the table was created in
|
||||||
|
# now-unknown storage engine.
|
||||||
|
#
|
||||||
|
--source include/have_example_plugin.inc
|
||||||
|
install plugin example soname 'ha_example';
|
||||||
|
create table t1 (a int) engine=example;
|
||||||
|
select 1;
|
||||||
|
uninstall plugin example;
|
||||||
|
flush tables;
|
||||||
|
select count(*) from information_schema.plugins where plugin_name='example';
|
||||||
|
--error ER_UNKNOWN_STORAGE_ENGINE
|
||||||
|
truncate table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
@ -70,88 +70,6 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Given a table name, check type of .frm and legacy table type.
|
|
||||||
|
|
||||||
@param[in] thd The current session.
|
|
||||||
@param[in] db Table schema.
|
|
||||||
@param[in] table_name Table database.
|
|
||||||
@param[out] table_type handlerton of the table if FRMTYPE_TABLE,
|
|
||||||
otherwise undefined.
|
|
||||||
|
|
||||||
@return FALSE if FRMTYPE_TABLE and storage engine found. TRUE otherwise.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name,
|
|
||||||
handlerton **table_type)
|
|
||||||
{
|
|
||||||
char path[FN_REFLEN + 1];
|
|
||||||
enum legacy_db_type db_type;
|
|
||||||
LEX_STRING db_name = {(char *) db, strlen(db)};
|
|
||||||
|
|
||||||
/* There should be at least some lock on the table. */
|
|
||||||
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db,
|
|
||||||
table_name, MDL_SHARED));
|
|
||||||
|
|
||||||
if (check_db_name(&db_name))
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_table_name(table_name, strlen(table_name), FALSE))
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) build_table_filename(path, sizeof(path) - 1, db,
|
|
||||||
table_name, reg_ext, 0);
|
|
||||||
|
|
||||||
dd_frm_type(thd, path, &db_type);
|
|
||||||
|
|
||||||
/* Type is unknown if the object is not found or is not a table. */
|
|
||||||
if (db_type == DB_TYPE_UNKNOWN ||
|
|
||||||
!(*table_type= ha_resolve_by_legacy_type(thd, db_type)))
|
|
||||||
{
|
|
||||||
my_error(ER_NO_SUCH_TABLE, MYF(0), db, table_name);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Given a table name, check if the storage engine for the
|
|
||||||
table referred by this name supports an option 'flag'.
|
|
||||||
Return an error if the table does not exist or is not a
|
|
||||||
base table.
|
|
||||||
|
|
||||||
@pre Any metadata lock on the table.
|
|
||||||
|
|
||||||
@param[in] thd The current session.
|
|
||||||
@param[in] db Table schema.
|
|
||||||
@param[in] table_name Table database.
|
|
||||||
@param[in] flag The option to check.
|
|
||||||
@param[out] yes_no The result. Undefined if error.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool dd_check_storage_engine_flag(THD *thd,
|
|
||||||
const char *db, const char *table_name,
|
|
||||||
uint32 flag, bool *yes_no)
|
|
||||||
{
|
|
||||||
handlerton *table_type;
|
|
||||||
|
|
||||||
if (dd_frm_storage_engine(thd, db, table_name, &table_type))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
*yes_no= ha_check_storage_engine_flag(table_type, flag);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Regenerate a metadata locked table.
|
Regenerate a metadata locked table.
|
||||||
|
|
||||||
|
@ -28,14 +28,21 @@ enum frm_type_enum
|
|||||||
FRMTYPE_VIEW
|
FRMTYPE_VIEW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Take extra care when using dd_frm_type() - it only checks the .frm file,
|
||||||
|
and it won't work for any engine that supports discovery.
|
||||||
|
|
||||||
|
Prefer to use ha_table_exists() instead.
|
||||||
|
To check whether it's an frm of a view, use dd_frm_is_view().
|
||||||
|
*/
|
||||||
frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt);
|
frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt);
|
||||||
|
|
||||||
bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name,
|
static inline bool dd_frm_is_view(THD *thd, char *path)
|
||||||
handlerton **table_type);
|
{
|
||||||
bool dd_check_storage_engine_flag(THD *thd,
|
enum legacy_db_type not_used;
|
||||||
const char *db, const char *table_name,
|
return dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW;
|
||||||
uint32 flag,
|
}
|
||||||
bool *yes_no);
|
|
||||||
bool dd_recreate_table(THD *thd, const char *db, const char *table_name,
|
bool dd_recreate_table(THD *thd, const char *db, const char *table_name,
|
||||||
const char *path = NULL);
|
const char *path = NULL);
|
||||||
|
|
||||||
|
@ -386,7 +386,6 @@ static int ha_finish_errors(void)
|
|||||||
static volatile int32 need_full_discover_for_existence= 0;
|
static volatile int32 need_full_discover_for_existence= 0;
|
||||||
static volatile int32 engines_with_discover_table_names= 0;
|
static volatile int32 engines_with_discover_table_names= 0;
|
||||||
|
|
||||||
|
|
||||||
static int full_discover_for_existence(handlerton *, const char *, const char *)
|
static int full_discover_for_existence(handlerton *, const char *, const char *)
|
||||||
{ return 1; }
|
{ return 1; }
|
||||||
|
|
||||||
@ -4373,8 +4372,7 @@ public:
|
|||||||
*cond_hdl= NULL;
|
*cond_hdl= NULL;
|
||||||
if (sql_errno == ER_NO_SUCH_TABLE ||
|
if (sql_errno == ER_NO_SUCH_TABLE ||
|
||||||
sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE ||
|
sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE ||
|
||||||
sql_errno == ER_WRONG_OBJECT ||
|
sql_errno == ER_WRONG_OBJECT)
|
||||||
sql_errno == ER_OPTION_PREVENTS_STATEMENT) // partition_disabled.test
|
|
||||||
{
|
{
|
||||||
m_handled_errors++;
|
m_handled_errors++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include "rpl_filter.h"
|
#include "rpl_filter.h"
|
||||||
#include "sql_table.h" // build_table_filename
|
#include "sql_table.h" // build_table_filename
|
||||||
#include "datadict.h" // dd_frm_type()
|
#include "datadict.h" // dd_frm_is_view()
|
||||||
#include "sql_hset.h" // Hash_set
|
#include "sql_hset.h" // Hash_set
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@ -2774,7 +2774,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
MDL_SHARED))
|
MDL_SHARED))
|
||||||
{
|
{
|
||||||
char path[FN_REFLEN + 1];
|
char path[FN_REFLEN + 1];
|
||||||
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, 0);
|
table_list->db, table_list->table_name, reg_ext, 0);
|
||||||
/*
|
/*
|
||||||
@ -2784,7 +2783,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
during prelocking process (in this case in theory we still
|
during prelocking process (in this case in theory we still
|
||||||
should hold shared metadata lock on it).
|
should hold shared metadata lock on it).
|
||||||
*/
|
*/
|
||||||
if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW)
|
if (dd_frm_is_view(thd, path))
|
||||||
{
|
{
|
||||||
if (!tdc_open_view(thd, table_list, alias, key, key_length,
|
if (!tdc_open_view(thd, table_list, alias, key, key_length,
|
||||||
mem_root, 0))
|
mem_root, 0))
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "sql_base.h" // tdc_remove_table, lock_table_names,
|
#include "sql_base.h" // tdc_remove_table, lock_table_names,
|
||||||
#include "sql_handler.h" // mysql_ha_rm_tables
|
#include "sql_handler.h" // mysql_ha_rm_tables
|
||||||
#include "sql_statistics.h"
|
#include "sql_statistics.h"
|
||||||
#include "datadict.h"
|
|
||||||
|
|
||||||
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
||||||
bool skip_error);
|
bool skip_error);
|
||||||
@ -241,11 +240,9 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
|
|||||||
char *new_table_alias, bool skip_error)
|
char *new_table_alias, bool skip_error)
|
||||||
{
|
{
|
||||||
int rc= 1;
|
int rc= 1;
|
||||||
char name[FN_REFLEN + 1];
|
handlerton *hton;
|
||||||
|
bool new_exists, old_exists;
|
||||||
const char *new_alias, *old_alias;
|
const char *new_alias, *old_alias;
|
||||||
frm_type_enum frm_type;
|
|
||||||
enum legacy_db_type table_type;
|
|
||||||
|
|
||||||
DBUG_ENTER("do_rename");
|
DBUG_ENTER("do_rename");
|
||||||
|
|
||||||
if (lower_case_table_names == 2)
|
if (lower_case_table_names == 2)
|
||||||
@ -260,53 +257,48 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
|
|||||||
}
|
}
|
||||||
DBUG_ASSERT(new_alias);
|
DBUG_ASSERT(new_alias);
|
||||||
|
|
||||||
build_table_filename(name, sizeof(name) - 1,
|
new_exists= ha_table_exists(thd, new_db, new_alias);
|
||||||
new_db, new_alias, reg_ext, 0);
|
|
||||||
if (!access(name,F_OK))
|
if (new_exists)
|
||||||
{
|
{
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||||
DBUG_RETURN(1); // This can't be skipped
|
DBUG_RETURN(1); // This can't be skipped
|
||||||
}
|
}
|
||||||
build_table_filename(name, sizeof(name) - 1,
|
|
||||||
ren_table->db, old_alias, reg_ext, 0);
|
|
||||||
|
|
||||||
frm_type= dd_frm_type(thd, name, &table_type);
|
old_exists= ha_table_exists(thd, ren_table->db, old_alias, &hton);
|
||||||
switch (frm_type)
|
|
||||||
|
if (old_exists)
|
||||||
{
|
{
|
||||||
case FRMTYPE_TABLE:
|
if (hton != view_pseudo_hton)
|
||||||
|
{
|
||||||
|
if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias,
|
||||||
|
new_db, new_alias, 0)))
|
||||||
{
|
{
|
||||||
if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
LEX_STRING db_name= { ren_table->db, ren_table->db_length };
|
||||||
table_type),
|
LEX_STRING table_name= { ren_table->table_name,
|
||||||
ren_table->db, old_alias,
|
ren_table->table_name_length };
|
||||||
new_db, new_alias, 0)))
|
LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) };
|
||||||
|
(void) rename_table_in_stat_tables(thd, &db_name, &table_name,
|
||||||
|
&db_name, &new_table);
|
||||||
|
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
|
||||||
|
old_alias,
|
||||||
|
ren_table->table_name,
|
||||||
|
new_db,
|
||||||
|
new_alias)))
|
||||||
{
|
{
|
||||||
LEX_STRING db_name= { ren_table->db, ren_table->db_length };
|
/*
|
||||||
LEX_STRING table_name= { ren_table->table_name,
|
We've succeeded in renaming table's .frm and in updating
|
||||||
ren_table->table_name_length };
|
corresponding handler data, but have failed to update table's
|
||||||
LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) };
|
triggers appropriately. So let us revert operations on .frm
|
||||||
(void) rename_table_in_stat_tables(thd, &db_name, &table_name,
|
and handler's data and report about failure to rename table.
|
||||||
&db_name, &new_table);
|
*/
|
||||||
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
|
(void) mysql_rename_table(hton, new_db, new_alias,
|
||||||
old_alias,
|
ren_table->db, old_alias, 0);
|
||||||
ren_table->table_name,
|
|
||||||
new_db,
|
|
||||||
new_alias)))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We've succeeded in renaming table's .frm and in updating
|
|
||||||
corresponding handler data, but have failed to update table's
|
|
||||||
triggers appropriately. So let us revert operations on .frm
|
|
||||||
and handler's data and report about failure to rename table.
|
|
||||||
*/
|
|
||||||
(void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
|
||||||
table_type),
|
|
||||||
new_db, new_alias,
|
|
||||||
ren_table->db, old_alias, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case FRMTYPE_VIEW:
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
change of schema is not allowed
|
change of schema is not allowed
|
||||||
except of ALTER ...UPGRADE DATA DIRECTORY NAME command
|
except of ALTER ...UPGRADE DATA DIRECTORY NAME command
|
||||||
@ -314,22 +306,19 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
|
|||||||
*/
|
*/
|
||||||
if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE &&
|
if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE &&
|
||||||
strcmp(ren_table->db, new_db))
|
strcmp(ren_table->db, new_db))
|
||||||
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
|
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db);
|
||||||
new_db);
|
|
||||||
else
|
else
|
||||||
rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
|
rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
|
||||||
break;
|
}
|
||||||
default:
|
}
|
||||||
DBUG_ASSERT(0); // should never happen
|
else
|
||||||
case FRMTYPE_ERROR:
|
{
|
||||||
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (rc && !skip_error)
|
if (rc && !skip_error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Rename all tables in list; Return pointer to wrong entry if something goes
|
Rename all tables in list; Return pointer to wrong entry if something goes
|
||||||
|
@ -57,7 +57,6 @@
|
|||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
#include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH
|
#include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
#include "datadict.h" // dd_frm_type()
|
|
||||||
#include "keycaches.h"
|
#include "keycaches.h"
|
||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
@ -4072,26 +4071,18 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
else if (tables->table_open_method != SKIP_OPEN_TABLE)
|
else if (tables->table_open_method != SKIP_OPEN_TABLE)
|
||||||
{
|
{
|
||||||
enum legacy_db_type not_used;
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
char path[FN_REFLEN + 1];
|
handlerton *hton;
|
||||||
(void) build_table_filename(path, sizeof(path) - 1, db_name->str,
|
if (ha_table_exists(thd, db_name->str, table_name->str, &hton))
|
||||||
table_name->str, reg_ext, 0);
|
{
|
||||||
switch (dd_frm_type(thd, path, ¬_used)) {
|
if (hton == view_pseudo_hton)
|
||||||
case FRMTYPE_ERROR:
|
table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
|
||||||
table->field[3]->store(STRING_WITH_LEN("ERROR"),
|
else
|
||||||
system_charset_info);
|
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
|
||||||
break;
|
|
||||||
case FRMTYPE_TABLE:
|
|
||||||
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
|
|
||||||
system_charset_info);
|
|
||||||
break;
|
|
||||||
case FRMTYPE_VIEW:
|
|
||||||
table->field[3]->store(STRING_WITH_LEN("VIEW"),
|
|
||||||
system_charset_info);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
table->field[3]->store(STRING_WITH_LEN("ERROR"), cs);
|
||||||
|
|
||||||
if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
|
if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
|
||||||
{
|
{
|
||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
|
@ -4637,9 +4637,13 @@ mysql_rename_table(handlerton *base, const char *old_db,
|
|||||||
if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
|
if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
|
||||||
{
|
{
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
/* Restore old file name */
|
|
||||||
if (file)
|
if (file)
|
||||||
file->ha_rename_table(to_base, from_base);
|
{
|
||||||
|
if (error == ENOENT)
|
||||||
|
error= 0; // this is ok if file->ha_rename_table() succeeded
|
||||||
|
else
|
||||||
|
file->ha_rename_table(to_base, from_base); // Restore old file name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete file;
|
delete file;
|
||||||
|
@ -341,9 +341,27 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref,
|
|||||||
MYSQL_OPEN_SKIP_TEMPORARY))
|
MYSQL_OPEN_SKIP_TEMPORARY))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name,
|
handlerton *hton;
|
||||||
HTON_CAN_RECREATE, hton_can_recreate))
|
if (!ha_table_exists(thd, table_ref->db, table_ref->table_name, &hton) ||
|
||||||
|
hton == view_pseudo_hton)
|
||||||
|
{
|
||||||
|
my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db, table_ref->table_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hton)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The table exists, but its storage engine is unknown, perhaps not
|
||||||
|
loaded at the moment. We need to open and parse the frm to know the
|
||||||
|
storage engine in question, so let's proceed with the truncation and
|
||||||
|
try to open the table. This will produce the correct error message
|
||||||
|
about unknown engine.
|
||||||
|
*/
|
||||||
|
*hton_can_recreate= false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*hton_can_recreate= hton->flags & HTON_CAN_RECREATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
#include "sp_cache.h"
|
#include "sp_cache.h"
|
||||||
#include "datadict.h" // dd_frm_type()
|
#include "datadict.h" // dd_frm_is_view()
|
||||||
|
|
||||||
#define MD5_BUFF_LENGTH 33
|
#define MD5_BUFF_LENGTH 33
|
||||||
|
|
||||||
@ -1642,7 +1642,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
String non_existant_views;
|
String non_existant_views;
|
||||||
char *wrong_object_db= NULL, *wrong_object_name= NULL;
|
char *wrong_object_db= NULL, *wrong_object_name= NULL;
|
||||||
bool error= FALSE;
|
bool error= FALSE;
|
||||||
enum legacy_db_type not_used;
|
|
||||||
bool some_views_deleted= FALSE;
|
bool some_views_deleted= FALSE;
|
||||||
bool something_wrong= FALSE;
|
bool something_wrong= FALSE;
|
||||||
DBUG_ENTER("mysql_drop_view");
|
DBUG_ENTER("mysql_drop_view");
|
||||||
@ -1665,12 +1664,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
|
|
||||||
for (view= views; view; view= view->next_local)
|
for (view= views; view; view= view->next_local)
|
||||||
{
|
{
|
||||||
frm_type_enum type= FRMTYPE_ERROR;
|
bool not_exist;
|
||||||
build_table_filename(path, sizeof(path) - 1,
|
build_table_filename(path, sizeof(path) - 1,
|
||||||
view->db, view->table_name, reg_ext, 0);
|
view->db, view->table_name, reg_ext, 0);
|
||||||
|
|
||||||
if (access(path, F_OK) ||
|
if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path))
|
||||||
FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used)))
|
|
||||||
{
|
{
|
||||||
char name[FN_REFLEN];
|
char name[FN_REFLEN];
|
||||||
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
|
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
|
||||||
@ -1681,7 +1679,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
name);
|
name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type == FRMTYPE_TABLE)
|
if (not_exist)
|
||||||
|
{
|
||||||
|
if (non_existant_views.length())
|
||||||
|
non_existant_views.append(',');
|
||||||
|
non_existant_views.append(String(view->table_name,system_charset_info));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!wrong_object_name)
|
if (!wrong_object_name)
|
||||||
{
|
{
|
||||||
@ -1689,12 +1693,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||||||
wrong_object_name= view->table_name;
|
wrong_object_name= view->table_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (non_existant_views.length())
|
|
||||||
non_existant_views.append(',');
|
|
||||||
non_existant_views.append(String(view->table_name,system_charset_info));
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mysql_file_delete(key_file_frm, path, MYF(MY_WME)))
|
if (mysql_file_delete(key_file_frm, path, MYF(MY_WME)))
|
||||||
|
20
sql/table.cc
20
sql/table.cc
@ -572,24 +572,6 @@ inline bool is_system_table_name(const char *name, uint length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
We don't try to open 5.0 unencoded name, if
|
|
||||||
- non-encoded name contains '@' signs,
|
|
||||||
because '@' can be misinterpreted.
|
|
||||||
It is not clear if '@' is escape character in 5.1,
|
|
||||||
or a normal character in 5.0.
|
|
||||||
|
|
||||||
- non-encoded db or table name contain "#mysql50#" prefix.
|
|
||||||
This kind of tables must have been opened only by the
|
|
||||||
mysql_file_open() above.
|
|
||||||
*/
|
|
||||||
static bool has_disabled_path_chars(const char *str)
|
|
||||||
{
|
|
||||||
return strpbrk(str, "/\\~@.") != 0 ||
|
|
||||||
strncmp(str, STRING_WITH_LEN(MYSQL50_TABLE_NAME_PREFIX)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read table definition from a binary / text based .frm file
|
Read table definition from a binary / text based .frm file
|
||||||
|
|
||||||
@ -3176,7 +3158,7 @@ rename_file_ext(const char * from,const char * to,const char * ext)
|
|||||||
char from_b[FN_REFLEN],to_b[FN_REFLEN];
|
char from_b[FN_REFLEN],to_b[FN_REFLEN];
|
||||||
(void) strxmov(from_b,from,ext,NullS);
|
(void) strxmov(from_b,from,ext,NullS);
|
||||||
(void) strxmov(to_b,to,ext,NullS);
|
(void) strxmov(to_b,to,ext,NullS);
|
||||||
return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(MY_WME)));
|
return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user