summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-04-09 15:50:30 +0200
committerSergei Golubchik <sergii@pisem.net>2013-04-09 15:50:30 +0200
commitcdc01e29d3a9f6d98aaa482363af81003485e256 (patch)
tree20c8ce171e2666e720ac5977561997038fe3c2f2 /sql
parent15c936e4b3d151346c027bd4b51b44c826b095b6 (diff)
downloadmariadb-git-cdc01e29d3a9f6d98aaa482363af81003485e256.tar.gz
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
Diffstat (limited to 'sql')
-rw-r--r--sql/datadict.cc82
-rw-r--r--sql/datadict.h19
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_rename.cc93
-rw-r--r--sql/sql_show.cc31
-rw-r--r--sql/sql_table.cc8
-rw-r--r--sql/sql_truncate.cc22
-rw-r--r--sql/sql_view.cc22
-rw-r--r--sql/table.cc20
10 files changed, 105 insertions, 201 deletions
diff --git a/sql/datadict.cc b/sql/datadict.cc
index 15419c4f577..55ffd8eaee3 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -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.
diff --git a/sql/datadict.h b/sql/datadict.h
index 9c625e6434c..dd80942daca 100644
--- a/sql/datadict.h
+++ b/sql/datadict.h
@@ -28,14 +28,21 @@ enum frm_type_enum
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);
-bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name,
- handlerton **table_type);
-bool dd_check_storage_engine_flag(THD *thd,
- const char *db, const char *table_name,
- uint32 flag,
- bool *yes_no);
+static inline bool dd_frm_is_view(THD *thd, char *path)
+{
+ enum legacy_db_type not_used;
+ return dd_frm_type(thd, path, &not_used) == FRMTYPE_VIEW;
+}
+
bool dd_recreate_table(THD *thd, const char *db, const char *table_name,
const char *path = NULL);
diff --git a/sql/handler.cc b/sql/handler.cc
index b8ad8678b87..57282102a1a 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -386,7 +386,6 @@ static int ha_finish_errors(void)
static volatile int32 need_full_discover_for_existence= 0;
static volatile int32 engines_with_discover_table_names= 0;
-
static int full_discover_for_existence(handlerton *, const char *, const char *)
{ return 1; }
@@ -4373,8 +4372,7 @@ public:
*cond_hdl= NULL;
if (sql_errno == ER_NO_SUCH_TABLE ||
sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE ||
- sql_errno == ER_WRONG_OBJECT ||
- sql_errno == ER_OPTION_PREVENTS_STATEMENT) // partition_disabled.test
+ sql_errno == ER_WRONG_OBJECT)
{
m_handled_errors++;
return TRUE;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d93c412dd60..c4e510fd451 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -55,7 +55,7 @@
#include <hash.h>
#include "rpl_filter.h"
#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
#ifdef __WIN__
#include <io.h>
@@ -2774,7 +2774,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
MDL_SHARED))
{
char path[FN_REFLEN + 1];
- enum legacy_db_type not_used;
build_table_filename(path, sizeof(path) - 1,
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
should hold shared metadata lock on it).
*/
- if (dd_frm_type(thd, path, &not_used) == FRMTYPE_VIEW)
+ if (dd_frm_is_view(thd, path))
{
if (!tdc_open_view(thd, table_list, alias, key, key_length,
mem_root, 0))
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index cf9810db445..2c75de6e8a6 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -29,7 +29,6 @@
#include "sql_base.h" // tdc_remove_table, lock_table_names,
#include "sql_handler.h" // mysql_ha_rm_tables
#include "sql_statistics.h"
-#include "datadict.h"
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
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)
{
int rc= 1;
- char name[FN_REFLEN + 1];
+ handlerton *hton;
+ bool new_exists, old_exists;
const char *new_alias, *old_alias;
- frm_type_enum frm_type;
- enum legacy_db_type table_type;
-
DBUG_ENTER("do_rename");
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);
- build_table_filename(name, sizeof(name) - 1,
- new_db, new_alias, reg_ext, 0);
- if (!access(name,F_OK))
+ new_exists= ha_table_exists(thd, new_db, new_alias);
+
+ if (new_exists)
{
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);
- switch (frm_type)
+ old_exists= ha_table_exists(thd, ren_table->db, old_alias, &hton);
+
+ 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,
- table_type),
- ren_table->db, old_alias,
- new_db, new_alias, 0)))
+ LEX_STRING db_name= { ren_table->db, ren_table->db_length };
+ LEX_STRING table_name= { ren_table->table_name,
+ ren_table->table_name_length };
+ 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,
- ren_table->table_name_length };
- 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)))
- {
- /*
- 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);
- }
+ /*
+ 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(hton, new_db, new_alias,
+ ren_table->db, old_alias, 0);
}
}
- break;
- case FRMTYPE_VIEW:
+ }
+ else
+ {
/*
change of schema is not allowed
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 &&
strcmp(ren_table->db, new_db))
- my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
- new_db);
+ my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db);
else
rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
- break;
- default:
- DBUG_ASSERT(0); // should never happen
- case FRMTYPE_ERROR:
- my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
- break;
+ }
+ }
+ else
+ {
+ my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
}
if (rc && !skip_error)
DBUG_RETURN(1);
DBUG_RETURN(0);
-
}
/*
Rename all tables in list; Return pointer to wrong entry if something goes
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 5c92d7db8f2..a0fa9807b29 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -57,7 +57,6 @@
#include <my_dir.h>
#include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH
#include "debug_sync.h"
-#include "datadict.h" // dd_frm_type()
#include "keycaches.h"
#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)
{
- enum legacy_db_type not_used;
- char path[FN_REFLEN + 1];
- (void) build_table_filename(path, sizeof(path) - 1, db_name->str,
- table_name->str, reg_ext, 0);
- switch (dd_frm_type(thd, path, &not_used)) {
- case FRMTYPE_ERROR:
- table->field[3]->store(STRING_WITH_LEN("ERROR"),
- system_charset_info);
- 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);
+ CHARSET_INFO *cs= system_charset_info;
+ handlerton *hton;
+ if (ha_table_exists(thd, db_name->str, table_name->str, &hton))
+ {
+ if (hton == view_pseudo_hton)
+ table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
+ else
+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
}
+ else
+ table->field[3]->store(STRING_WITH_LEN("ERROR"), cs);
+
if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
{
thd->clear_error();
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6fc5d9c0fc1..7d5f2d870ec 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -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))
{
error=my_errno;
- /* Restore old file name */
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;
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 0e97de5a6aa..92c4d150433 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -341,9 +341,27 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref,
MYSQL_OPEN_SKIP_TEMPORARY))
DBUG_RETURN(TRUE);
- if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name,
- HTON_CAN_RECREATE, hton_can_recreate))
+ handlerton *hton;
+ 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);
+ }
+
+ 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;
}
/*
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 7c033f74fb2..0a84dd996ce 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -33,7 +33,7 @@
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
-#include "datadict.h" // dd_frm_type()
+#include "datadict.h" // dd_frm_is_view()
#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;
char *wrong_object_db= NULL, *wrong_object_name= NULL;
bool error= FALSE;
- enum legacy_db_type not_used;
bool some_views_deleted= FALSE;
bool something_wrong= FALSE;
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)
{
- frm_type_enum type= FRMTYPE_ERROR;
+ bool not_exist;
build_table_filename(path, sizeof(path) - 1,
view->db, view->table_name, reg_ext, 0);
- if (access(path, F_OK) ||
- FRMTYPE_VIEW != (type= dd_frm_type(thd, path, &not_used)))
+ if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path))
{
char name[FN_REFLEN];
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);
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)
{
@@ -1689,12 +1693,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
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;
}
if (mysql_file_delete(key_file_frm, path, MYF(MY_WME)))
diff --git a/sql/table.cc b/sql/table.cc
index 647e8d3ee5a..0eaae05af77 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -573,24 +573,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
SYNOPSIS
@@ -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];
(void) strxmov(from_b,from,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)));
}