|
|
|
@ -110,7 +110,7 @@ extern "C" { |
|
|
|
# ifndef MYSQL_PLUGIN_IMPORT
|
|
|
|
# define MYSQL_PLUGIN_IMPORT /* nothing */
|
|
|
|
# endif /* MYSQL_PLUGIN_IMPORT */
|
|
|
|
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
|
|
|
|
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
|
|
|
|
is defined the same in both builds: the MySQL server and the InnoDB plugin. */ |
|
|
|
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count; |
|
|
|
|
|
|
|
@ -129,6 +129,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
|
|
|
|
@ -229,21 +230,6 @@ static handler *innobase_create_handler(handlerton *hton, |
|
|
|
TABLE_SHARE *table, |
|
|
|
MEM_ROOT *mem_root); |
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
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 error message to the client, and returns true. */ |
|
|
|
static |
|
|
|
bool |
|
|
|
innobase_index_name_is_reserved( |
|
|
|
/*============================*/ |
|
|
|
/* out: true if index name matches a
|
|
|
|
reserved name */ |
|
|
|
const trx_t* trx, /* in: InnoDB transaction handle */ |
|
|
|
const TABLE* form, /* in: information on table
|
|
|
|
columns and indexes */ |
|
|
|
const char* norm_name); /* in: table name */ |
|
|
|
|
|
|
|
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
|
|
|
|
system primary index. */ |
|
|
|
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX"; |
|
|
|
@ -2266,6 +2252,7 @@ innobase_change_buffering_inited_ok: |
|
|
|
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
|
|
|
|
@ -2320,6 +2307,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); |
|
|
|
} |
|
|
|
|
|
|
|
@ -2598,6 +2586,8 @@ innobase_rollback( |
|
|
|
|
|
|
|
innobase_release_stat_resources(trx); |
|
|
|
|
|
|
|
trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */ |
|
|
|
|
|
|
|
/* If we had reserved the auto-inc lock for some table (if
|
|
|
|
we come here to roll back the latest SQL statement) we |
|
|
|
release it now before a possibly lengthy rollback */ |
|
|
|
@ -3758,7 +3748,10 @@ 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; |
|
|
|
@ -5688,7 +5681,7 @@ create_table_def( |
|
|
|
number fits in one byte in prtype */ |
|
|
|
push_warning_printf( |
|
|
|
(THD*) trx->mysql_thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_CANT_CREATE_TABLE, |
|
|
|
"In InnoDB, charset-collation codes" |
|
|
|
" must be below 256." |
|
|
|
@ -5722,7 +5715,7 @@ create_table_def( |
|
|
|
if (dict_col_name_is_reserved(field->field_name)){ |
|
|
|
push_warning_printf( |
|
|
|
(THD*) trx->mysql_thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_CANT_CREATE_TABLE, |
|
|
|
"Error creating table '%s' with " |
|
|
|
"column name '%s'. '%s' is a " |
|
|
|
@ -5956,7 +5949,7 @@ create_options_are_valid( |
|
|
|
/* Valid value. */ |
|
|
|
break; |
|
|
|
default: |
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: invalid" |
|
|
|
" KEY_BLOCK_SIZE = %lu." |
|
|
|
@ -5970,7 +5963,7 @@ create_options_are_valid( |
|
|
|
/* If KEY_BLOCK_SIZE was specified, check for its
|
|
|
|
dependencies. */ |
|
|
|
if (kbs_specified && !srv_file_per_table) { |
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: KEY_BLOCK_SIZE" |
|
|
|
" requires innodb_file_per_table."); |
|
|
|
@ -5978,7 +5971,7 @@ create_options_are_valid( |
|
|
|
} |
|
|
|
|
|
|
|
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { |
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: KEY_BLOCK_SIZE" |
|
|
|
" requires innodb_file_format >" |
|
|
|
@ -6002,7 +5995,7 @@ create_options_are_valid( |
|
|
|
if (!srv_file_per_table) { |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: ROW_FORMAT=%s" |
|
|
|
" requires innodb_file_per_table.", |
|
|
|
@ -6014,7 +6007,7 @@ create_options_are_valid( |
|
|
|
if (srv_file_format < DICT_TF_FORMAT_ZIP) { |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: ROW_FORMAT=%s" |
|
|
|
" requires innodb_file_format >" |
|
|
|
@ -6031,7 +6024,7 @@ create_options_are_valid( |
|
|
|
&& form->s->row_type == ROW_TYPE_DYNAMIC) { |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: cannot specify" |
|
|
|
" ROW_FORMAT = DYNAMIC with" |
|
|
|
@ -6055,7 +6048,7 @@ create_options_are_valid( |
|
|
|
if (kbs_specified) { |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: cannot specify" |
|
|
|
" ROW_FORMAT = %s with" |
|
|
|
@ -6068,7 +6061,7 @@ create_options_are_valid( |
|
|
|
|
|
|
|
default: |
|
|
|
push_warning(thd, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_ERROR, |
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
ER_ILLEGAL_HA_CREATE_OPTION, |
|
|
|
"InnoDB: invalid ROW_FORMAT specifier."); |
|
|
|
ret = FALSE; |
|
|
|
@ -6132,13 +6125,15 @@ ha_innobase::create( |
|
|
|
1. <database_name>/<table_name>: for normal table creation |
|
|
|
2. full path: for temp table creation, or sym link |
|
|
|
|
|
|
|
When srv_file_per_table is on, check for full path pattern, i.e. |
|
|
|
When srv_file_per_table is on and mysqld_embedded is off, |
|
|
|
check for full path pattern, i.e. |
|
|
|
X:\dir\..., X is a driver letter, or |
|
|
|
\\dir1\dir2\..., UNC path |
|
|
|
returns error if it is in full path format, but not creating a temp. |
|
|
|
table. Currently InnoDB does not support symbolic link on Windows. */ |
|
|
|
|
|
|
|
if (srv_file_per_table |
|
|
|
&& !mysqld_embedded |
|
|
|
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) { |
|
|
|
|
|
|
|
if ((name[1] == ':') |
|
|
|
@ -6342,7 +6337,8 @@ ha_innobase::create( |
|
|
|
|
|
|
|
/* Check for name conflicts (with reserved name) for
|
|
|
|
any user indices to be created. */ |
|
|
|
if (innobase_index_name_is_reserved(trx, form, norm_name)) { |
|
|
|
if (innobase_index_name_is_reserved(trx, form->key_info, |
|
|
|
form->s->keys)) { |
|
|
|
error = -1; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
@ -6429,18 +6425,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; |
|
|
|
|
|
|
|
@ -7294,9 +7294,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); |
|
|
|
} |
|
|
|
|
|
|
|
@ -8773,6 +8779,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; |
|
|
|
|
|
|
|
@ -8781,11 +8788,12 @@ 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; |
|
|
|
|
|
|
|
@ -9804,36 +9812,39 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff) |
|
|
|
/***********************************************************************
|
|
|
|
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 error message to the client, and returns true. */ |
|
|
|
static |
|
|
|
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 TABLE* form, /* in: information on table
|
|
|
|
columns and indexes */ |
|
|
|
const char* norm_name) /* in: table name */ |
|
|
|
const KEY* key_info, /* in: Indexes to be created */ |
|
|
|
ulint num_of_keys) /* in: Number of indexes to
|
|
|
|
be created. */ |
|
|
|
{ |
|
|
|
KEY* key; |
|
|
|
const KEY* key; |
|
|
|
uint key_num; /* index number */ |
|
|
|
|
|
|
|
for (key_num = 0; key_num < form->s->keys; key_num++) { |
|
|
|
key = form->key_info + key_num; |
|
|
|
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_ERROR, |
|
|
|
ER_CANT_CREATE_TABLE, |
|
|
|
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); |
|
|
|
} |
|
|
|
} |
|
|
|
|