• unknown's avatar
    5.0 version of fix for: · e8c35f16
    unknown authored
     Bug #23667 "CREATE TABLE LIKE is not isolated from alteration
                 by other connections"
     Bug #18950 "CREATE TABLE LIKE does not obtain LOCK_open"
    As well as:
     Bug #25578 "CREATE TABLE LIKE does not require any privileges
                 on source table".
    
    The first and the second bugs resulted in various errors and wrong
    binary log order when one tried to execute concurrently CREATE TABLE LIKE
    statement and DDL statements on source table or DML/DDL statements on its
    target table.
    
    The problem was caused by incomplete protection/table-locking against
    concurrent statements implemented in mysql_create_like_table() routine.
    We solve it by simply implementing such protection in proper way (see
    comment for sql_table.cc for details).
    
    The third bug allowed user who didn't have any privileges on table create
    its copy and therefore circumvent privilege check for SHOW CREATE TABLE.
    
    This patch solves this problem by adding privilege check, which was missing.
    
    Finally it also removes some duplicated code from mysql_create_like_table().
    
    Note that, altough tests covering concurrency-related aspects of CREATE TABLE
    LIKE behaviour will only be introduced in 5.1, they were run manually for
    this patch as well.
    
    
    mysql-test/r/grant2.result:
      Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges
      on source table".
    mysql-test/t/grant2.test:
      Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges
      on source table".
    sql/handler.h:
      Introduced new flag for HA_CREATE_INFO::options in order to be able to
      distinguish CREATE TABLE ... LIKE from other types of CREATE TABLE.
    sql/mysql_priv.h:
      mysql_create_like_table() now takes source table name not as a
      Table_ident object but as regular table list element.
    sql/sql_parse.cc:
      CREATE TABLE ... LIKE implementation now uses statement's table list
      for storing information about the source table. We also use flag
      in LEX::create_info.options for distinguishing it from other types
      of CREATE TABLE.
      Finally CREATE TABLE ... LIKE now requires the same privileges on
      the source tables as SHOW CREATE TABLE. Moved this privilege check
      to check_show_create_table_access() function.
    sql/sql_table.cc:
      mysql_create_like_table():
       - Provided proper protection from concurrent statements.
         This is achieved by keeping name-lock on the source table and holding
         LOCK_open mutex during whole operation. This gives protection against
         concurrent DDL on source table. Also holding this mutex makes copying
         of .frm file, call to ha_create_table() and binlogging atomic against
         concurrent DML and DDL operations on target table.
       - Get rid of duplicated code related to source database/table name
         handling. All these operations are already done in
         st_select_lex::add_table_to_list(), so we achieve the same effect
         by including source table into the statement's table list.
    sql/sql_yacc.yy:
      Now we use special flag in LEX::create_info::options for distinguishing
      CREATE TABLE ... LIKE from other types of CREATE TABLE and store name
      of source table as regular element in statement's table list.
    e8c35f16
handler.h 35.7 KB