Commit 3a31f7b9 authored by unknown's avatar unknown

Simple fixes during review of new code


include/my_global.h:
  Added floatget() to read unaligned flaot
mysql-test/r/select.result:
  Added test for found_rows()
mysql-test/t/select.test:
  Added test for found_rows()
sql/des_key_file.cc:
  Moved initalization of LOCK_des_key_file to mysqld to make simpler code and avoid theoretical race condition
sql/field_conv.cc:
  Added optimizzed varsion of do_cut_string (for simple character sets)
sql/item_func.cc:
  Simplify code (and ensure DBUG_ENTER is excuted before main code)
sql/item_strfunc.cc:
  Safe calculation of max_length
  This was needed as max_length can now be 1<<32-1 (after konstantins recent patch to fix BLOB_LENGTH)
  Remove init_des_key_file() as this is not initialized in mysqld.cc
sql/item_timefunc.cc:
  Safe calculation of max_length
  This was needed as max_length can now be 1<<32-1 (after konstantins recent patch to fix BLOB_LENGTH)
sql/log_event.cc:
  Simplify code
sql/mysql_priv.h:
  Moved initalization of LOCK_des_key_file to mysqld to make simpler code and avoid theoretical race condition
sql/mysqld.cc:
  Moved initalization of LOCK_des_key_file to mysqld to make simpler code and avoid theoretical race condition
  Revert wrong patch of calling close_connection() in first close_connections() loop. (Bug #7403)
  Instead we now print a warning for closed connections only if mysqld is sarted with --warnings
  Added comments to make the close_connections() logic clearer
sql/sql_prepare.cc:
  Use floatget() and doubleget() to protect against unaligned data
sql/sql_select.cc:
  Fixed some cases unlikely cases where found_rows() would return wrong for queries that would return 0 or 1 rows
parent ddc35864
...@@ -972,7 +972,8 @@ do { doubleget_union _tmp; \ ...@@ -972,7 +972,8 @@ do { doubleget_union _tmp; \
#define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0) #define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0)
#define float8get(V,M) doubleget((V),(M)) #define float8get(V,M) doubleget((V),(M))
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) #define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
#define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) #define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V),sizeof(float))
#define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float))
#define float8store(V,M) doublestore((V),(M)) #define float8store(V,M) doublestore((V),(M))
#endif /* __i386__ */ #endif /* __i386__ */
...@@ -1143,7 +1144,8 @@ do { doubleget_union _tmp; \ ...@@ -1143,7 +1144,8 @@ do { doubleget_union _tmp; \
*(((char*)T)+1)=(((A) >> 16));\ *(((char*)T)+1)=(((A) >> 16));\
*(((char*)T)+0)=(((A) >> 24)); } while(0) *(((char*)T)+0)=(((A) >> 24)); } while(0)
#define floatstore(T,V) memcpy_fixed((byte*)(T), (byte*)(&V), sizeof(float)) #define floatget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
#define floatstore(T,V) memcpy_fixed((byte*) (T),(byte*)(&V),sizeof(float))
#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double)) #define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double)) #define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong)) #define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
...@@ -1158,7 +1160,8 @@ do { doubleget_union _tmp; \ ...@@ -1158,7 +1160,8 @@ do { doubleget_union _tmp; \
#define shortstore(T,V) int2store(T,V) #define shortstore(T,V) int2store(T,V)
#define longstore(T,V) int4store(T,V) #define longstore(T,V) int4store(T,V)
#ifndef floatstore #ifndef floatstore
#define floatstore(T,V) memcpy_fixed((byte*)(T), (byte*)(&V), sizeof(float)) #define floatstore(T,V) memcpy_fixed((byte*) (T),(byte*) (&V),sizeof(float))
#define floatget(V,M) memcpy_fixed((byte*) &V, (byte*) (M), sizeof(float))
#endif #endif
#ifndef doubleget #ifndef doubleget
#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double)) #define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
......
...@@ -2594,7 +2594,26 @@ INSERT INTO t1 ...@@ -2594,7 +2594,26 @@ INSERT INTO t1
SELECT 50, 3, 3 FROM DUAL SELECT 50, 3, 3 FROM DUAL
WHERE NOT EXISTS WHERE NOT EXISTS
(SELECT * FROM t1 WHERE a = 50 AND b = 3); (SELECT * FROM t1 WHERE a = 50 AND b = 3);
select found_rows();
found_rows()
0
SELECT * FROM t1; SELECT * FROM t1;
a b c a b c
50 3 3 50 3 3
select count(*) from t1;
count(*)
1
select found_rows();
found_rows()
1
select count(*) from t1 limit 2,3;
count(*)
select found_rows();
found_rows()
0
select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3;
count(*)
select found_rows();
found_rows()
1
DROP TABLE t1; DROP TABLE t1;
...@@ -2153,6 +2153,13 @@ INSERT INTO t1 ...@@ -2153,6 +2153,13 @@ INSERT INTO t1
SELECT 50, 3, 3 FROM DUAL SELECT 50, 3, 3 FROM DUAL
WHERE NOT EXISTS WHERE NOT EXISTS
(SELECT * FROM t1 WHERE a = 50 AND b = 3); (SELECT * FROM t1 WHERE a = 50 AND b = 3);
select found_rows();
SELECT * FROM t1; SELECT * FROM t1;
select count(*) from t1;
select found_rows();
select count(*) from t1 limit 2,3;
select found_rows();
select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3;
select found_rows();
DROP TABLE t1; DROP TABLE t1;
...@@ -21,18 +21,6 @@ ...@@ -21,18 +21,6 @@
struct st_des_keyschedule des_keyschedule[10]; struct st_des_keyschedule des_keyschedule[10];
uint des_default_key; uint des_default_key;
pthread_mutex_t LOCK_des_key_file;
static int initialized= 0;
void
init_des_key_file()
{
if (!initialized)
{
initialized=1;
pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
}
}
/* /*
Function which loads DES keys from plaintext file into memory on MySQL Function which loads DES keys from plaintext file into memory on MySQL
...@@ -55,8 +43,6 @@ load_des_key_file(const char *file_name) ...@@ -55,8 +43,6 @@ load_des_key_file(const char *file_name)
DBUG_ENTER("load_des_key_file"); DBUG_ENTER("load_des_key_file");
DBUG_PRINT("enter",("name: %s",file_name)); DBUG_PRINT("enter",("name: %s",file_name));
init_des_key_file();
VOID(pthread_mutex_lock(&LOCK_des_key_file)); VOID(pthread_mutex_lock(&LOCK_des_key_file));
if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 || if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 ||
init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME))) init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME)))
...@@ -113,15 +99,4 @@ error: ...@@ -113,15 +99,4 @@ error:
VOID(pthread_mutex_unlock(&LOCK_des_key_file)); VOID(pthread_mutex_unlock(&LOCK_des_key_file));
DBUG_RETURN(result); DBUG_RETURN(result);
} }
void free_des_key_file()
{
if (initialized)
{
initialized= 01;
pthread_mutex_destroy(&LOCK_des_key_file);
}
}
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -324,7 +324,34 @@ static void do_field_real(Copy_field *copy) ...@@ -324,7 +324,34 @@ static void do_field_real(Copy_field *copy)
} }
/*
string copy for single byte characters set when to string is shorter than
from string
*/
static void do_cut_string(Copy_field *copy) static void do_cut_string(Copy_field *copy)
{
CHARSET_INFO *cs= copy->from_field->charset();
memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
/* Check if we loosed any important characters */
if (cs->cset->scan(cs,
copy->from_ptr + copy->to_length,
copy->from_ptr + copy->from_length,
MY_SEQ_SPACES) < copy->from_length - copy->to_length)
{
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, 1);
}
}
/*
string copy for multi byte characters set when to string is shorter than
from string
*/
static void do_cut_string_complex(Copy_field *copy)
{ // Shorter string field { // Shorter string field
int well_formed_error; int well_formed_error;
CHARSET_INFO *cs= copy->from_field->charset(); CHARSET_INFO *cs= copy->from_field->charset();
...@@ -351,6 +378,8 @@ static void do_cut_string(Copy_field *copy) ...@@ -351,6 +378,8 @@ static void do_cut_string(Copy_field *copy)
} }
static void do_expand_string(Copy_field *copy) static void do_expand_string(Copy_field *copy)
{ {
CHARSET_INFO *cs= copy->from_field->charset(); CHARSET_INFO *cs= copy->from_field->charset();
...@@ -517,7 +546,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) ...@@ -517,7 +546,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
from_length) from_length)
return do_varstring; return do_varstring;
else if (to_length < from_length) else if (to_length < from_length)
return do_cut_string; return (from->charset()->mbmaxlen == 1 ?
do_cut_string : do_cut_string_complex);
else if (to_length > from_length) else if (to_length > from_length)
return do_expand_string; return do_expand_string;
} }
......
...@@ -3045,14 +3045,15 @@ Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, ...@@ -3045,14 +3045,15 @@ Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
bool bool
Item_func_get_system_var::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_func_get_system_var::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
Item *item= var->item(thd, var_type, &component); Item *item;
DBUG_ENTER("Item_func_get_system_var::fix_fields"); DBUG_ENTER("Item_func_get_system_var::fix_fields");
/* /*
Evaluate the system variable and substitute the result (a basic constant) Evaluate the system variable and substitute the result (a basic constant)
instead of this item. If the variable can not be evaluated, instead of this item. If the variable can not be evaluated,
the error is reported in sys_var::item(). the error is reported in sys_var::item().
*/ */
if (item == 0) if (!(item= var->item(thd, var_type, &component)))
DBUG_RETURN(1); // Impossible DBUG_RETURN(1); // Impossible
item->set_name(name, 0, system_charset_info); // don't allocate a new name item->set_name(name, 0, system_charset_info); // don't allocate a new name
thd->change_item_tree(ref, item); thd->change_item_tree(ref, item);
......
...@@ -345,19 +345,20 @@ null: ...@@ -345,19 +345,20 @@ null:
void Item_func_concat::fix_length_and_dec() void Item_func_concat::fix_length_and_dec()
{ {
max_length=0; ulonglong max_result_length= 0;
if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV))
return; return;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
max_length+=args[i]->max_length; max_result_length+= args[i]->max_length;
if (max_length > MAX_BLOB_WIDTH) if (max_result_length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_result_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) max_result_length;
} }
/* /*
...@@ -388,9 +389,6 @@ String *Item_func_des_encrypt::val_str(String *str) ...@@ -388,9 +389,6 @@ String *Item_func_des_encrypt::val_str(String *str)
if (arg_count == 1) if (arg_count == 1)
{ {
/* Make sure LOCK_des_key_file was initialized. */
init_des_key_file();
/* Protect against someone doing FLUSH DES_KEY_FILE */ /* Protect against someone doing FLUSH DES_KEY_FILE */
VOID(pthread_mutex_lock(&LOCK_des_key_file)); VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number=des_default_key]; keyschedule= des_keyschedule[key_number=des_default_key];
...@@ -401,10 +399,6 @@ String *Item_func_des_encrypt::val_str(String *str) ...@@ -401,10 +399,6 @@ String *Item_func_des_encrypt::val_str(String *str)
key_number= (uint) args[1]->val_int(); key_number= (uint) args[1]->val_int();
if (key_number > 9) if (key_number > 9)
goto error; goto error;
/* Make sure LOCK_des_key_file was initialized. */
init_des_key_file();
VOID(pthread_mutex_lock(&LOCK_des_key_file)); VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number]; keyschedule= des_keyschedule[key_number];
VOID(pthread_mutex_unlock(&LOCK_des_key_file)); VOID(pthread_mutex_unlock(&LOCK_des_key_file));
...@@ -493,9 +487,6 @@ String *Item_func_des_decrypt::val_str(String *str) ...@@ -493,9 +487,6 @@ String *Item_func_des_decrypt::val_str(String *str)
if (!(current_thd->master_access & SUPER_ACL) || key_number > 9) if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
goto error; goto error;
/* Make sure LOCK_des_key_file was initialized. */
init_des_key_file();
VOID(pthread_mutex_lock(&LOCK_des_key_file)); VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number]; keyschedule= des_keyschedule[key_number];
VOID(pthread_mutex_unlock(&LOCK_des_key_file)); VOID(pthread_mutex_unlock(&LOCK_des_key_file));
...@@ -669,7 +660,7 @@ null: ...@@ -669,7 +660,7 @@ null:
void Item_func_concat_ws::fix_length_and_dec() void Item_func_concat_ws::fix_length_and_dec()
{ {
max_length=0; ulonglong max_result_length;
if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV))
return; return;
...@@ -679,15 +670,16 @@ void Item_func_concat_ws::fix_length_and_dec() ...@@ -679,15 +670,16 @@ void Item_func_concat_ws::fix_length_and_dec()
it is done on parser level in sql_yacc.yy it is done on parser level in sql_yacc.yy
so, (arg_count - 2) is safe here. so, (arg_count - 2) is safe here.
*/ */
max_length= args[0]->max_length * (arg_count - 2); max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2);
for (uint i=1 ; i < arg_count ; i++) for (uint i=1 ; i < arg_count ; i++)
max_length+=args[i]->max_length; max_result_length+=args[i]->max_length;
if (max_length > MAX_BLOB_WIDTH) if (max_result_length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_result_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) max_result_length;
} }
...@@ -866,18 +858,19 @@ null: ...@@ -866,18 +858,19 @@ null:
void Item_func_replace::fix_length_and_dec() void Item_func_replace::fix_length_and_dec()
{ {
max_length=args[0]->max_length; ulonglong max_result_length= args[0]->max_length;
int diff=(int) (args[2]->max_length - args[1]->max_length); int diff=(int) (args[2]->max_length - args[1]->max_length);
if (diff > 0 && args[1]->max_length) if (diff > 0 && args[1]->max_length)
{ // Calculate of maxreplaces { // Calculate of maxreplaces
uint max_substrs= max_length/args[1]->max_length; ulonglong max_substrs= max_result_length/args[1]->max_length;
max_length+= max_substrs * (uint) diff; max_result_length+= max_substrs * (uint) diff;
} }
if (max_length > MAX_BLOB_WIDTH) if (max_result_length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_result_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) max_result_length;
if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV)) if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV))
return; return;
...@@ -925,18 +918,22 @@ null: ...@@ -925,18 +918,22 @@ null:
void Item_func_insert::fix_length_and_dec() void Item_func_insert::fix_length_and_dec()
{ {
Item *cargs[2]; Item *cargs[2];
ulonglong max_result_length;
cargs[0]= args[0]; cargs[0]= args[0];
cargs[1]= args[3]; cargs[1]= args[3];
if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
return; return;
args[0]= cargs[0]; args[0]= cargs[0];
args[3]= cargs[1]; args[3]= cargs[1];
max_length=args[0]->max_length+args[3]->max_length; max_result_length= ((ulonglong) args[0]->max_length+
if (max_length > MAX_BLOB_WIDTH) (ulonglong) args[3]->max_length);
if (max_result_length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_result_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) max_result_length;
} }
...@@ -1967,17 +1964,19 @@ void Item_func_repeat::fix_length_and_dec() ...@@ -1967,17 +1964,19 @@ void Item_func_repeat::fix_length_and_dec()
collation.set(args[0]->collation); collation.set(args[0]->collation);
if (args[1]->const_item()) if (args[1]->const_item())
{ {
max_length=(long) (args[0]->max_length * args[1]->val_int()); ulonglong max_result_length= ((ulonglong) args[0]->max_length *
if (max_length >= MAX_BLOB_WIDTH) args[1]->val_int());
if (max_result_length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_result_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) max_result_length;
} }
else else
{ {
max_length=MAX_BLOB_WIDTH; max_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
} }
...@@ -2032,6 +2031,7 @@ err: ...@@ -2032,6 +2031,7 @@ err:
void Item_func_rpad::fix_length_and_dec() void Item_func_rpad::fix_length_and_dec()
{ {
Item *cargs[2]; Item *cargs[2];
cargs[0]= args[0]; cargs[0]= args[0];
cargs[1]= args[2]; cargs[1]= args[2];
if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
...@@ -2040,18 +2040,20 @@ void Item_func_rpad::fix_length_and_dec() ...@@ -2040,18 +2040,20 @@ void Item_func_rpad::fix_length_and_dec()
args[2]= cargs[1]; args[2]= cargs[1];
if (args[1]->const_item()) if (args[1]->const_item())
{ {
uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; ulonglong length= ((ulonglong) args[1]->val_int() *
max_length=max(args[0]->max_length,length); collation.collation->mbmaxlen);
if (max_length >= MAX_BLOB_WIDTH) length= max((ulonglong) args[0]->max_length, length);
if (length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) length;
} }
else else
{ {
max_length=MAX_BLOB_WIDTH; max_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
} }
...@@ -2126,18 +2128,20 @@ void Item_func_lpad::fix_length_and_dec() ...@@ -2126,18 +2128,20 @@ void Item_func_lpad::fix_length_and_dec()
if (args[1]->const_item()) if (args[1]->const_item())
{ {
uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; ulonglong length= ((ulonglong) args[1]->val_int() *
max_length=max(args[0]->max_length,length); collation.collation->mbmaxlen);
if (max_length >= MAX_BLOB_WIDTH) length= max((ulonglong) args[0]->max_length, length);
if (length >= MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
max_length= (ulong) length;
} }
else else
{ {
max_length=MAX_BLOB_WIDTH; max_length= MAX_BLOB_WIDTH;
maybe_null=1; maybe_null= 1;
} }
} }
......
...@@ -1538,7 +1538,7 @@ void Item_func_date_format::fix_length_and_dec() ...@@ -1538,7 +1538,7 @@ void Item_func_date_format::fix_length_and_dec()
{ {
fixed_length=0; fixed_length=0;
/* The result is a binary string (no reason to use collation->mbmaxlen */ /* The result is a binary string (no reason to use collation->mbmaxlen */
max_length=args[1]->max_length*10; max_length=min(args[1]->max_length,MAX_BLOB_WIDTH) * 10;
set_if_smaller(max_length,MAX_BLOB_WIDTH); set_if_smaller(max_length,MAX_BLOB_WIDTH);
} }
maybe_null=1; // If wrong date maybe_null=1; // If wrong date
......
...@@ -1810,24 +1810,13 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1810,24 +1810,13 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
thd->query= load_data_query; thd->query= load_data_query;
} }
/*
We need to set thd->lex->sql_command and thd->lex->duplicates
since InnoDB tests these variables to decide if this is a LOAD
DATA ... REPLACE INTO ... statement even though mysql_parse()
is not called. This is not needed in 5.0 since there the LOAD
DATA ... statement is replicated using mysql_parse(), which
sets the thd->lex fields correctly.
*/
thd->lex->sql_command= SQLCOM_LOAD;
if (sql_ex.opt_flags & REPLACE_FLAG) if (sql_ex.opt_flags & REPLACE_FLAG)
{ {
thd->lex->duplicates= DUP_REPLACE;
handle_dup= DUP_REPLACE; handle_dup= DUP_REPLACE;
} }
else if (sql_ex.opt_flags & IGNORE_FLAG) else if (sql_ex.opt_flags & IGNORE_FLAG)
{ {
ignore= 1; ignore= 1;
thd->lex->duplicates= DUP_ERROR;
handle_dup= DUP_ERROR; handle_dup= DUP_ERROR;
} }
else else
...@@ -1845,9 +1834,18 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1845,9 +1834,18 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
If reading from net (a 3.23 master), mysql_load() will change this If reading from net (a 3.23 master), mysql_load() will change this
to IGNORE. to IGNORE.
*/ */
thd->lex->duplicates= DUP_ERROR;
handle_dup= DUP_ERROR; handle_dup= DUP_ERROR;
} }
/*
We need to set thd->lex->sql_command and thd->lex->duplicates
since InnoDB tests these variables to decide if this is a LOAD
DATA ... REPLACE INTO ... statement even though mysql_parse()
is not called. This is not needed in 5.0 since there the LOAD
DATA ... statement is replicated using mysql_parse(), which
sets the thd->lex fields correctly.
*/
thd->lex->sql_command= SQLCOM_LOAD;
thd->lex->duplicates= handle_dup;
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG); sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs); String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
......
...@@ -631,9 +631,7 @@ extern char *des_key_file; ...@@ -631,9 +631,7 @@ extern char *des_key_file;
extern struct st_des_keyschedule des_keyschedule[10]; extern struct st_des_keyschedule des_keyschedule[10];
extern uint des_default_key; extern uint des_default_key;
extern pthread_mutex_t LOCK_des_key_file; extern pthread_mutex_t LOCK_des_key_file;
void init_des_key_file();
bool load_des_key_file(const char *file_name); bool load_des_key_file(const char *file_name);
void free_des_key_file();
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/* sql_do.cc */ /* sql_do.cc */
...@@ -943,6 +941,9 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, ...@@ -943,6 +941,9 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_slave_list, LOCK_active_mi, LOCK_manager,
LOCK_global_system_variables, LOCK_user_conn; LOCK_global_system_variables, LOCK_user_conn;
#ifdef HAVE_OPENSSL
extern pthread_mutex_t LOCK_des_key_file;
#endif
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_attr_t connection_attrib; extern pthread_attr_t connection_attrib;
......
...@@ -417,6 +417,9 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, ...@@ -417,6 +417,9 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables, LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
#ifdef HAVE_OPENSSL
pthread_mutex_t LOCK_des_key_file;
#endif
rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped, pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
COND_slave_start; COND_slave_start;
...@@ -647,7 +650,11 @@ static void close_connections(void) ...@@ -647,7 +650,11 @@ static void close_connections(void)
end_thr_alarm(0); // Abort old alarms. end_thr_alarm(0); // Abort old alarms.
end_slave(); end_slave();
/* First signal all threads that it's time to die */ /*
First signal all threads that it's time to die
This will give the threads some time to gracefully abort their
statements and inform their clients that the server is about to die.
*/
THD *tmp; THD *tmp;
(void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
...@@ -657,13 +664,7 @@ static void close_connections(void) ...@@ -657,13 +664,7 @@ static void close_connections(void)
{ {
DBUG_PRINT("quit",("Informing thread %ld that it's time to die", DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
tmp->thread_id)); tmp->thread_id));
/* tmp->killed= 1;
Re: bug 7403 - close_connection will be called mulitple times
bug a wholesale clean up of our network code is a very large
project. This will wake up the socket on Windows and prevent the
printing of the error message that we are force closing a connection.
*/
close_connection(tmp, 0, 0);
if (tmp->mysys_var) if (tmp->mysys_var)
{ {
tmp->mysys_var->abort=1; tmp->mysys_var->abort=1;
...@@ -680,9 +681,13 @@ static void close_connections(void) ...@@ -680,9 +681,13 @@ static void close_connections(void)
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
if (thread_count) if (thread_count)
sleep(1); // Give threads time to die sleep(2); // Give threads time to die
/* Force remaining threads to die by closing the connection to the client */ /*
Force remaining threads to die by closing the connection to the client
This will ensure that threads that are waiting for a command from the
client on a blocking read call are aborted.
*/
for (;;) for (;;)
{ {
...@@ -697,7 +702,8 @@ static void close_connections(void) ...@@ -697,7 +702,8 @@ static void close_connections(void)
#ifndef __bsdi__ // Bug in BSDI kernel #ifndef __bsdi__ // Bug in BSDI kernel
if (tmp->vio_ok()) if (tmp->vio_ok())
{ {
sql_print_error(ER(ER_FORCING_CLOSE),my_progname, if (global_system_variables.log_warnings)
sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
tmp->thread_id,tmp->user ? tmp->user : ""); tmp->thread_id,tmp->user ? tmp->user : "");
close_connection(tmp,0,0); close_connection(tmp,0,0);
} }
...@@ -1012,7 +1018,6 @@ void clean_up(bool print_message) ...@@ -1012,7 +1018,6 @@ void clean_up(bool print_message)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (ssl_acceptor_fd) if (ssl_acceptor_fd)
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
free_des_key_file();
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#ifdef USE_REGEX #ifdef USE_REGEX
regex_end(); regex_end();
...@@ -1082,6 +1087,9 @@ static void clean_up_mutexes() ...@@ -1082,6 +1087,9 @@ static void clean_up_mutexes()
(void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_sent);
(void) pthread_mutex_destroy(&LOCK_bytes_received); (void) pthread_mutex_destroy(&LOCK_bytes_received);
(void) pthread_mutex_destroy(&LOCK_user_conn); (void) pthread_mutex_destroy(&LOCK_user_conn);
#ifdef HAVE_OPENSSL
(void) pthread_mutex_destroy(&LOCK_des_key_file);
#endif
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
(void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_mutex_destroy(&LOCK_rpl_status);
(void) pthread_cond_destroy(&COND_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status);
...@@ -2585,6 +2593,9 @@ static int init_thread_environment() ...@@ -2585,6 +2593,9 @@ static int init_thread_environment()
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
#ifdef HAVE_OPENSSL
(void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
#endif
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL); (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL); (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
(void) my_rwlock_init(&LOCK_grant, NULL); (void) my_rwlock_init(&LOCK_grant, NULL);
......
...@@ -312,7 +312,7 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len) ...@@ -312,7 +312,7 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len)
return; return;
float4get(data,*pos); float4get(data,*pos);
#else #else
data= *(float*) *pos; floatget(data, *pos);
#endif #endif
param->set_double((double) data); param->set_double((double) data);
*pos+= 4; *pos+= 4;
...@@ -326,7 +326,7 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len) ...@@ -326,7 +326,7 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len)
return; return;
float8get(data,*pos); float8get(data,*pos);
#else #else
data= *(double*) *pos; doubleget(data, *pos);
#endif #endif
param->set_double((double) data); param->set_double((double) data);
*pos+= 8; *pos+= 8;
...@@ -580,10 +580,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, ...@@ -580,10 +580,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
Item_param **begin= stmt->param_array; Item_param **begin= stmt->param_array;
Item_param **end= begin + stmt->param_count; Item_param **end= begin + stmt->param_count;
uint32 length= 0; uint32 length= 0;
String str; String str;
const String *res; const String *res;
DBUG_ENTER("insert_params_withlog"); DBUG_ENTER("insert_params_withlog");
if (query->copy(stmt->query, stmt->query_length, default_charset_info)) if (query->copy(stmt->query, stmt->query_length, default_charset_info))
......
...@@ -1081,14 +1081,18 @@ JOIN::exec() ...@@ -1081,14 +1081,18 @@ JOIN::exec()
else else
{ {
error= (int) result->send_eof(); error= (int) result->send_eof();
send_records=1; send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
thd->sent_row_count);
} }
} }
else else
{
error=(int) result->send_eof(); error=(int) result->send_eof();
send_records= 0;
}
} }
/* Single select (without union and limit) always returns 1 row */ /* Single select (without union) always returns 0 or 1 row */
thd->limit_found_rows= 1; thd->limit_found_rows= send_records;
thd->examined_row_count= 0; thd->examined_row_count= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -3552,6 +3556,7 @@ static void add_not_null_conds(JOIN *join) ...@@ -3552,6 +3556,7 @@ static void add_not_null_conds(JOIN *join)
if (tab->ref.null_rejecting & (1 << keypart)) if (tab->ref.null_rejecting & (1 << keypart))
{ {
Item *item= tab->ref.items[keypart]; Item *item= tab->ref.items[keypart];
Item *notnull;
DBUG_ASSERT(item->type() == Item::FIELD_ITEM); DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
Item_field *not_null_item= (Item_field*)item; Item_field *not_null_item= (Item_field*)item;
JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
...@@ -3562,7 +3567,6 @@ static void add_not_null_conds(JOIN *join) ...@@ -3562,7 +3567,6 @@ static void add_not_null_conds(JOIN *join)
*/ */
if (!referred_tab || referred_tab->join != join) if (!referred_tab || referred_tab->join != join)
continue; continue;
Item *notnull;
if (!(notnull= new Item_func_isnotnull(not_null_item))) if (!(notnull= new Item_func_isnotnull(not_null_item)))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment