summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/manual.texi3
-rw-r--r--include/thr_lock.h1
-rw-r--r--mysql-test/r/update.result37
-rw-r--r--mysql-test/t/update.test10
-rw-r--r--mysys/getvar.c14
-rw-r--r--mysys/thr_lock.c3
-rw-r--r--sql/ha_myisam.cc2
-rw-r--r--sql/lock.cc3
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_update.cc14
10 files changed, 78 insertions, 15 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi
index c8d959ea729..be16d266166 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -41442,6 +41442,9 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.34
@itemize @bullet
@item
+Fixed problem in automatic repair that could let some threads in state
+@code{Waiting for table}.
+@item
@code{SHOW CREATE TABLE} now dumps the @code{UNION()} for @code{MERGE} tables.
@item
Fixed bug when replicating timestamps.
diff --git a/include/thr_lock.h b/include/thr_lock.h
index ffcad4a4d11..42bcd9bcaba 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -32,6 +32,7 @@ extern ulong locks_immediate,locks_waited ;
enum thr_lock_type { TL_IGNORE=-1,
TL_UNLOCK, /* UNLOCK ANY LOCK */
TL_READ, /* Read lock */
+ TL_READ_WITH_SHARED_LOCKS,
/* High prior. than TL_WRITE. Allow concurrent insert */
TL_READ_HIGH_PRIORITY,
/* READ, Don't allow concurrent insert */
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 9aa47a089a6..d0cca3bdb6f 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -1,2 +1,39 @@
+a
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+145
+146
place_id shows
1 1
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 6010c311015..a51bce8aebe 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -7,6 +7,16 @@ create table t1 (a int auto_increment , primary key (a));
insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
update t1 set a=a+10 where a > 34;
update t1 set a=a+100 where a > 0;
+
+# Some strange updates to test some otherwise unused code
+update t1 set a=a+100 where a=1 and a=2;
+--error 1054
+update t1 set a=b+100 where a=1 and a=2;
+--error 1054
+update t1 set a=b+100 where c=1 and a=2;
+--error 1054
+update t1 set d=a+100 where a=1;
+select * from t1;
drop table t1;
CREATE TABLE t1
diff --git a/mysys/getvar.c b/mysys/getvar.c
index 1d452002490..a86215ea56b 100644
--- a/mysys/getvar.c
+++ b/mysys/getvar.c
@@ -52,11 +52,17 @@ my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str);
else
{
- uint length=(uint) (end-str),found_count=0;
- CHANGEABLE_VAR *var,*found;
+ uint length,found_count=0;
+ CHANGEABLE_VAR *var,*found, *var_end;
const char *name;
long num;
+ /* Skip end space from variable */
+ for (var_end=end ; end > str && is_space(end[-1]) ; end--) ;
+ length=(uint) (var_end-str);
+ /* Skip start space from argument */
+ for (end++ ; is_space(*end) ; end++) ;
+
for (var=vars,found=0 ; (name=var->name) ; var++)
{
if (!my_casecmp(name,str,length))
@@ -80,11 +86,13 @@ my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
DBUG_RETURN(1);
}
- num=(long) atol(end+1); endchar=strend(end+1)[-1];
+ num=(long) atol(end); endchar=strend(end)[-1];
if (endchar == 'k' || endchar == 'K')
num*=1024;
else if (endchar == 'm' || endchar == 'M')
num*=1024L*1024L;
+ else if (endchar == 'g' || endchar == 'G')
+ num*=1024L*1024L*1024L;
else if (!isdigit(endchar))
{
fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str);
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 2e20d3e24c0..2cd920245e2 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -27,6 +27,7 @@ Locks are prioritized according to:
The current lock types are:
TL_READ # Low priority read
+TL_READ_WITH_SHARED_LOCKS
TL_READ_HIGH_PRIORITY # High priority read
TL_READ_NO_INSERT # Read without concurrent inserts
TL_WRITE_ALLOW_WRITE # Write lock that allows other writers
@@ -667,7 +668,7 @@ void thr_unlock(THR_LOCK_DATA *data)
/* Release write-locks with TL_WRITE or TL_WRITE_ONLY priority first */
if (data &&
(data->type != TL_WRITE_LOW_PRIORITY || !lock->read_wait.data ||
- lock->read_wait.data->type == TL_READ))
+ lock->read_wait.data->type < TL_READ_HIGH_PRIORITY))
{
if (lock->write_lock_count++ > max_write_lock_count)
{
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 1a5721009f5..d8d9f12e8ea 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -643,7 +643,7 @@ bool ha_myisam::activate_all_index(THD *thd)
T_CREATE_MISSING_KEYS | T_TRUST_HEADER);
param.myf_rw&= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= myisam_sort_buffer_size;
- param.opt_rep_quick++;
+ param.opt_rep_quick++; // Don't copy data file
param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK;
diff --git a/sql/lock.cc b/sql/lock.cc
index c85983b65d6..915f1831245 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -446,7 +446,10 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
{
if (table_list->table)
+ {
hash_delete(&open_cache, (byte*) table_list->table);
+ (void) pthread_cond_broadcast(&COND_refresh);
+ }
}
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 97e6879a3a1..a293064f71e 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -687,7 +687,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
pthread_mutex_lock(&LOCK_open);
- if (open_unireg_entry(thd, table, db, table_name, table_name,0) ||
+ if (open_unireg_entry(thd, table, db, table_name, table_name, 1) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length)))
{
@@ -1259,14 +1259,14 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
if (error < 0)
{
if (!locked)
- pthread_mutex_lock(&LOCK_open);
+ pthread_mutex_unlock(&LOCK_open);
goto err;
}
if (wait_for_locked_table_names(thd,&table_list))
{
unlock_table_name(thd,&table_list);
if (!locked)
- pthread_mutex_lock(&LOCK_open);
+ pthread_mutex_unlock(&LOCK_open);
goto err;
}
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 9a08fec5a3d..a4e5dea5e76 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -62,7 +62,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
LINT_INIT(timestamp_query_id);
if (!(table = open_ltable(thd,table_list,lock_type)))
- DBUG_RETURN(-1);
+ DBUG_RETURN(-1); /* purecov: inspected */
save_time_stamp=table->time_stamp;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
@@ -156,8 +156,8 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
{
- delete select;
- table->time_stamp=save_time_stamp; // Restore timestamp pointer
+ delete select; /* purecov: inspected */
+ table->time_stamp=save_time_stamp; // Restore timestamp pointer /* purecov: inspected */
DBUG_RETURN(-1);
}
if (old_used_keys & ((key_map) 1 << used_index))
@@ -176,8 +176,8 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
if (my_b_write(&tempfile,table->file->ref,
table->file->ref_length))
{
- error=1;
- break;
+ error=1; /* purecov: inspected */
+ break; /* purecov: inspected */
}
}
else
@@ -209,7 +209,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
select->head=table;
}
if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
- error=1;
+ error=1; /* purecov: inspected */
select->file=tempfile; // Read row ptrs from this file
if (error >= 0)
{
@@ -237,7 +237,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
{
store_record(table,1);
if (fill_record(fields,values))
- break;
+ break; /* purecov: inspected */
found++;
if (compare_record(table, query_id))
{