Loading mysql-test/r/create.result +18 −0 Original line number Diff line number Diff line Loading @@ -563,3 +563,21 @@ select * from t2; b 1 drop table t1,t2; use test; create table t1 (a int); create table t1 select * from t1; ERROR HY000: You can't specify target table 't1' for update in FROM clause create table t2 union = (t1) select * from t1; ERROR HY000: You can't specify target table 't1' for update in FROM clause flush tables with read lock; unlock tables; drop table t1; create table t1(column.name int); ERROR 42000: Incorrect table name 'column' create table t1(test.column.name int); ERROR 42000: Incorrect table name 'column' create table t1(xyz.t1.name int); ERROR 42000: Incorrect database name 'xyz' create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2; mysql-test/t/create.test +30 −0 Original line number Diff line number Diff line Loading @@ -460,3 +460,33 @@ insert into t2 values (); select * from t1; select * from t2; drop table t1,t2; # # Bug#10224 - ANALYZE TABLE crashing with simultaneous # CREATE ... SELECT statement. # This tests two additional possible errors and a hang if # an improper fix is present. # connection default; use test; create table t1 (a int); --error 1093 create table t1 select * from t1; --error 1093 create table t2 union = (t1) select * from t1; flush tables with read lock; unlock tables; drop table t1; # # Bug#10413: Invalid column name is not rejected # --error 1103 create table t1(column.name int); --error 1103 create table t1(test.column.name int); --error 1102 create table t1(xyz.t1.name int); create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2; sql/lock.cc +21 −48 Original line number Diff line number Diff line Loading @@ -82,8 +82,24 @@ static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error); MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, bool ignore_global_read_lock) /* Lock tables. SYNOPSIS mysql_lock_tables() thd The current thread. tables An array of pointers to the tables to lock. count The number of tables to lock. flags Options: MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. RETURN A lock structure pointer on success. NULL on error. */ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags) { MYSQL_LOCK *sql_lock; TABLE *write_lock_used; Loading @@ -94,7 +110,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used))) break; if (global_read_lock && write_lock_used && ! ignore_global_read_lock) if (global_read_lock && write_lock_used && ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) { /* Someone has issued LOCK ALL TABLES FOR READ and we want a write lock Loading Loading @@ -128,7 +145,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, thd->some_tables_deleted=1; // Try again sql_lock->lock_count=0; // Locks are alread freed } else if (!thd->some_tables_deleted) else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) { thd->locked=0; break; Loading Loading @@ -914,47 +931,3 @@ void make_global_read_lock_block_commit(THD *thd) } /* Set protection against global read lock. SYNOPSIS set_protect_against_global_read_lock() void RETURN FALSE OK, no global read lock exists. TRUE Error, global read lock exists already. */ my_bool set_protect_against_global_read_lock(void) { my_bool global_read_lock_exists; pthread_mutex_lock(&LOCK_open); if (! (global_read_lock_exists= test(global_read_lock))) protect_against_global_read_lock++; pthread_mutex_unlock(&LOCK_open); return global_read_lock_exists; } /* Unset protection against global read lock. SYNOPSIS unset_protect_against_global_read_lock() void RETURN void */ void unset_protect_against_global_read_lock(void) { pthread_mutex_lock(&LOCK_open); protect_against_global_read_lock--; pthread_mutex_unlock(&LOCK_open); pthread_cond_broadcast(&COND_refresh); } sql/mysql_priv.h +5 −2 Original line number Diff line number Diff line Loading @@ -978,8 +978,11 @@ extern pthread_t signal_thread; extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; #endif /* HAVE_OPENSSL */ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, bool ignore_global_read_lock= FALSE); MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags); /* mysql_lock_tables() flags bits */ #define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001 #define MYSQL_LOCK_IGNORE_FLUSH 0x0002 void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count); Loading sql/sql_acl.cc +2 −2 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ptr[0]= tables[0].table; ptr[1]= tables[1].table; ptr[2]= tables[2].table; if (!(lock=mysql_lock_tables(thd,ptr,3))) if (! (lock= mysql_lock_tables(thd, ptr, 3, 0))) { sql_print_error("Fatal error: Can't lock privilege tables: %s", thd->net.last_error); Loading Loading @@ -2658,7 +2658,7 @@ my_bool grant_init(THD *org_thd) TABLE *ptr[2]; // Lock tables for quick update ptr[0]= tables[0].table; ptr[1]= tables[1].table; if (!(lock=mysql_lock_tables(thd,ptr,2))) if (! (lock= mysql_lock_tables(thd, ptr, 2, 0))) goto end; t_table = tables[0].table; c_table = tables[1].table; Loading Loading
mysql-test/r/create.result +18 −0 Original line number Diff line number Diff line Loading @@ -563,3 +563,21 @@ select * from t2; b 1 drop table t1,t2; use test; create table t1 (a int); create table t1 select * from t1; ERROR HY000: You can't specify target table 't1' for update in FROM clause create table t2 union = (t1) select * from t1; ERROR HY000: You can't specify target table 't1' for update in FROM clause flush tables with read lock; unlock tables; drop table t1; create table t1(column.name int); ERROR 42000: Incorrect table name 'column' create table t1(test.column.name int); ERROR 42000: Incorrect table name 'column' create table t1(xyz.t1.name int); ERROR 42000: Incorrect database name 'xyz' create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2;
mysql-test/t/create.test +30 −0 Original line number Diff line number Diff line Loading @@ -460,3 +460,33 @@ insert into t2 values (); select * from t1; select * from t2; drop table t1,t2; # # Bug#10224 - ANALYZE TABLE crashing with simultaneous # CREATE ... SELECT statement. # This tests two additional possible errors and a hang if # an improper fix is present. # connection default; use test; create table t1 (a int); --error 1093 create table t1 select * from t1; --error 1093 create table t2 union = (t1) select * from t1; flush tables with read lock; unlock tables; drop table t1; # # Bug#10413: Invalid column name is not rejected # --error 1103 create table t1(column.name int); --error 1103 create table t1(test.column.name int); --error 1102 create table t1(xyz.t1.name int); create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2;
sql/lock.cc +21 −48 Original line number Diff line number Diff line Loading @@ -82,8 +82,24 @@ static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error); MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, bool ignore_global_read_lock) /* Lock tables. SYNOPSIS mysql_lock_tables() thd The current thread. tables An array of pointers to the tables to lock. count The number of tables to lock. flags Options: MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. RETURN A lock structure pointer on success. NULL on error. */ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags) { MYSQL_LOCK *sql_lock; TABLE *write_lock_used; Loading @@ -94,7 +110,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used))) break; if (global_read_lock && write_lock_used && ! ignore_global_read_lock) if (global_read_lock && write_lock_used && ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) { /* Someone has issued LOCK ALL TABLES FOR READ and we want a write lock Loading Loading @@ -128,7 +145,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, thd->some_tables_deleted=1; // Try again sql_lock->lock_count=0; // Locks are alread freed } else if (!thd->some_tables_deleted) else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) { thd->locked=0; break; Loading Loading @@ -914,47 +931,3 @@ void make_global_read_lock_block_commit(THD *thd) } /* Set protection against global read lock. SYNOPSIS set_protect_against_global_read_lock() void RETURN FALSE OK, no global read lock exists. TRUE Error, global read lock exists already. */ my_bool set_protect_against_global_read_lock(void) { my_bool global_read_lock_exists; pthread_mutex_lock(&LOCK_open); if (! (global_read_lock_exists= test(global_read_lock))) protect_against_global_read_lock++; pthread_mutex_unlock(&LOCK_open); return global_read_lock_exists; } /* Unset protection against global read lock. SYNOPSIS unset_protect_against_global_read_lock() void RETURN void */ void unset_protect_against_global_read_lock(void) { pthread_mutex_lock(&LOCK_open); protect_against_global_read_lock--; pthread_mutex_unlock(&LOCK_open); pthread_cond_broadcast(&COND_refresh); }
sql/mysql_priv.h +5 −2 Original line number Diff line number Diff line Loading @@ -978,8 +978,11 @@ extern pthread_t signal_thread; extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; #endif /* HAVE_OPENSSL */ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, bool ignore_global_read_lock= FALSE); MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags); /* mysql_lock_tables() flags bits */ #define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001 #define MYSQL_LOCK_IGNORE_FLUSH 0x0002 void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count); Loading
sql/sql_acl.cc +2 −2 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ptr[0]= tables[0].table; ptr[1]= tables[1].table; ptr[2]= tables[2].table; if (!(lock=mysql_lock_tables(thd,ptr,3))) if (! (lock= mysql_lock_tables(thd, ptr, 3, 0))) { sql_print_error("Fatal error: Can't lock privilege tables: %s", thd->net.last_error); Loading Loading @@ -2658,7 +2658,7 @@ my_bool grant_init(THD *org_thd) TABLE *ptr[2]; // Lock tables for quick update ptr[0]= tables[0].table; ptr[1]= tables[1].table; if (!(lock=mysql_lock_tables(thd,ptr,2))) if (! (lock= mysql_lock_tables(thd, ptr, 2, 0))) goto end; t_table = tables[0].table; c_table = tables[1].table; Loading