diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 158 | ||||
-rw-r--r-- | sql/field.h | 8 | ||||
-rw-r--r-- | sql/item.cc | 13 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 1 | ||||
-rw-r--r-- | sql/item_func.h | 5 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 58 | ||||
-rw-r--r-- | sql/item_timefunc.h | 29 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/protocol.cc | 34 | ||||
-rw-r--r-- | sql/set_var.cc | 4 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 50 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_error.cc | 2 | ||||
-rw-r--r-- | sql/sql_repl.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 10 | ||||
-rw-r--r-- | sql/sql_show.cc | 1 |
17 files changed, 214 insertions, 169 deletions
diff --git a/sql/field.cc b/sql/field.cc index a412c2cb146..cceaff62417 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2585,10 +2585,10 @@ void Field_double::sql_type(String &res) const Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg) - :Field_num(ptr_arg, len_arg, (uchar*) 0,0, - unireg_check_arg, field_name_arg, table_arg, - 0, 1, 1) + struct st_table *table_arg, + CHARSET_INFO *cs) + :Field_str(ptr_arg, 19, (uchar*) 0,0, + unireg_check_arg, field_name_arg, table_arg, cs) { if (table && !table->timestamp_field) { @@ -2613,35 +2613,6 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) return 0; } -void Field_timestamp::fill_and_store(char *from,uint len) -{ - uint res_length; - if (len <= field_length) - res_length=field_length; - else if (len <= 12) - res_length=12; /* purecov: inspected */ - else if (len <= 14) - res_length=14; /* purecov: inspected */ - else - res_length=(len+1)/2*2; // must be even - if (res_length != len) - { - bmove_upp(from+res_length,from+len,len); - bfill(from,res_length-len,'0'); - len=res_length; - } - long tmp=(long) str_to_timestamp(from,len); -#ifdef WORDS_BIGENDIAN - if (table->db_low_byte_first) - { - int4store(ptr,tmp); - } - else -#endif - longstore(ptr,tmp); -} - - int Field_timestamp::store(double nr) { int error= 0; @@ -2752,44 +2723,34 @@ longlong Field_timestamp::val_int(void) time_arg=(time_t) temp; localtime_r(&time_arg,&tm_tmp); l_time=&tm_tmp; - res=(longlong) 0; - for (pos=len=0; len+1 < (uint) field_length ; len+=2,pos++) - { - bool year_flag=0; - switch (dayord.pos[pos]) { - case 0: part_time=l_time->tm_year % 100; year_flag=1 ; break; - case 1: part_time=l_time->tm_mon+1; break; - case 2: part_time=l_time->tm_mday; break; - case 3: part_time=l_time->tm_hour; break; - case 4: part_time=l_time->tm_min; break; - case 5: part_time=l_time->tm_sec; break; - default: part_time=0; break; /* purecov: deadcode */ - } - if (year_flag && (field_length == 8 || field_length == 14)) - { - res=res*(longlong) 10000+(part_time+ - ((part_time < YY_PART_YEAR) ? 2000 : 1900)); - len+=2; - } - else - res=res*(longlong) 100+part_time; - } - return (longlong) res; + + part_time= l_time->tm_year % 100; + res= ((longlong) (part_time+ ((part_time < YY_PART_YEAR) ? 2000 : 1900))* + LL(10000000000)); + part_time= l_time->tm_mon+1; + res+= (longlong) part_time * LL(100000000); + part_time=l_time->tm_mday; + res+= (longlong) ((long) part_time * 1000000L); + part_time=l_time->tm_hour; + res+= (longlong) (part_time * 10000L); + part_time=l_time->tm_min; + res+= (longlong) (part_time * 100); + part_time=l_time->tm_sec; + return res+part_time; } String *Field_timestamp::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { - uint pos; - int part_time; - uint32 temp; + uint32 temp, temp2; time_t time_arg; struct tm *l_time; struct tm tm_tmp; val_buffer->alloc(field_length+1); char *to=(char*) val_buffer->ptr(),*end=to+field_length; + val_buffer->length(field_length); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -2800,41 +2761,53 @@ String *Field_timestamp::val_str(String *val_buffer, if (temp == 0L) { /* Zero time is "000000" */ - VOID(strfill(to,field_length,'0')); - val_buffer->length(field_length); + strmov(to, "0000-00-00 00:00:00"); return val_buffer; } time_arg=(time_t) temp; localtime_r(&time_arg,&tm_tmp); l_time=&tm_tmp; - for (pos=0; to < end ; pos++) - { - bool year_flag=0; - switch (dayord.pos[pos]) { - case 0: part_time=l_time->tm_year % 100; year_flag=1; break; - case 1: part_time=l_time->tm_mon+1; break; - case 2: part_time=l_time->tm_mday; break; - case 3: part_time=l_time->tm_hour; break; - case 4: part_time=l_time->tm_min; break; - case 5: part_time=l_time->tm_sec; break; - default: part_time=0; break; /* purecov: deadcode */ - } - if (year_flag && (field_length == 8 || field_length == 14)) - { - if (part_time < YY_PART_YEAR) - { - *to++='2'; *to++='0'; /* purecov: inspected */ - } - else - { - *to++='1'; *to++='9'; - } - } - *to++=(char) ('0'+((uint) part_time/10)); - *to++=(char) ('0'+((uint) part_time % 10)); - } - *to=0; // Safeguard - val_buffer->length((uint) (to-val_buffer->ptr())); + + temp= l_time->tm_year % 100; + if (temp < YY_PART_YEAR) + { + *to++= '2'; + *to++= '0'; + } + else + { + *to++= '1'; + *to++= '9'; + } + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to++= '-'; + temp=l_time->tm_mon+1; + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to++= '-'; + temp=l_time->tm_mday; + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to++= ' '; + temp=l_time->tm_hour; + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to++= ':'; + temp=l_time->tm_min; + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to++= ':'; + temp=l_time->tm_sec; + temp2=temp/10; temp=temp-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (temp)); + *to= 0; return val_buffer; } @@ -2929,10 +2902,7 @@ void Field_timestamp::sort_string(char *to,uint length __attribute__((unused))) void Field_timestamp::sql_type(String &res) const { - ulong length= my_sprintf((char*) res.ptr(), - ((char*) res.ptr(),"timestamp(%d)", - (int) field_length)); - res.length(length); + res.set("timestamp", 9, default_charset_info); } @@ -5310,7 +5280,7 @@ Field *make_field(char *ptr, uint32 field_length, f_is_dec(pack_flag) == 0); case FIELD_TYPE_TIMESTAMP: return new Field_timestamp(ptr,field_length, - unireg_check, field_name, table); + unireg_check, field_name, table, field_charset); case FIELD_TYPE_YEAR: return new Field_year(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table); diff --git a/sql/field.h b/sql/field.h index 49f75a3d471..6817a6e386f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -561,14 +561,15 @@ public: }; -class Field_timestamp :public Field_num { +class Field_timestamp :public Field_str { public: Field_timestamp(char *ptr_arg, uint32 len_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg); - enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; } + struct st_table *table_arg, + CHARSET_INFO *cs); enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } + enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); @@ -598,7 +599,6 @@ public: longget(tmp,ptr); return tmp; } - void fill_and_store(char *from,uint len); bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); }; diff --git a/sql/item.cc b/sql/item.cc index 2d90db0cc5d..bfc900b61e1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -873,8 +873,15 @@ bool Item::send(Protocol *protocol, String *buffer) switch ((type=field_type())) { default: - DBUG_ASSERT(1); - /* If not assert on, send as a string */ + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: { @@ -899,6 +906,7 @@ bool Item::send(Protocol *protocol, String *buffer) result= protocol->store_short(nr); break; } + case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: { longlong nr; @@ -925,6 +933,7 @@ bool Item::send(Protocol *protocol, String *buffer) } case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIMESTAMP: { TIME tm; get_date(&tm, 1); diff --git a/sql/item.h b/sql/item.h index 63890ea3f64..782d6198470 100644 --- a/sql/item.h +++ b/sql/item.h @@ -565,6 +565,7 @@ public: class Item_copy_string :public Item { + enum enum_field_types cached_field_type; public: Item *item; Item_copy_string(Item *i) :item(i) @@ -573,11 +574,12 @@ public: decimals=item->decimals; max_length=item->max_length; name=item->name; + cached_field_type= item->field_type(); } ~Item_copy_string() { delete item; } enum Type type() const { return COPY_STR_ITEM; } enum Item_result result_type () const { return STRING_RESULT; } - enum_field_types field_type() const { return MYSQL_TYPE_STRING; } + enum_field_types field_type() const { return cached_field_type; } double val() { return null_value ? 0.0 : my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),NULL); } longlong val_int() diff --git a/sql/item_func.cc b/sql/item_func.cc index 1ce5b038f3b..c0b6a872831 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1945,6 +1945,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */ if (Item_func::fix_fields(thd, tables, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) return 1; diff --git a/sql/item_func.h b/sql/item_func.h index 5de493a5341..36d6dcbe002 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -940,6 +940,11 @@ public: void fix_length_and_dec(); void print(String *str); enum Item_result result_type() const; + /* + We must always return variables as strings to guard against selects of type + select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b) + */ + enum_field_types field_type() const { return MYSQL_TYPE_STRING; } const char *func_name() const { return "get_user_var"; } bool const_item() const { return const_var_flag; } table_map used_tables() const diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 7e2e8f7cfbd..7b58fbe8404 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -295,8 +295,8 @@ longlong Item_func_time_to_sec::val_int() /* -** Convert a string to a interval value -** To make code easy, allow interval objects without separators. + Convert a string to a interval value + To make code easy, allow interval objects without separators. */ static bool get_interval_value(Item *args,interval_type int_type, @@ -516,12 +516,14 @@ void Item_func_curtime::fix_length_and_dec() (int) start->tm_sec); } + String *Item_func_now::val_str(String *str) { str_value.set(buff,buff_length,thd_charset()); return &str_value; } + void Item_func_now::fix_length_and_dec() { struct tm tm_tmp,*start; @@ -540,13 +542,14 @@ void Item_func_now::fix_length_and_dec() (ulong) (((uint) start->tm_min)*100L+ (uint) start->tm_sec))); - buff_length= (uint) cs->snprintf(cs,buff, sizeof(buff),"%04d-%02d-%02d %02d:%02d:%02d", - ((int) (start->tm_year+1900)) % 10000, - (int) start->tm_mon+1, - (int) start->tm_mday, - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); + buff_length= (uint) cs->snprintf(cs,buff, sizeof(buff), + "%04d-%02d-%02d %02d:%02d:%02d", + ((int) (start->tm_year+1900)) % 10000, + (int) start->tm_mon+1, + (int) start->tm_mday, + (int) start->tm_hour, + (int) start->tm_min, + (int) start->tm_sec); /* For getdate */ ltime.year= start->tm_year+1900; ltime.month= start->tm_mon+1; @@ -995,7 +998,42 @@ bool Item_func_from_unixtime::get_date(TIME *ltime, return 0; } - /* Here arg[1] is a Item_interval object */ + +void Item_date_add_interval::fix_length_and_dec() +{ + enum_field_types arg0_field_type; + set_charset(thd_charset()); + maybe_null=1; + max_length=19*thd_charset()->mbmaxlen; + value.alloc(32); + + /* + The field type for the result of an Item_date function is defined as + follows: + + - If first arg is a MYSQL_TYPE_DATETIME result is MYSQL_TYPE_DATETIME + - If first arg is a MYSQL_TYPE_DATE and the interval type uses hours, + minutes or seconds then type is MYSQL_TYPE_DATETIME. + - Otherwise the result is MYSQL_TYPE_STRING + (This is because you can't know if the string contains a DATE, TIME or + DATETIME argument) + */ + cached_field_type= MYSQL_TYPE_STRING; + arg0_field_type= args[0]->field_type(); + if (arg0_field_type == MYSQL_TYPE_DATETIME || + arg0_field_type == MYSQL_TYPE_TIMESTAMP) + cached_field_type= MYSQL_TYPE_DATETIME; + else if (arg0_field_type == MYSQL_TYPE_DATE) + { + if (int_type <= INTERVAL_MONTH || int_type == INTERVAL_YEAR_MONTH) + cached_field_type= arg0_field_type; + else + cached_field_type= MYSQL_TYPE_DATETIME; + } +} + + +/* Here arg[1] is a Item_interval object */ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index b4a0b517090..aa075e1a91d 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -443,7 +443,6 @@ class Item_func_from_unixtime :public Item_date_func decimals=0; max_length=19*thd_charset()->mbmaxlen; } -// enum Item_result result_type () const { return STRING_RESULT; } bool get_date(TIME *res,bool fuzzy_date); }; @@ -470,32 +469,34 @@ public: } }; +/* + The following must be sorted so that simple intervals comes first. + (get_interval_value() depends on this) +*/ + +enum interval_type +{ + INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, + INTERVAL_SECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, + INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, + INTERVAL_MINUTE_SECOND +}; -enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY, - INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, - INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, - INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, - INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, - INTERVAL_MINUTE_SECOND}; class Item_date_add_interval :public Item_date_func { const interval_type int_type; String value; const bool date_sub_interval; + enum_field_types cached_field_type; public: Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg) :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} String *val_str(String *); const char *func_name() const { return "date_add_interval"; } - void fix_length_and_dec() - { - set_charset(thd_charset()); - maybe_null=1; - max_length=19*thd_charset()->mbmaxlen; - value.alloc(32); - } + void fix_length_and_dec(); + enum_field_types field_type() const { return cached_field_type; } double val() { return (double) val_int(); } longlong val_int(); bool get_date(TIME *res,bool fuzzy_date); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d53ed0f8594..a805cde966f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1537,7 +1537,7 @@ static void start_signal_handler(void) (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR); - pthread_attr_setstacksize(&thr_attr,32768); + pthread_attr_setstacksize(&thr_attr, 129*1024); #endif (void) pthread_mutex_lock(&LOCK_thread_count); diff --git a/sql/protocol.cc b/sql/protocol.cc index a7540f39f9e..88bfe6831c4 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -577,18 +577,19 @@ bool Protocol::store(I_List<i_string>* str_list) { char buf[256]; String tmp(buf, sizeof(buf), default_charset_info); - tmp.length(0); + uint32 len; I_List_iterator<i_string> it(*str_list); i_string* s; + tmp.length(0); while ((s=it++)) { - if (tmp.length()) - tmp.append(','); tmp.append(s->ptr); + tmp.append(','); } - - return store((char*) tmp.ptr(), tmp.length()); + if ((len= tmp.length())) + len--; // Remove last ',' + return store((char*) tmp.ptr(), len); } @@ -623,8 +624,9 @@ bool Protocol_simple::store(const char *from, uint length) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos] == MYSQL_TYPE_STRING || - field_types[field_pos] == MYSQL_TYPE_VAR_STRING); + field_types[field_pos] == MYSQL_TYPE_DECIMAL || + (field_types[field_pos] >= MYSQL_TYPE_ENUM && + field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); field_pos++; #endif if (convert) @@ -702,11 +704,11 @@ bool Protocol_simple::store(double from, uint32 decimals, String *buffer) bool Protocol_simple::store(Field *field) { + if (field->is_null()) + return store_null(); #ifndef DEBUG_OFF field_pos++; #endif - if (field->is_null()) - return store_null(); char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff),default_charset_info); field->val_str(&tmp,&tmp); @@ -720,7 +722,9 @@ bool Protocol_simple::store(TIME *tm) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_DATETIME); + field_types[field_pos] == MYSQL_TYPE_DATETIME || + field_types[field_pos] == MYSQL_TYPE_TIMESTAMP); + field_pos++; #endif char buff[40]; uint length; @@ -759,7 +763,7 @@ bool Protocol_simple::store_time(TIME *tm) #endif char buff[40]; uint length; - length= my_sprintf(buff,(buff, "%s%ld:%02d:%02d", + length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", tm->neg ? "-" : "", (long) tm->day*3600L+(long) tm->hour, (int) tm->minute, @@ -796,8 +800,9 @@ bool Protocol_prep::store(const char *from,uint length) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos] == MYSQL_TYPE_STRING || - field_types[field_pos] == MYSQL_TYPE_VAR_STRING); + field_types[field_pos] == MYSQL_TYPE_DECIMAL || + (field_types[field_pos] >= MYSQL_TYPE_ENUM && + field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); #endif field_pos++; if (convert) @@ -922,7 +927,8 @@ bool Protocol_prep::store(TIME *tm) #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_DATETIME || - field_types[field_pos] == MYSQL_TYPE_DATE); + field_types[field_pos] == MYSQL_TYPE_DATE || + field_types[field_pos] == MYSQL_TYPE_TIMESTAMP); #endif char buff[12],*pos; uint length; diff --git a/sql/set_var.cc b/sql/set_var.cc index 691add191b2..3404df1c56a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -992,8 +992,12 @@ bool sys_var_thd_conv_charset::update(THD *thd, set_var *var) if (var->type == OPT_GLOBAL) global_system_variables.convert_set= var->save_result.convert; else + { thd->lex.convert_set= thd->variables.convert_set= var->save_result.convert; + thd->protocol_simple.init(thd); + thd->protocol_prep.init(thd); + } return 0; } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index ecd9f635060..acd67ad66d7 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -310,30 +310,7 @@ void field_str::add() was_maybe_zerofill = num_info.maybe_zerofill; } - if (room_in_tree) - { - if (res != &s) - s.copy(*res); - if (!tree_search(&tree, (void*) &s, tree.custom_arg)) // If not in tree - { - s.copy(); // slow, when SAFE_MALLOC is in use - if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg)) - { - room_in_tree = 0; // Remove tree, out of RAM ? - delete_tree(&tree); - } - else - { - bzero((char*) &s, sizeof(s)); // Let tree handle free of this - if ((treemem += length) > pc->max_treemem) - { - room_in_tree = 0; // Remove tree, too big tree - delete_tree(&tree); - } - } - } - } - + /* Update min and max arguments */ if (!found) { found = 1; @@ -364,6 +341,31 @@ void field_str::add() max_arg.copy(*res); } } + + if (room_in_tree) + { + if (res != &s) + s.copy(*res); + if (!tree_search(&tree, (void*) &s, tree.custom_arg)) // If not in tree + { + s.copy(); // slow, when SAFE_MALLOC is in use + if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg)) + { + room_in_tree = 0; // Remove tree, out of RAM ? + delete_tree(&tree); + } + else + { + bzero((char*) &s, sizeof(s)); // Let tree handle free of this + if ((treemem += length) > pc->max_treemem) + { + room_in_tree = 0; // Remove tree, too big tree + delete_tree(&tree); + } + } + } + } + if ((num_info.zerofill && (max_length != min_length)) || (was_zero_fill && (max_length != min_length))) can_be_still_num = 0; // zerofilled numbers must be of same length diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dedf496db3c..82dabc0e9da 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -520,6 +520,7 @@ bool select_send::send_data(List<Item> &items) if (unit->offset_limit_cnt) { // using limit offset,count unit->offset_limit_cnt--; + return 0; } List_iterator_fast<Item> li(items); diff --git a/sql/sql_error.cc b/sql/sql_error.cc index b208015a2bb..c9684855b86 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -158,7 +158,7 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) DBUG_ENTER("mysqld_show_warnings"); field_list.push_back(new Item_empty_string("Level", 7)); - field_list.push_back(new Item_int("Code",0,4)); + field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG)); field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE)); if (thd->protocol->send_fields(&field_list,1)) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 63cd192e539..375a7478377 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1043,7 +1043,6 @@ int show_binlog_info(THD* thd) DBUG_RETURN(-1); protocol->prepare_for_resend(); - if (mysql_bin_log.is_open()) { LOG_INFO li; @@ -1103,8 +1102,8 @@ int show_binlogs(THD* thd) /* The file ends with EOF or empty line */ while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1) { + protocol->prepare_for_resend(); int dir_len = dirname_length(fname); - packet->length(0); /* The -1 is for removing newline from fname */ protocol->store(fname + dir_len, length-1-dir_len); if (protocol->write()) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 683cc0925b6..d1f03a10be1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3047,6 +3047,7 @@ join_free(JOIN *join, bool full) if (join->tables > join->const_tables) // Test for not-const tables free_io_cache(join->table[join->const_tables]); if (join->select_lex->dependent && !full) + { for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) { if (tab->table) @@ -3061,6 +3062,7 @@ join_free(JOIN *join, bool full) tab->table->file->index_end(); } } + } else { for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) @@ -3078,6 +3080,11 @@ join_free(JOIN *join, bool full) /* Don't free index if we are using read_record */ if (!tab->read_record.table) tab->table->file->index_end(); + /* + We need to reset this for next select + (Tested in part_of_refkey) + */ + tab->table->reginfo.join_tab= 0; } end_read_record(&tab->read_record); } @@ -7487,9 +7494,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), default_charset_info)); - Item *empty= new Item_empty_string("",0); for (uint i=0 ; i < 7; i++) - item_list.push_back(empty); + item_list.push_back(item_null); item_list.push_back(new Item_string(message,strlen(message), default_charset_info)); if (result->send_data(item_list)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2826b44692e..f60cba54e84 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -802,6 +802,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(1); protocol->prepare_for_resend(); protocol->store(table->table_name); + buffer.length(0); if (store_create_info(thd, table, &buffer)) DBUG_RETURN(-1); protocol->store(buffer.ptr(), buffer.length()); |