summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorgopal.shankar@oracle.com <>2012-04-11 15:53:17 +0530
committergopal.shankar@oracle.com <>2012-04-11 15:53:17 +0530
commit796fad1424dabed0d60cdbf353c8ce88c4066bb8 (patch)
tree5351d27e52955b31c1d107afd9480b37224c2b8d /sql/sql_table.cc
parentd3782bffbdd2c5cdda3d6760acfaebfe9549aeef (diff)
downloadmariadb-git-796fad1424dabed0d60cdbf353c8ce88c4066bb8.tar.gz
Bug#11815557 60269: MYSQL SHOULD REJECT ATTEMPTS TO CREATE SYSTEM
TABLES IN INCORRECT ENGINE PROBLEM: CREATE/ALTER TABLE currently can move system tables like mysql.db, user, host etc, to engines other than MyISAM. This is not completely supported as of now, by mysqld. When some of system tables like plugin, servers, event, func, *_priv, time_zone* are moved to innodb, mysqld restart crashes. Currently system tables can be moved to BLACKHOLE also!!!. ANALYSIS: The problem is that there is no check before creating or moving a system table to some particular engine. System tables are suppose to be residing in MyISAM. We can think of restricting system tables to exist only in MyISAM. But, there could be future needs of these system tables to be part of other engines by design. For eg, NDB cluster expects some tables to be on innodb or ndb engine. This calls for a solution, by which system tables can be supported by any desired engine, with minimal effort. FIX: The solution provides a handlerton interface using which, mysqld server can query particular storage engine handlerton for system tables that it supports. This way each storage engine layer can define their own system database and system tables. The check_engine() function uses the new handlerton function ha_check_if_supported_system_table() to check if db.tablename provided in the DDL is supported by the SE. Note: This fix has modified a test in help.test, which was moving mysql.help_* to innodb. The primary intention of the test was not to move them between engines.
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc49
1 files changed, 41 insertions, 8 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b9ec70f6560..0f4bac47cab 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -69,7 +69,10 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
bool error_if_not_empty);
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
-static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
+static bool check_engine(THD *thd, const char *db_name,
+ const char *table_name,
+ HA_CREATE_INFO *create_info);
+
static int
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info,
@@ -3940,7 +3943,7 @@ bool mysql_create_table_no_lock(THD *thd,
MYF(0));
DBUG_RETURN(TRUE);
}
- if (check_engine(thd, table_name, create_info))
+ if (check_engine(thd, db, table_name, create_info))
DBUG_RETURN(TRUE);
set_table_default_charset(thd, create_info, (char*) db);
@@ -5923,7 +5926,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
create_info->db_type= old_db_type;
}
- if (check_engine(thd, new_name, create_info))
+ if (check_engine(thd, new_db, new_name, create_info))
goto err;
new_db_type= create_info->db_type;
@@ -7342,16 +7345,32 @@ err:
DBUG_RETURN(TRUE);
}
-static bool check_engine(THD *thd, const char *table_name,
- HA_CREATE_INFO *create_info)
+/**
+ @brief Check if the table can be created in the specified storage engine.
+
+ Checks if the storage engine is enabled and supports the given table
+ type (e.g. normal, temporary, system). May do engine substitution
+ if the requested engine is disabled.
+
+ @param thd Thread descriptor.
+ @param db_name Database name.
+ @param table_name Name of table to be created.
+ @param create_info Create info from parser, including engine.
+
+ @retval true Engine not available/supported, error has been reported.
+ @retval false Engine available/supported.
+*/
+static bool check_engine(THD *thd, const char *db_name,
+ const char *table_name, HA_CREATE_INFO *create_info)
{
+ DBUG_ENTER("check_engine");
handlerton **new_engine= &create_info->db_type;
handlerton *req_engine= *new_engine;
bool no_substitution=
test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION);
if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
no_substitution, 1)))
- return TRUE;
+ DBUG_RETURN(true);
if (req_engine && req_engine != *new_engine)
{
@@ -7369,9 +7388,23 @@ static bool check_engine(THD *thd, const char *table_name,
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
*new_engine= 0;
- return TRUE;
+ DBUG_RETURN(true);
}
*new_engine= myisam_hton;
}
- return FALSE;
+
+ /*
+ Check, if the given table name is system table, and if the storage engine
+ does supports it.
+ */
+ if ((create_info->used_fields & HA_CREATE_USED_ENGINE) &&
+ !ha_check_if_supported_system_table(*new_engine, db_name, table_name))
+ {
+ my_error(ER_UNSUPPORTED_ENGINE, MYF(0),
+ ha_resolve_storage_engine_name(*new_engine), db_name, table_name);
+ *new_engine= NULL;
+ DBUG_RETURN(true);
+ }
+
+ DBUG_RETURN(false);
}