summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2009-11-30 22:37:27 +0100
committerunknown <knielsen@knielsen-hq.org>2009-11-30 22:37:27 +0100
commitdb260b19e3edb9e153abf784711a3ae13e40db4a (patch)
tree4a9d9e50072d36ee917a570f8bf83a0117e971db /storage/xtradb
parent0df8279c468235f4feaf9eb25aa2beb5032ee1dc (diff)
parent4a458290441937661136c73afa61393a6634f7b0 (diff)
downloadmariadb-git-db260b19e3edb9e153abf784711a3ae13e40db4a.tar.gz
Merge MySQL 5.1.41 into MariaDB trunk, including a number of after-merge fixes.
Also merge charset patch.
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/dict/dict0dict.c2
-rw-r--r--storage/xtradb/handler/ha_innodb.cc148
-rw-r--r--storage/xtradb/handler/ha_innodb.h23
-rw-r--r--storage/xtradb/handler/handler0alter.cc10
4 files changed, 156 insertions, 27 deletions
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 1a28f354a67..050182bc831 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -1231,7 +1231,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
- if (strcmp(name, reserved_names[i]) == 0) {
+ if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index a0d02848199..cbcb5651c2e 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -139,6 +139,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
#define INSIDE_HA_INNOBASE_CC
@@ -245,6 +246,9 @@ static int innobase_release_savepoint(handlerton *hton, THD* thd,
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
/** @brief Initialize the default value of innodb_commit_concurrency.
@@ -2414,6 +2418,7 @@ skip_overwrite:
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -2468,6 +2473,7 @@ innobase_end(
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
@@ -3915,7 +3921,11 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
+
CHARSET_INFO* cs;
ulint key_len;
@@ -5869,6 +5879,28 @@ create_table_def(
}
}
+ /* First check whether the column to be added has a
+ system reserved name. */
+ if (dict_col_name_is_reserved(field->field_name)){
+ push_warning_printf(
+ (THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_CREATE_TABLE,
+ "Error creating table '%s' with "
+ "column name '%s'. '%s' is a "
+ "reserved name. Please try to "
+ "re-create the table with a "
+ "different column name.",
+ table->name, (char*) field->field_name,
+ (char*) field->field_name);
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ error = DB_ERROR;
+ goto error_ret;
+ }
+
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
@@ -5882,6 +5914,7 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
DBUG_RETURN(error);
@@ -5920,6 +5953,9 @@ create_index(
n_fields = key->key_parts;
+ /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+ ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
ind_type = 0;
if (key_num == form->s->primary_key) {
@@ -6029,7 +6065,8 @@ create_clustered_index_when_no_primary(
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
- index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+ index = dict_mem_index_create(table_name,
+ innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
@@ -6455,14 +6492,6 @@ ha_innobase::create(
flags = DICT_TF_COMPACT;
}
- error = create_table_def(trx, form, norm_name,
- create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- flags);
-
- if (error) {
- goto cleanup;
- }
-
/* Look for a primary key */
primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -6474,6 +6503,22 @@ ha_innobase::create(
ut_a(primary_key_no == -1 || primary_key_no == 0);
+ /* Check for name conflicts (with reserved name) for
+ any user indices to be created. */
+ if (innobase_index_name_is_reserved(trx, form->key_info,
+ form->s->keys)) {
+ error = -1;
+ goto cleanup;
+ }
+
+ error = create_table_def(trx, form, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+ flags);
+
+ if (error) {
+ goto cleanup;
+ }
+
/* Create the keys */
if (form->s->keys == 0 || primary_key_no == -1) {
@@ -6547,18 +6592,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -7416,9 +7465,15 @@ ha_innobase::analyze(
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
@@ -8013,8 +8068,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8892,6 +8948,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -8900,11 +8957,13 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
+
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -9943,6 +10002,49 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an warning message to the client, and returns true. */
+extern "C" UNIV_INTERN
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if an index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys) /* in: Number of indexes to
+ be created. */
+{
+ const KEY* key;
+ uint key_num; /* index number */
+
+ for (key_num = 0; key_num < num_of_keys; key_num++) {
+ key = &key_info[key_num];
+
+ if (innobase_strcasecmp(key->name,
+ innobase_index_reserve_name) == 0) {
+ /* Push warning to mysql */
+ push_warning_printf((THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_NAME_FOR_INDEX,
+ "Cannot Create Index with name "
+ "'%s'. The name is reserved "
+ "for the system default primary "
+ "index.",
+ innobase_index_reserve_name);
+
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ innobase_index_reserve_name);
+
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index cc98003f8ff..b88aac2ae32 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -257,6 +257,13 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
typedef struct trx_struct trx_t;
@@ -282,3 +289,19 @@ trx_t*
innobase_trx_allocate(
/*==================*/
MYSQL_THD thd); /*!< in: user thread handle */
+/*********************************************************************//**
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name
+matches, this function pushes an warning message to the client,
+and returns true. */
+extern "C"
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if the index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys); /* in: Number of indexes to
+ be created. */
+
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 12f6099eeb3..a523fe406ed 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -657,9 +657,13 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
- /* Check that index keys are sensible */
-
- error = innobase_check_index_keys(key_info, num_of_keys);
+ /* Check if the index name is reserved. */
+ if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
+ error = ER_WRONG_NAME_FOR_INDEX;
+ } else {
+ /* Check that index keys are sensible */
+ error = innobase_check_index_keys(key_info, num_of_keys);
+ }
if (UNIV_UNLIKELY(error)) {
err_exit: