summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc158
-rw-r--r--sql/field.h8
-rw-r--r--sql/item.cc13
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_func.cc1
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/item_timefunc.cc58
-rw-r--r--sql/item_timefunc.h29
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/protocol.cc34
-rw-r--r--sql/set_var.cc4
-rw-r--r--sql/sql_analyse.cc50
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_repl.cc3
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_show.cc1
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());