Loading .bzrignore +2 −0 Original line number Diff line number Diff line Loading @@ -333,3 +333,5 @@ innobase/autom4te.cache/requests innobase/autom4te.cache/traces.0 innobase/stamp-h1 stamp-h1 configure.lineno innobase/configure.lineno mysql-test/r/delete.result 0 → 100644 +4 −0 Original line number Diff line number Diff line bool not_null misc NULL c 6 NULL d 7 bool not_null misc mysql-test/t/delete.test +20 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,23 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a)); insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27); delete from t1 where a=27; drop table t1; # # CHAR(0) bug - not actually DELETE bug, but anyway... # CREATE TABLE t1 ( bool char(0) default NULL, not_null varchar(20) binary NOT NULL default '', misc integer not null, PRIMARY KEY (not_null) ) TYPE=MyISAM; INSERT INTO t1 VALUES (NULL,'a',4), (NULL,'b',5), (NULL,'c',6), (NULL,'d',7); select * from t1 where misc > 5 and bool is null; delete from t1 where misc > 5 and bool is null; select * from t1 where misc > 5 and bool is null; drop table t1; sql/field.h +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ class Field { virtual String *val_str(String*,String *)=0; virtual Item_result result_type () const=0; virtual Item_result cmp_type () const { return result_type(); } bool eq(Field *field) { return ptr == field->ptr; } bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } virtual void reset(void) { bzero(ptr,pack_length()); } Loading sql/lock.cc +74 −2 Original line number Diff line number Diff line Loading @@ -416,10 +416,11 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) { TABLE *table; char key[MAX_DBKEY_LENGTH]; char *db= table_list->db ? table_list->db : (thd->db ? thd->db : (char*) ""); uint key_length; DBUG_ENTER("lock_table_name"); key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->real_name) key_length=(uint) (strmov(strmov(key,db)+1,table_list->real_name) -key)+ 1; /* Only insert the table if we haven't insert it already */ Loading Loading @@ -447,7 +448,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) my_free((gptr) table,MYF(0)); DBUG_RETURN(-1); } if (remove_table_from_cache(thd, table_list->db, table_list->real_name)) if (remove_table_from_cache(thd, db, table_list->real_name)) DBUG_RETURN(1); // Table is in use DBUG_RETURN(0); } Loading Loading @@ -490,6 +491,77 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(result); } /* Lock all tables in list with a name lock SYNOPSIS lock_table_names() thd Thread handle table_list Names of tables to lock NOTES One must have a lock on LOCK_open when calling this RETURN 0 ok 1 Fatal error (end of memory ?) */ bool lock_table_names(THD *thd, TABLE_LIST *table_list) { bool got_all_locks=1; TABLE_LIST *lock_table; for (lock_table=table_list ; lock_table ; lock_table=lock_table->next) { int got_lock; if ((got_lock=lock_table_name(thd,lock_table)) < 0) goto end; // Fatal error if (got_lock) got_all_locks=0; // Someone is using table } /* If some table was in use, wait until we got the lock */ if (!got_all_locks && wait_for_locked_table_names(thd, table_list)) goto end; return 0; end: unlock_table_names(thd, table_list, lock_table); return 1; } /* Unlock all tables in list with a name lock SYNOPSIS unlock_table_names() thd Thread handle table_list Names of tables to unlock last_table Don't unlock any tables after this one. (default 0, which will unlock all tables) NOTES One must have a lock on LOCK_open when calling this This function will send a COND_refresh signal to inform other threads that the name locks are removed RETURN 0 ok 1 Fatal error (end of memory ?) */ void unlock_table_names(THD *thd, TABLE_LIST *table_list, TABLE_LIST *last_table) { for (TABLE_LIST *table=table_list ; table != last_table ; table=table->next) unlock_table_name(thd,table); pthread_cond_broadcast(&COND_refresh); } static void print_lock_error(int error) { int textno; Loading Loading
.bzrignore +2 −0 Original line number Diff line number Diff line Loading @@ -333,3 +333,5 @@ innobase/autom4te.cache/requests innobase/autom4te.cache/traces.0 innobase/stamp-h1 stamp-h1 configure.lineno innobase/configure.lineno
mysql-test/r/delete.result 0 → 100644 +4 −0 Original line number Diff line number Diff line bool not_null misc NULL c 6 NULL d 7 bool not_null misc
mysql-test/t/delete.test +20 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,23 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a)); insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27); delete from t1 where a=27; drop table t1; # # CHAR(0) bug - not actually DELETE bug, but anyway... # CREATE TABLE t1 ( bool char(0) default NULL, not_null varchar(20) binary NOT NULL default '', misc integer not null, PRIMARY KEY (not_null) ) TYPE=MyISAM; INSERT INTO t1 VALUES (NULL,'a',4), (NULL,'b',5), (NULL,'c',6), (NULL,'d',7); select * from t1 where misc > 5 and bool is null; delete from t1 where misc > 5 and bool is null; select * from t1 where misc > 5 and bool is null; drop table t1;
sql/field.h +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ class Field { virtual String *val_str(String*,String *)=0; virtual Item_result result_type () const=0; virtual Item_result cmp_type () const { return result_type(); } bool eq(Field *field) { return ptr == field->ptr; } bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } virtual void reset(void) { bzero(ptr,pack_length()); } Loading
sql/lock.cc +74 −2 Original line number Diff line number Diff line Loading @@ -416,10 +416,11 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) { TABLE *table; char key[MAX_DBKEY_LENGTH]; char *db= table_list->db ? table_list->db : (thd->db ? thd->db : (char*) ""); uint key_length; DBUG_ENTER("lock_table_name"); key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->real_name) key_length=(uint) (strmov(strmov(key,db)+1,table_list->real_name) -key)+ 1; /* Only insert the table if we haven't insert it already */ Loading Loading @@ -447,7 +448,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) my_free((gptr) table,MYF(0)); DBUG_RETURN(-1); } if (remove_table_from_cache(thd, table_list->db, table_list->real_name)) if (remove_table_from_cache(thd, db, table_list->real_name)) DBUG_RETURN(1); // Table is in use DBUG_RETURN(0); } Loading Loading @@ -490,6 +491,77 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(result); } /* Lock all tables in list with a name lock SYNOPSIS lock_table_names() thd Thread handle table_list Names of tables to lock NOTES One must have a lock on LOCK_open when calling this RETURN 0 ok 1 Fatal error (end of memory ?) */ bool lock_table_names(THD *thd, TABLE_LIST *table_list) { bool got_all_locks=1; TABLE_LIST *lock_table; for (lock_table=table_list ; lock_table ; lock_table=lock_table->next) { int got_lock; if ((got_lock=lock_table_name(thd,lock_table)) < 0) goto end; // Fatal error if (got_lock) got_all_locks=0; // Someone is using table } /* If some table was in use, wait until we got the lock */ if (!got_all_locks && wait_for_locked_table_names(thd, table_list)) goto end; return 0; end: unlock_table_names(thd, table_list, lock_table); return 1; } /* Unlock all tables in list with a name lock SYNOPSIS unlock_table_names() thd Thread handle table_list Names of tables to unlock last_table Don't unlock any tables after this one. (default 0, which will unlock all tables) NOTES One must have a lock on LOCK_open when calling this This function will send a COND_refresh signal to inform other threads that the name locks are removed RETURN 0 ok 1 Fatal error (end of memory ?) */ void unlock_table_names(THD *thd, TABLE_LIST *table_list, TABLE_LIST *last_table) { for (TABLE_LIST *table=table_list ; table != last_table ; table=table->next) unlock_table_name(thd,table); pthread_cond_broadcast(&COND_refresh); } static void print_lock_error(int error) { int textno; Loading