row0mysql.c, row0mysql.h, ha_innodb.cc, sql_table.cc, handler.h:

  Fix crash when InnoDB temp table is truncated + fix bug: do not X-lock rows under LOCK TABLES except if the table is temp
parent f9e6ae6f
...@@ -408,6 +408,10 @@ struct row_prebuilt_struct { ...@@ -408,6 +408,10 @@ struct row_prebuilt_struct {
an SQL statement: we may have to set an SQL statement: we may have to set
an intention lock on the table, an intention lock on the table,
create a consistent read view etc. */ create a consistent read view etc. */
ibool mysql_has_locked; /* this is set TRUE when MySQL
calls external_lock on this handle
with a lock flag, and set FALSE when
with the F_UNLOCK flag */
ibool clust_index_was_generated; ibool clust_index_was_generated;
/* if the user did not define a /* if the user did not define a
primary key in MySQL, then Innobase primary key in MySQL, then Innobase
......
...@@ -320,6 +320,8 @@ row_create_prebuilt( ...@@ -320,6 +320,8 @@ row_create_prebuilt(
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
prebuilt->mysql_has_locked = FALSE;
prebuilt->index = NULL; prebuilt->index = NULL;
prebuilt->n_template = 0; prebuilt->n_template = 0;
prebuilt->mysql_template = NULL; prebuilt->mysql_template = NULL;
......
...@@ -3077,19 +3077,22 @@ ha_innobase::create( ...@@ -3077,19 +3077,22 @@ ha_innobase::create(
} }
} }
error = row_table_add_foreign_constraints(trx, if (current_thd->query != NULL) {
create_info->create_statement, norm_name);
error = row_table_add_foreign_constraints(trx,
current_thd->query, norm_name);
error = convert_error_code_to_mysql(error, NULL); error = convert_error_code_to_mysql(error, NULL);
if (error) { if (error) {
innobase_commit_low(trx); innobase_commit_low(trx);
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx); trx_free_for_mysql(trx);
DBUG_RETURN(error); DBUG_RETURN(error);
}
} }
innobase_commit_low(trx); innobase_commit_low(trx);
...@@ -3751,7 +3754,7 @@ ha_innobase::start_stmt( ...@@ -3751,7 +3754,7 @@ ha_innobase::start_stmt(
prebuilt->hint_no_need_to_fetch_extra_cols = TRUE; prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
prebuilt->read_just_key = 0; prebuilt->read_just_key = 0;
if (prebuilt->select_lock_type == LOCK_NONE) { if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside /* This handle is for a temporary table created inside
this same LOCK TABLES; since MySQL does NOT call external_lock this same LOCK TABLES; since MySQL does NOT call external_lock
in this case, we must use x-row locks inside InnoDB to be in this case, we must use x-row locks inside InnoDB to be
...@@ -3829,6 +3832,7 @@ ha_innobase::external_lock( ...@@ -3829,6 +3832,7 @@ ha_innobase::external_lock(
thd->transaction.all.innodb_active_trans = 1; thd->transaction.all.innodb_active_trans = 1;
trx->n_mysql_tables_in_use++; trx->n_mysql_tables_in_use++;
prebuilt->mysql_has_locked = TRUE;
if (thd->variables.tx_isolation != ISO_REPEATABLE_READ) { if (thd->variables.tx_isolation != ISO_REPEATABLE_READ) {
trx->isolation_level = innobase_map_isolation_level( trx->isolation_level = innobase_map_isolation_level(
...@@ -3852,6 +3856,7 @@ ha_innobase::external_lock( ...@@ -3852,6 +3856,7 @@ ha_innobase::external_lock(
} }
} else { } else {
trx->n_mysql_tables_in_use--; trx->n_mysql_tables_in_use--;
prebuilt->mysql_has_locked = FALSE;
auto_inc_counter_for_this_stat = 0; auto_inc_counter_for_this_stat = 0;
if (trx->n_mysql_tables_in_use == 0) { if (trx->n_mysql_tables_in_use == 0) {
......
...@@ -157,7 +157,6 @@ typedef struct st_ha_create_information ...@@ -157,7 +157,6 @@ typedef struct st_ha_create_information
ulonglong auto_increment_value; ulonglong auto_increment_value;
char *comment,*password; char *comment,*password;
char *data_file_name, *index_file_name; char *data_file_name, *index_file_name;
char *create_statement;
uint options; /* OR of HA_CREATE_ options */ uint options; /* OR of HA_CREATE_ options */
uint raid_type,raid_chunks; uint raid_type,raid_chunks;
ulong raid_chunksize; ulong raid_chunksize;
......
...@@ -695,7 +695,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -695,7 +695,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
thd->proc_info="creating table"; thd->proc_info="creating table";
create_info->create_statement = thd->query;
create_info->table_options=db_options; create_info->table_options=db_options;
if (rea_create_table(path, create_info, fields, key_count, if (rea_create_table(path, create_info, fields, key_count,
key_info_buffer)) key_info_buffer))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment