|
|
|
@ -707,7 +707,9 @@ convert_error_code_to_mysql( |
|
|
|
|
|
|
|
return(HA_ERR_ROW_IS_REFERENCED); |
|
|
|
|
|
|
|
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) { |
|
|
|
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT |
|
|
|
|| error == (int) DB_FOREIGN_NO_INDEX |
|
|
|
|| error == (int) DB_REFERENCING_NO_INDEX) { |
|
|
|
|
|
|
|
return(HA_ERR_CANNOT_ADD_FOREIGN); |
|
|
|
|
|
|
|
@ -6099,6 +6101,8 @@ ha_innobase::rename_table( |
|
|
|
innobase_commit_low(trx); |
|
|
|
trx_free_for_mysql(trx); |
|
|
|
|
|
|
|
switch (error) { |
|
|
|
case DB_DUPLICATE_KEY: |
|
|
|
/* Add a special case to handle the Duplicated Key error
|
|
|
|
and return DB_ERROR instead. |
|
|
|
This is to avoid a possible SIGSEGV error from mysql error |
|
|
|
@ -6111,10 +6115,28 @@ ha_innobase::rename_table( |
|
|
|
the dup key error here is due to an existing table whose name |
|
|
|
is the one we are trying to rename to) and return the generic |
|
|
|
error code. */ |
|
|
|
if (error == (int) DB_DUPLICATE_KEY) { |
|
|
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to); |
|
|
|
|
|
|
|
error = DB_ERROR; |
|
|
|
break; |
|
|
|
case DB_FOREIGN_NO_INDEX: |
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
HA_ERR_CANNOT_ADD_FOREIGN, |
|
|
|
"Alter or rename of table '%s' failed" |
|
|
|
" because the new table is a child table" |
|
|
|
" in a FK relationship and it does not" |
|
|
|
" have an index that contains foreign" |
|
|
|
" keys as its prefix columns.", norm_to); |
|
|
|
break; |
|
|
|
case DB_REFERENCING_NO_INDEX: |
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, |
|
|
|
HA_ERR_CANNOT_ADD_FOREIGN, |
|
|
|
"Alter or rename of table '%s' failed" |
|
|
|
" because the new table is a parent table" |
|
|
|
" in a FK relationship and it does not" |
|
|
|
" have an index that contains foreign" |
|
|
|
" keys as its prefix columns.", norm_to); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
error = convert_error_code_to_mysql(error, NULL); |
|
|
|
@ -6343,8 +6365,6 @@ ha_innobase::info( |
|
|
|
dict_index_t* index; |
|
|
|
ha_rows rec_per_key; |
|
|
|
ib_longlong n_rows; |
|
|
|
ulong j; |
|
|
|
ulong i; |
|
|
|
char path[FN_REFLEN]; |
|
|
|
os_file_stat_t stat_info; |
|
|
|
|
|
|
|
@ -6354,16 +6374,6 @@ ha_innobase::info( |
|
|
|
statistics calculation on tables, because that may crash the |
|
|
|
server if an index is badly corrupted. */ |
|
|
|
|
|
|
|
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { |
|
|
|
|
|
|
|
/* We return success (0) instead of HA_ERR_CRASHED,
|
|
|
|
because we want MySQL to process this query and not |
|
|
|
stop, like it would do if it received the error code |
|
|
|
HA_ERR_CRASHED. */ |
|
|
|
|
|
|
|
DBUG_RETURN(0); |
|
|
|
} |
|
|
|
|
|
|
|
/* We do not know if MySQL can call this function before calling
|
|
|
|
external_lock(). To be safe, update the thd of the current table |
|
|
|
handle. */ |
|
|
|
@ -6458,25 +6468,24 @@ ha_innobase::info( |
|
|
|
acquiring latches inside InnoDB, we do not call it if we |
|
|
|
are asked by MySQL to avoid locking. Another reason to |
|
|
|
avoid the call is that it uses quite a lot of CPU. |
|
|
|
See Bug#38185. |
|
|
|
We do not update delete_length if no locking is requested |
|
|
|
so the "old" value can remain. delete_length is initialized |
|
|
|
to 0 in the ha_statistics' constructor. */ |
|
|
|
if (!(flag & HA_STATUS_NO_LOCK)) { |
|
|
|
|
|
|
|
/* lock the data dictionary to avoid races with
|
|
|
|
ibd_file_missing and tablespace_discarded */ |
|
|
|
row_mysql_lock_data_dictionary(prebuilt->trx); |
|
|
|
|
|
|
|
/* ib_table->space must be an existent tablespace */ |
|
|
|
if (!ib_table->ibd_file_missing |
|
|
|
&& !ib_table->tablespace_discarded) { |
|
|
|
|
|
|
|
stats.delete_length = |
|
|
|
fsp_get_available_space_in_free_extents( |
|
|
|
ib_table->space) * 1024; |
|
|
|
} else { |
|
|
|
See Bug#38185. */ |
|
|
|
if (flag & HA_STATUS_NO_LOCK) { |
|
|
|
/* We do not update delete_length if no
|
|
|
|
locking is requested so the "old" value can |
|
|
|
remain. delete_length is initialized to 0 in |
|
|
|
the ha_statistics' constructor. */ |
|
|
|
} else if (UNIV_UNLIKELY |
|
|
|
(srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { |
|
|
|
/* Avoid accessing the tablespace if
|
|
|
|
innodb_crash_recovery is set to a high value. */ |
|
|
|
stats.delete_length = 0; |
|
|
|
} else { |
|
|
|
ullint avail_space; |
|
|
|
|
|
|
|
avail_space = fsp_get_available_space_in_free_extents( |
|
|
|
ib_table->space); |
|
|
|
|
|
|
|
if (avail_space == ULLINT_UNDEFINED) { |
|
|
|
THD* thd; |
|
|
|
|
|
|
|
thd = ha_thd(); |
|
|
|
@ -6493,9 +6502,9 @@ ha_innobase::info( |
|
|
|
ib_table->name); |
|
|
|
|
|
|
|
stats.delete_length = 0; |
|
|
|
} else { |
|
|
|
stats.delete_length = avail_space * 1024; |
|
|
|
} |
|
|
|
|
|
|
|
row_mysql_unlock_data_dictionary(prebuilt->trx); |
|
|
|
} |
|
|
|
|
|
|
|
stats.check_time = 0; |
|
|
|
@ -6508,6 +6517,7 @@ ha_innobase::info( |
|
|
|
} |
|
|
|
|
|
|
|
if (flag & HA_STATUS_CONST) { |
|
|
|
ulong i = 0; |
|
|
|
index = dict_table_get_first_index_noninline(ib_table); |
|
|
|
|
|
|
|
if (prebuilt->clust_index_was_generated) { |
|
|
|
@ -6515,6 +6525,8 @@ ha_innobase::info( |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < table->s->keys; i++) { |
|
|
|
ulong j; |
|
|
|
|
|
|
|
if (index == NULL) { |
|
|
|
sql_print_error("Table %s contains fewer " |
|
|
|
"indexes inside InnoDB than " |
|
|
|
@ -6571,6 +6583,11 @@ ha_innobase::info( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { |
|
|
|
|
|
|
|
goto func_exit; |
|
|
|
} |
|
|
|
|
|
|
|
if (flag & HA_STATUS_ERRKEY) { |
|
|
|
ut_a(prebuilt->trx); |
|
|
|
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); |
|
|
|
@ -6583,6 +6600,7 @@ ha_innobase::info( |
|
|
|
stats.auto_increment_value = innobase_peek_autoinc(); |
|
|
|
} |
|
|
|
|
|
|
|
func_exit: |
|
|
|
prebuilt->trx->op_info = (char*)""; |
|
|
|
|
|
|
|
DBUG_RETURN(0); |
|
|
|
@ -7814,16 +7832,17 @@ ha_innobase::store_lock( |
|
|
|
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) |
|
|
|
&& (sql_command == SQLCOM_INSERT_SELECT |
|
|
|
|| sql_command == SQLCOM_UPDATE |
|
|
|
|| sql_command == SQLCOM_CREATE_TABLE)) { |
|
|
|
|| sql_command == SQLCOM_CREATE_TABLE |
|
|
|
|| sql_command == SQLCOM_SET_OPTION)) { |
|
|
|
|
|
|
|
/* If we either have innobase_locks_unsafe_for_binlog
|
|
|
|
option set or this session is using READ COMMITTED |
|
|
|
isolation level and isolation level of the transaction |
|
|
|
is not set to serializable and MySQL is doing |
|
|
|
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or |
|
|
|
CREATE ... SELECT... without FOR UPDATE or |
|
|
|
IN SHARE MODE in select, then we use consistent |
|
|
|
read for select. */ |
|
|
|
CREATE ... SELECT... or SET ... = (SELECT ...) |
|
|
|
without FOR UPDATE or IN SHARE MODE in select, |
|
|
|
then we use consistent read for select. */ |
|
|
|
|
|
|
|
prebuilt->select_lock_type = LOCK_NONE; |
|
|
|
prebuilt->stored_select_lock_type = LOCK_NONE; |
|
|
|
|