mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix calls to free_underlaid_joins() in INSERT, DELETE, and UPDATE
handling so that indexes are closed before trying to commit the transaction. (Bug #15536)
This commit is contained in:
@ -1284,3 +1284,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
|||||||
id
|
id
|
||||||
4
|
4
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (a int, key(a)) engine=bdb;
|
||||||
|
create table t2 (b int, key(b)) engine=bdb;
|
||||||
|
insert into t1 values (1),(1),(2),(3),(4);
|
||||||
|
insert into t2 values (1),(5),(6),(7);
|
||||||
|
delete from t1 where (a in (select b from t2));
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
3
|
||||||
|
insert into t1 set a=(select b from t2);
|
||||||
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
3
|
||||||
|
update t1 set a = a + 1 where (a in (select b from t2));
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
3
|
||||||
|
drop table t1, t2;
|
||||||
|
End of 4.1 tests
|
||||||
|
@ -930,4 +930,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
|
|||||||
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
#
|
||||||
|
# Bug #15536: Crash when DELETE with subquery using BDB tables
|
||||||
|
#
|
||||||
|
create table t1 (a int, key(a)) engine=bdb;
|
||||||
|
create table t2 (b int, key(b)) engine=bdb;
|
||||||
|
insert into t1 values (1),(1),(2),(3),(4);
|
||||||
|
insert into t2 values (1),(5),(6),(7);
|
||||||
|
delete from t1 where (a in (select b from t2));
|
||||||
|
select count(*) from t1;
|
||||||
|
# INSERT also blows up
|
||||||
|
--error 1242
|
||||||
|
insert into t1 set a=(select b from t2);
|
||||||
|
select count(*) from t1;
|
||||||
|
# UPDATE also blows up
|
||||||
|
update t1 set a = a + 1 where (a in (select b from t2));
|
||||||
|
select count(*) from t1;
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
|
--echo End of 4.1 tests
|
||||||
|
@ -241,6 +241,7 @@ cleanup:
|
|||||||
if (!log_delayed)
|
if (!log_delayed)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||||
}
|
}
|
||||||
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
{
|
{
|
||||||
if (ha_autocommit_or_rollback(thd,error >= 0))
|
if (ha_autocommit_or_rollback(thd,error >= 0))
|
||||||
@ -252,7 +253,6 @@ cleanup:
|
|||||||
mysql_unlock_tables(thd, thd->lock);
|
mysql_unlock_tables(thd, thd->lock);
|
||||||
thd->lock=0;
|
thd->lock=0;
|
||||||
}
|
}
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
|
||||||
if (error >= 0 || thd->net.report_error)
|
if (error >= 0 || thd->net.report_error)
|
||||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
|
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
|
||||||
else
|
else
|
||||||
|
@ -194,7 +194,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
runs without --log-update or --log-bin).
|
runs without --log-update or --log-bin).
|
||||||
*/
|
*/
|
||||||
int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ;
|
int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ;
|
||||||
bool transactional_table, log_delayed;
|
bool transactional_table, log_delayed, joins_freed= FALSE;
|
||||||
uint value_count;
|
uint value_count;
|
||||||
ulong counter = 1;
|
ulong counter = 1;
|
||||||
ulonglong id;
|
ulonglong id;
|
||||||
@ -386,6 +386,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
thd->row_count++;
|
thd->row_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
|
joins_freed= TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Now all rows are inserted. Time to update logs and sends response to
|
Now all rows are inserted. Time to update logs and sends response to
|
||||||
user
|
user
|
||||||
@ -480,7 +483,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
(ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
|
(ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
|
||||||
::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff);
|
::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff);
|
||||||
}
|
}
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
|
||||||
table->insert_values=0;
|
table->insert_values=0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -489,6 +491,7 @@ abort:
|
|||||||
if (lock_type == TL_WRITE_DELAYED)
|
if (lock_type == TL_WRITE_DELAYED)
|
||||||
end_delayed_insert(thd);
|
end_delayed_insert(thd);
|
||||||
#endif
|
#endif
|
||||||
|
if (!joins_freed)
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
table->insert_values=0;
|
table->insert_values=0;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -377,6 +377,7 @@ int mysql_update(THD *thd,
|
|||||||
if (!log_delayed)
|
if (!log_delayed)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||||
}
|
}
|
||||||
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
{
|
{
|
||||||
if (ha_autocommit_or_rollback(thd, error >= 0))
|
if (ha_autocommit_or_rollback(thd, error >= 0))
|
||||||
@ -389,7 +390,6 @@ int mysql_update(THD *thd,
|
|||||||
thd->lock=0;
|
thd->lock=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
|
||||||
if (error >= 0)
|
if (error >= 0)
|
||||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
|
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user