• unknown's avatar
    Bug#30882 Dropping a temporary table inside a stored function may cause a server crash · c6fd10db
    unknown authored
    If a stored function that contains a drop temporary table statement
    is invoked by a create temporary table of the same name may cause
    a server crash. The problem is that when dropping a table no check
    is done to ensure that table is not being used by some outer query
    (or outer statement), potentially leaving the outer query with a
    reference to a stale (freed) table.
    
    The solution is when dropping a temporary table, always check if
    the table is being used by some outer statement as a temporary
    table can be dropped inside stored procedures.
    
    The check is performed by looking at the TABLE::query_id value for
    temporary tables. To simplify this check and to solve a bug related
    to handling of temporary tables in prelocked mode, this patch changes
    the way in which this member is used to track the fact that table is
    used/unused. Now we ensure that TABLE::query_id is zero for unused
    temporary tables (which means that all temporary tables which were
    used by a statement should be marked as free for reuse after it's
    execution has been completed).
    
    
    mysql-test/include/handler.inc:
      Add test case for side effect of Bug#30882
    mysql-test/r/handler_innodb.result:
      Add test case result for side effect of Bug#30882
    mysql-test/r/handler_myisam.result:
      Add test case result for side effect of Bug#30882
    mysql-test/r/sp-error.result:
      Add test case result for Bug#30882
    mysql-test/t/sp-error.test:
      Add test case for Bug#30882
    sql/event_db_repository.cc:
      Update close_thread_tables call, no more default values.
    sql/mysql_priv.h:
      Remove implicit default parameters values of the close_thread_tables
      function as no callers are using it.
    sql/slave.cc:
      Update close_thread_tables call, no more default values
    sql/sp_head.cc:
      Update close_thread_tables call, no more default values
    sql/sql_base.cc:
      Changed the approach to distinguishing currently unused temporary tables.
      Now we ensure that such tables always have TABLE::query_id set to 0 and
      use this fact to perform checks during opening and dropping of temporary
      tables. This means that we have to call close_thread_tables() even for
      statements which use only temporary tables. To make this call cheaper,
      we re-factored close_thread_tables() to not take LOCK_open unless there
      are open base tables.
    sql/sql_handler.cc:
      Properly close temporary tables associated with a handler.
    sql/sql_insert.cc:
      close_temporary_table is now merged into drop_temporary_table.
    sql/sql_parse.cc:
      Now the condition doesn't cover all cases because close_thread_tables()
      must be called even for statements that use only temporary tables.
    sql/sql_table.cc:
      Use drop_temporary_table which perform checks to verify if
      the table is not being used. Error path problem is due to
      a handler tables issue and is going to be addressed in bug
      31397.
    sql/table.h:
      Rename previously unused clear_query_id and document the usage of
      query_id and open_by_handler.
    c6fd10db
sql_handler.cc 24.9 KB