diff options
author | tulin@dl145b.mysql.com <> | 2005-07-20 07:53:10 +0200 |
---|---|---|
committer | tulin@dl145b.mysql.com <> | 2005-07-20 07:53:10 +0200 |
commit | bf6e3f9aa8a3f16667d8065df7d6c8e39cd6f9a0 (patch) | |
tree | 7f7a1503ba15f11a67dc0148085dd7ceb97e727d /sql | |
parent | 7a37e581357c7345a1b5b2008f4b5bb3702a16f3 (diff) | |
parent | d4e0d60156707b01f7a67c48b99aae84bbf90ea6 (diff) | |
download | mariadb-git-bf6e3f9aa8a3f16667d8065df7d6c8e39cd6f9a0.tar.gz |
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
Diffstat (limited to 'sql')
-rw-r--r-- | sql/des_key_file.cc | 25 | ||||
-rw-r--r-- | sql/field.cc | 211 | ||||
-rw-r--r-- | sql/field_conv.cc | 32 | ||||
-rw-r--r-- | sql/ha_blackhole.cc | 2 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 4 | ||||
-rw-r--r-- | sql/hostname.cc | 10 | ||||
-rw-r--r-- | sql/item.cc | 7 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 106 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 4 | ||||
-rw-r--r-- | sql/log_event.cc | 16 | ||||
-rw-r--r-- | sql/mysql_priv.h | 7 | ||||
-rw-r--r-- | sql/mysqld.cc | 37 | ||||
-rw-r--r-- | sql/sql_parse.cc | 30 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 12 |
16 files changed, 262 insertions, 252 deletions
diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc index 34bcbd4fc4b..77cb0c8de0f 100644 --- a/sql/des_key_file.cc +++ b/sql/des_key_file.cc @@ -21,18 +21,6 @@ struct st_des_keyschedule des_keyschedule[10]; 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 @@ -55,8 +43,6 @@ load_des_key_file(const char *file_name) DBUG_ENTER("load_des_key_file"); DBUG_PRINT("enter",("name: %s",file_name)); - init_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 || init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME))) @@ -113,15 +99,4 @@ error: VOID(pthread_mutex_unlock(&LOCK_des_key_file)); DBUG_RETURN(result); } - - -void free_des_key_file() -{ - if (initialized) - { - initialized= 01; - pthread_mutex_destroy(&LOCK_des_key_file); - } -} - #endif /* HAVE_OPENSSL */ diff --git a/sql/field.cc b/sql/field.cc index 0a8f0a39262..7661041eca2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4472,13 +4472,13 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) bool in_dst_time_gap; THD *thd= table->in_use; + /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ have_smth_to_conv= (str_to_datetime(from, len, &l_time, - ((table->in_use->variables.sql_mode & - MODE_NO_ZERO_DATE) | - MODE_NO_ZERO_IN_DATE), - &error) > + (table->in_use->variables.sql_mode & + MODE_NO_ZERO_DATE) | + MODE_NO_ZERO_IN_DATE, &error) > MYSQL_TIMESTAMP_ERROR); - + if (error || !have_smth_to_conv) { error= 1; @@ -4491,16 +4491,15 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { if (!(tmp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_DATETIME, !error); - error= 1; } else if (in_dst_time_gap) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_INVALID_TIMESTAMP, + ER_WARN_INVALID_TIMESTAMP, from, len, MYSQL_TIMESTAMP_DATETIME, !error); error= 1; } @@ -4525,8 +4524,8 @@ int Field_timestamp::store(double nr) int error= 0; if (nr < 0 || nr > 99991231235959.0) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATETIME); nr= 0; // Avoid overflow on buff error= 1; @@ -4544,35 +4543,35 @@ int Field_timestamp::store(longlong nr) bool in_dst_time_gap; THD *thd= table->in_use; - if (number_to_datetime(nr, &l_time, 0, &error)) + /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ + long tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode & + MODE_NO_ZERO_DATE) | + MODE_NO_ZERO_IN_DATE, &error); + if (tmp < 0) + { + error= 2; + } + + if (!error && tmp) { if (!(timestamp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - nr, MYSQL_TIMESTAMP_DATETIME, 1); + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, + nr, MYSQL_TIMESTAMP_DATETIME, 1); error= 1; } - if (in_dst_time_gap) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_INVALID_TIMESTAMP, - nr, MYSQL_TIMESTAMP_DATETIME, !error); + ER_WARN_INVALID_TIMESTAMP, + nr, MYSQL_TIMESTAMP_DATETIME, 1); error= 1; } - } - else if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + } else if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATETIME, 1); - if (!error && timestamp == 0 && - (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE)) - { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, - nr, MYSQL_TIMESTAMP_DATETIME, 1); - } #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4582,7 +4581,7 @@ int Field_timestamp::store(longlong nr) else #endif longstore(ptr,(uint32) timestamp); - + return error; } @@ -5155,14 +5154,14 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) TIME l_time; uint32 tmp; int error; - + if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE | (table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)), &error) <= MYSQL_TIMESTAMP_ERROR) { - tmp=0; + tmp= 0; error= 2; } else @@ -5193,56 +5192,50 @@ int Field_date::store(double nr) if (nr < 0.0 || nr > 99991231.0) { tmp=0L; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATE); error= 1; } else tmp=(long) rint(nr); - /* - We don't need to check for zero dates here as this date type is only - used in .frm tables from very old MySQL versions - */ - -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - { - int4store(ptr,tmp); - } - else -#endif - longstore(ptr,tmp); - return error; + return Field_date::store(tmp); } int Field_date::store(longlong nr) { - long tmp; - int error= 0; - if (nr >= LL(19000000000000) && nr < LL(99991231235959)) - nr=nr/LL(1000000); // Timestamp to date - if (nr < 0 || nr > LL(99991231)) + TIME not_used; + int error; + longlong initial_nr= nr; + + nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | + MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), &error); + + if (nr < 0) { - tmp=0L; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - nr, MYSQL_TIMESTAMP_DATE, 0); - error= 1; + nr= 0; + error= 2; } - else - tmp=(long) nr; + + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED, initial_nr, + MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { - int4store(ptr,tmp); + int4store(ptr, nr); } else #endif - longstore(ptr,tmp); + longstore(ptr, nr); return error; } @@ -5366,7 +5359,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) MODE_INVALID_DATES))), &error) <= MYSQL_TIMESTAMP_ERROR) { - tmp=0L; + tmp= 0L; error= 2; } else @@ -5375,7 +5368,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_DATE, 1); - + int3store(ptr,tmp); return error; } @@ -5386,7 +5379,7 @@ int Field_newdate::store(double nr) if (nr < 0.0 || nr > 99991231235959.0) { int3store(ptr,(int32) 0); - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); return 1; } @@ -5396,52 +5389,28 @@ int Field_newdate::store(double nr) int Field_newdate::store(longlong nr) { - int32 tmp; - int error= 0; - if (nr >= LL(100000000) && nr <= LL(99991231235959)) - nr=nr/LL(1000000); // Timestamp to date - if (nr < 0L || nr > 99991231L) - { - tmp=0; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, - MYSQL_TIMESTAMP_DATE, 1); - error= 1; + TIME l_time; + long tmp; + int error; + if ((tmp= number_to_datetime(nr, &l_time, + (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), + &error) < 0)) + { + tmp= 0L; + error= 2; } else - { - uint month, day; + tmp= l_time.day + l_time.month*32 + l_time.year*16*32; - tmp=(int32) nr; - if (tmp) - { - if (tmp < YY_PART_YEAR*10000L) // Fix short dates - tmp+= (uint32) 20000000L; - else if (tmp < 999999L) - tmp+= (uint32) 19000000L; - - month= (uint) ((tmp/100) % 100); - day= (uint) (tmp%100); - if (month > 12 || day > 31) - { - tmp=0L; // Don't allow date to change - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, - MYSQL_TIMESTAMP_DATE, 1); - error= 1; - } - else - tmp= day + month*32 + (tmp/10000)*16*32; - } - else if (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) - { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - 0, MYSQL_TIMESTAMP_DATE); - error= 1; - } - } - int3store(ptr, tmp); + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED,nr,MYSQL_TIMESTAMP_DATE, 1); + + int3store(ptr,tmp); return error; } @@ -5568,7 +5537,7 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) int error; ulonglong tmp= 0; enum enum_mysql_timestamp_type func_res; - + func_res= str_to_datetime(from, len, &time_tmp, (TIME_FUZZY_DATE | (table->in_use->variables.sql_mode & @@ -5581,7 +5550,7 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; // Fix if invalid zero date if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_DATETIME, 1); @@ -5618,21 +5587,25 @@ int Field_datetime::store(longlong nr) TIME not_used; int error; longlong initial_nr= nr; - - nr= number_to_datetime(nr, ¬_used, 1, &error); - if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, initial_nr, - MYSQL_TIMESTAMP_DATETIME, 1); - else if (nr == 0 && table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) + nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | + MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), &error); + + if (nr < 0) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - initial_nr, MYSQL_TIMESTAMP_DATE, 1); - error= 1; + nr= 0; + error= 2; } + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED, initial_nr, + MYSQL_TIMESTAMP_DATETIME, 1); + #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 0dc82666f52..fc7347ef9af 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -322,7 +322,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) +{ + 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, + 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 int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); @@ -349,6 +376,8 @@ static void do_cut_string(Copy_field *copy) } + + static void do_expand_string(Copy_field *copy) { CHARSET_INFO *cs= copy->from_field->charset(); @@ -550,7 +579,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) do_varstring1 : do_varstring2); } 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) return do_expand_string; } diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 856a053db9e..ae6952d4e5b 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -26,7 +26,7 @@ /* Blackhole storage engine handlerton */ -static handlerton myisam_hton= { +static handlerton blackhole_hton= { "BLACKHOLE", 0, /* slot */ 0, /* savepoint size. */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c3882436149..59d05368779 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -709,8 +709,8 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, blob_ptr= (char*)""; } - DBUG_PRINT("value", ("set blob ptr=%x len=%u", - (unsigned)blob_ptr, blob_len)); + DBUG_PRINT("value", ("set blob ptr=%p len=%u", + blob_ptr, blob_len)); DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26)); if (set_blob_value) diff --git a/sql/hostname.cc b/sql/hostname.cc index 39223556024..12b69a97859 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -130,15 +130,23 @@ void reset_host_errors(struct in_addr *in) VOID(pthread_mutex_unlock(&hostname_cache->lock)); } +/* Deal with systems that don't defined INADDR_LOOPBACK */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001UL +#endif my_string ip_to_hostname(struct in_addr *in, uint *errors) { uint i; host_entry *entry; DBUG_ENTER("ip_to_hostname"); + *errors=0; + + /* We always treat the loopback address as "localhost". */ + if (in->s_addr == INADDR_LOOPBACK) + return (char *)my_localhost; /* Check first if we have name in cache */ - *errors=0; if (!(specialflag & SPECIAL_NO_HOST_CACHE)) { VOID(pthread_mutex_lock(&hostname_cache->lock)); diff --git a/sql/item.cc b/sql/item.cc index 593708688f1..604f2f6dd2c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3328,7 +3328,12 @@ void Item::make_field(Send_field *tmp_field) void Item_empty_string::make_field(Send_field *tmp_field) { - init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); + enum_field_types type= FIELD_TYPE_VAR_STRING; + if (max_length >= 16777216) + type= FIELD_TYPE_LONG_BLOB; + else if (max_length >= 65536) + type= FIELD_TYPE_MEDIUM_BLOB; + init_make_field(tmp_field, type); } diff --git a/sql/item_func.cc b/sql/item_func.cc index c3bdb11418f..53895cc7331 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4231,14 +4231,15 @@ Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, bool Item_func_get_system_var::fix_fields(THD *thd, Item **ref) { - Item *item= var->item(thd, var_type, &component); + Item *item; DBUG_ENTER("Item_func_get_system_var::fix_fields"); + /* Evaluate the system variable and substitute the result (a basic constant) instead of this item. If the variable can not be evaluated, the error is reported in sys_var::item(). */ - if (item == 0) + if (!(item= var->item(thd, var_type, &component))) DBUG_RETURN(1); // Impossible item->set_name(name, 0, system_charset_info); // don't allocate a new name thd->change_item_tree(ref, item); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6d519c73b13..eb37609c28e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -335,19 +335,20 @@ null: 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)) return; 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; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } /* @@ -378,9 +379,6 @@ String *Item_func_des_encrypt::val_str(String *str) if (arg_count == 1) { - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - /* Protect against someone doing FLUSH DES_KEY_FILE */ VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number=des_default_key]; @@ -391,10 +389,6 @@ String *Item_func_des_encrypt::val_str(String *str) key_number= (uint) args[1]->val_int(); if (key_number > 9) goto error; - - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number]; VOID(pthread_mutex_unlock(&LOCK_des_key_file)); @@ -482,9 +476,6 @@ String *Item_func_des_decrypt::val_str(String *str) if (!(current_thd->master_access & SUPER_ACL) || key_number > 9) goto error; - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number]; VOID(pthread_mutex_unlock(&LOCK_des_key_file)); @@ -658,7 +649,7 @@ null: 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)) return; @@ -668,15 +659,16 @@ void Item_func_concat_ws::fix_length_and_dec() it is done on parser level in sql_yacc.yy 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++) - 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; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } @@ -855,18 +847,19 @@ null: 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); if (diff > 0 && args[1]->max_length) { // Calculate of maxreplaces - uint max_substrs= max_length/args[1]->max_length; - max_length+= max_substrs * (uint) diff; + ulonglong max_substrs= max_result_length/args[1]->max_length; + 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; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV)) return; @@ -914,18 +907,22 @@ null: void Item_func_insert::fix_length_and_dec() { Item *cargs[2]; + ulonglong max_result_length; + cargs[0]= args[0]; cargs[1]= args[3]; if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) return; args[0]= cargs[0]; args[3]= cargs[1]; - max_length=args[0]->max_length+args[3]->max_length; - if (max_length > MAX_BLOB_WIDTH) + max_result_length= ((ulonglong) args[0]->max_length+ + (ulonglong) args[3]->max_length); + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } @@ -2001,17 +1998,19 @@ void Item_func_repeat::fix_length_and_dec() collation.set(args[0]->collation); if (args[1]->const_item()) { - max_length=(long) (args[0]->max_length * args[1]->val_int()); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong max_result_length= ((ulonglong) args[0]->max_length * + args[1]->val_int()); + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } @@ -2066,6 +2065,7 @@ err: void Item_func_rpad::fix_length_and_dec() { Item *cargs[2]; + cargs[0]= args[0]; cargs[1]= args[2]; if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) @@ -2074,18 +2074,20 @@ void Item_func_rpad::fix_length_and_dec() args[2]= cargs[1]; if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; - max_length=max(args[0]->max_length,length); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong length= ((ulonglong) args[1]->val_int() * + collation.collation->mbmaxlen); + length= max((ulonglong) args[0]->max_length, length); + if (length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } @@ -2160,18 +2162,20 @@ void Item_func_lpad::fix_length_and_dec() if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; - max_length=max(args[0]->max_length,length); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong length= ((ulonglong) args[1]->val_int() * + collation.collation->mbmaxlen); + length= max((ulonglong) args[0]->max_length, length); + if (length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cac9613f1ad..aa377d0bdd8 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1555,7 +1555,7 @@ void Item_func_date_format::fix_length_and_dec() { fixed_length=0; /* 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); } maybe_null=1; // If wrong date @@ -2524,7 +2524,7 @@ void Item_func_add_time::print(String *str) } args[0]->print(str); str->append(','); - args[0]->print(str); + args[1]->print(str); str->append(')'); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 9b30989278e..29f1160466e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000-2004 MySQL AB - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -2775,6 +2775,16 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, */ 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); String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 933b2f8efad..1cc1aa836a8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -806,9 +806,7 @@ extern char *des_key_file; extern struct st_des_keyschedule des_keyschedule[10]; extern uint des_default_key; extern pthread_mutex_t LOCK_des_key_file; -void init_des_key_file(); bool load_des_key_file(const char *file_name); -void free_des_key_file(); #endif /* HAVE_OPENSSL */ /* sql_do.cc */ @@ -1173,8 +1171,11 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, - LOCK_global_system_variables, LOCK_user_conn, + LOCK_global_system_variables, LOCK_user_conn, LOCK_bytes_sent, LOCK_bytes_received; +#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 pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 412d6175e10..e4a44b41317 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -448,6 +448,9 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, 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; pthread_cond_t COND_refresh,COND_thread_count; pthread_t signal_thread; @@ -676,7 +679,11 @@ static void close_connections(void) end_thr_alarm(0); // Abort old alarms. 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; (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list @@ -686,13 +693,7 @@ static void close_connections(void) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", tmp->thread_id)); - /* - Re: bug 7403 - close_connection will be called mulitple times - 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); + tmp->killed= THD::KILL_CONNECTION; if (tmp->mysys_var) { tmp->mysys_var->abort=1; @@ -709,9 +710,13 @@ static void close_connections(void) (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list 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 (;;) { @@ -726,8 +731,9 @@ static void close_connections(void) #ifndef __bsdi__ // Bug in BSDI kernel if (tmp->vio_ok()) { - sql_print_error(ER(ER_FORCING_CLOSE),my_progname, - tmp->thread_id,tmp->user ? tmp->user : ""); + if (global_system_variables.log_warnings) + sql_print_warning(ER(ER_FORCING_CLOSE),my_progname, + tmp->thread_id,tmp->user ? tmp->user : ""); close_connection(tmp,0,0); } #endif @@ -1040,7 +1046,6 @@ void clean_up(bool print_message) #ifdef HAVE_OPENSSL if (ssl_acceptor_fd) my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); - free_des_key_file(); #endif /* HAVE_OPENSSL */ #ifdef USE_REGEX regex_end(); @@ -1112,6 +1117,9 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_received); (void) pthread_mutex_destroy(&LOCK_user_conn); +#ifdef HAVE_OPENSSL + (void) pthread_mutex_destroy(&LOCK_des_key_file); +#endif #ifdef HAVE_REPLICATION (void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status); @@ -2615,6 +2623,9 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_read_lock, 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_slave, NULL); (void) my_rwlock_init(&LOCK_grant, NULL); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 58af959888e..3a7defebddd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -779,29 +779,19 @@ static int check_connection(THD *thd) return (ER_OUT_OF_RESOURCES); thd->host_or_ip= thd->ip; vio_in_addr(net->vio,&thd->remote.sin_addr); -#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread) - /* Fast local hostname resolve for Win32 */ - if (!strcmp(thd->ip,"127.0.0.1")) + if (!(specialflag & SPECIAL_NO_RESOLVE)) { - thd->host= (char*) my_localhost; - thd->host_or_ip= my_localhost; - } - else -#endif - { - if (!(specialflag & SPECIAL_NO_RESOLVE)) + vio_in_addr(net->vio,&thd->remote.sin_addr); + thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); + /* Cut very long hostnames to avoid possible overflows */ + if (thd->host) { - vio_in_addr(net->vio,&thd->remote.sin_addr); - thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); - /* Cut very long hostnames to avoid possible overflows */ - if (thd->host) - { - thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0; - thd->host_or_ip= thd->host; - } - if (connect_errors > max_connect_errors) - return(ER_HOST_IS_BLOCKED); + if (thd->host != my_localhost) + thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0; + thd->host_or_ip= thd->host; } + if (connect_errors > max_connect_errors) + return(ER_HOST_IS_BLOCKED); } DBUG_PRINT("info",("Host: %s ip: %s", thd->host ? thd->host : "unknown host", diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9ec2cff71a1..87366fe157d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -319,7 +319,7 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len) return; float4get(data,*pos); #else - data= *(float*) *pos; + floatget(data, *pos); #endif param->set_double((double) data); *pos+= 4; @@ -333,7 +333,7 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len) return; float8get(data,*pos); #else - data= *(double*) *pos; + doubleget(data, *pos); #endif param->set_double((double) data); *pos+= 8; @@ -601,10 +601,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, Item_param **begin= stmt->param_array; Item_param **end= begin + stmt->param_count; uint32 length= 0; - String str; const String *res; - DBUG_ENTER("insert_params_withlog"); if (query->copy(stmt->query, stmt->query_length, default_charset_info)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 45460d0da01..e994b5ff26b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1203,14 +1203,18 @@ JOIN::exec() else { error= (int) result->send_eof(); - send_records=1; + send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : + thd->sent_row_count); } } else + { error=(int) result->send_eof(); + send_records= 0; + } } - /* Single select (without union and limit) always returns 1 row */ - thd->limit_found_rows= 1; + /* Single select (without union) always returns 0 or 1 row */ + thd->limit_found_rows= send_records; thd->examined_row_count= 0; DBUG_VOID_RETURN; } @@ -5212,6 +5216,7 @@ static void add_not_null_conds(JOIN *join) if (tab->ref.null_rejecting & (1 << keypart)) { Item *item= tab->ref.items[keypart]; + Item *notnull; DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *not_null_item= (Item_field*)item; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; @@ -5222,7 +5227,6 @@ static void add_not_null_conds(JOIN *join) */ if (!referred_tab || referred_tab->join != join) continue; - Item *notnull; if (!(notnull= new Item_func_isnotnull(not_null_item))) DBUG_VOID_RETURN; /* |