1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Bug#39843 DELETE requires write access to table in subquery in where clause

An unnecessarily restrictive lock were taken on sub-SELECTs during DELETE.

During parsing, a global structure is reused for sub-SELECTs and the attribute
keeping track of lock options were not reset properly.
This patch introduces a new attribute to keep track on the syntactical lock
option elements found in a sub-SELECT and then sets the lock options accordingly.

Now the sub-SELECTs will try to acquire a READ lock if possible
instead of a WRITE lock as inherited from the outer DELETE statement.


mysql-test/r/lock.result:
  Added test case for bug39843
mysql-test/t/lock.test:
  Added test case for bug39843
sql/sql_lex.cc:
  * Reset member variable lock_option on each new query.
sql/sql_lex.h:
  * Introduced new member variable 'lock_option' which is keeping track
    of the syntactical lock option of a (sub-)select query.
sql/sql_parse.cc:
  * Wrote comments to functions.
sql/sql_yacc.yy:
  * Introduced an attribute to keep track of syntactical lock options
    in sub-selects.
  * Made sure that the default value TL_READ_DEFAULT is at the begining
    of each subselect-rule.
This commit is contained in:
Kristofer Pettersson
2009-03-05 15:22:33 +01:00
parent d61f114f7f
commit ddaede8087
6 changed files with 103 additions and 2 deletions

View File

@ -5580,6 +5580,14 @@ void mysql_reset_thd_for_next_command(THD *thd)
}
/**
Resets the lex->current_select object.
@note It is assumed that lex->current_select != NULL
This function is a wrapper around select_lex->init_select() with an added
check for the special situation when using INTO OUTFILE and LOAD DATA.
*/
void
mysql_init_select(LEX *lex)
{
@ -5594,6 +5602,18 @@ mysql_init_select(LEX *lex)
}
/**
Used to allocate a new SELECT_LEX object on the current thd mem_root and
link it into the relevant lists.
This function is always followed by mysql_init_select.
@see mysql_init_select
@retval TRUE An error occurred
@retval FALSE The new SELECT_LEX was successfully allocated.
*/
bool
mysql_new_select(LEX *lex, bool move_down)
{
@ -6411,7 +6431,6 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
DBUG_ENTER("set_lock_for_tables");
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
for_update));
for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
tables;
tables= tables->next_local)