diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 14 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 11 | ||||
-rw-r--r-- | sql/key.cc | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | sql/protocol.cc | 30 | ||||
-rw-r--r-- | sql/sql_db.cc | 8 | ||||
-rw-r--r-- | sql/sql_lex.cc | 9 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 29 | ||||
-rw-r--r-- | sql/sql_select.h | 3 | ||||
-rw-r--r-- | sql/sql_string.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 |
15 files changed, 85 insertions, 45 deletions
diff --git a/sql/item.h b/sql/item.h index cc4e9a5909b..7b31f03f6ac 100644 --- a/sql/item.h +++ b/sql/item.h @@ -487,7 +487,7 @@ public: enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const { return ref && (*ref)->eq(item, binary_cmp); } - ~Item_ref() { if (ref && (*ref) != this) delete *ref; } + ~Item_ref() { if (ref && (*ref) && (*ref) != this) delete *ref; } double val() { double tmp=(*ref)->val_result(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 40640ccee9c..301e5b4454f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -298,12 +298,22 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, return 1; cache->setup(args[0]); if (cache->cols() == 1) - cache->set_used_tables(RAND_TABLE_BIT); + { + if (args[0]->used_tables()) + cache->set_used_tables(RAND_TABLE_BIT); + else + cache->set_used_tables(0); + } else { uint n= cache->cols(); for (uint i= 0; i < n; i++) - ((Item_cache *)cache->el(i))->set_used_tables(RAND_TABLE_BIT); + { + if (args[0]->el(i)->used_tables()) + ((Item_cache *)cache->el(i))->set_used_tables(RAND_TABLE_BIT); + else + ((Item_cache *)cache->el(i))->set_used_tables(0); + } } if (args[1]->fix_fields(thd, tables, args)) return 1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 0361fd0db65..8fb97dc2873 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -136,7 +136,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } else if ((*arg)->coercibility < coercibility) { - if (strcmp(charset()->csname,(*arg)->charset()->csname)) + if (!my_charset_same(charset(),(*arg)->charset())) { set_charset(&my_charset_bin); coercibility= COER_NOCOLL; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f049c13c974..80d85e565e7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2216,7 +2216,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, return 1; } - if (strcmp(args[0]->charset()->csname,set_collation->csname)) + if (!my_charset_same(args[0]->charset(),set_collation)) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), set_collation->name,args[0]->charset()->csname); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 79416204972..76451680b59 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -88,7 +88,14 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (have_to_be_excluded) engine->exclude(); substitution= 0; - return (*ref)->fix_fields(thd, tables, ref); + int ret= (*ref)->fix_fields(thd, tables, ref); + // We can't substitute aggregate functions (like (SELECT (max(i))) + if ((*ref)->with_sum_func) + { + my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); + return 1; + } + return ret; } char const *save_where= thd->where; @@ -487,6 +494,8 @@ void Item_in_subselect::single_value_transformer(THD *thd, setup_ref_array(thd, &sl->ref_pointer_array, 1 + sl->with_sum_func + sl->order_list.elements + sl->group_list.elements); + // To prevent crash on Item_ref_null_helper destruction in case of error + sl->ref_pointer_array[0]= 0; item= (*func)(expr, new Item_ref_null_helper(this, sl->ref_pointer_array, (char *)"<ref>", diff --git a/sql/key.cc b/sql/key.cc index 38ab596e213..feda9e156b3 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -67,7 +67,7 @@ int find_ref_key(TABLE *table,Field *field, uint *key_length) /* Copy a key from record to some buffer */ - /* if length == 0 then copy hole key */ + /* if length == 0 then copy whole key */ void key_copy(byte *key,TABLE *table,uint idx,uint key_length) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 50dabc14286..e01af4de543 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2082,8 +2082,9 @@ static int init_common_variables(const char *conf_file_name, int argc, #ifdef USE_REGEX regex_init(&my_charset_latin1); #endif - if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME))) + if (!(default_charset_info= get_charset_by_name(sys_charset.value, MYF(MY_WME)))) return 1; + system_charset_info= default_charset_info; charsets_list= list_charsets(MYF(MY_CS_COMPILED | MY_CS_CONFIG)); if (use_temp_pool && bitmap_init(&temp_pool,1024,1)) diff --git a/sql/protocol.cc b/sql/protocol.cc index 6bd5c4534e9..454b8bae625 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -719,7 +719,8 @@ bool Protocol_simple::store(const char *from, uint length) bool Protocol_simple::store_tiny(longlong from) { #ifndef DEBUG_OFF - DBUG_ASSERT(field_types == 0 || field_types[field_pos++] == MYSQL_TYPE_TINY); + DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY); + field_pos++; #endif char buff[20]; return net_store_data((char*) buff, @@ -731,7 +732,8 @@ bool Protocol_simple::store_short(longlong from) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_SHORT); + field_types[field_pos] == MYSQL_TYPE_SHORT); + field_pos++; #endif char buff[20]; return net_store_data((char*) buff, @@ -742,7 +744,10 @@ bool Protocol_simple::store_short(longlong from) bool Protocol_simple::store_long(longlong from) { #ifndef DEBUG_OFF - DBUG_ASSERT(field_types == 0 || field_types[field_pos++] == MYSQL_TYPE_LONG); + DBUG_ASSERT(field_types == 0 || + field_types[field_pos] == MYSQL_TYPE_INT24 || + field_types[field_pos] == MYSQL_TYPE_LONG); + field_pos++; #endif char buff[20]; return net_store_data((char*) buff, @@ -754,7 +759,8 @@ bool Protocol_simple::store_longlong(longlong from, bool unsigned_flag) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_LONGLONG); + field_types[field_pos] == MYSQL_TYPE_LONGLONG); + field_pos++; #endif char buff[22]; return net_store_data((char*) buff, @@ -768,7 +774,8 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_FLOAT); + field_types[field_pos] == MYSQL_TYPE_FLOAT); + field_pos++; #endif buffer->set((double) from, decimals, thd->variables.thd_charset); return net_store_data((char*) buffer->ptr(), buffer->length()); @@ -779,7 +786,8 @@ bool Protocol_simple::store(double from, uint32 decimals, String *buffer) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_DOUBLE); + field_types[field_pos] == MYSQL_TYPE_DOUBLE); + field_pos++; #endif buffer->set(from, decimals, thd->variables.thd_charset); return net_store_data((char*) buffer->ptr(), buffer->length()); @@ -827,7 +835,8 @@ bool Protocol_simple::store_date(TIME *tm) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_DATE); + field_types[field_pos] == MYSQL_TYPE_DATE); + field_pos++; #endif char buff[40]; uint length; @@ -843,7 +852,8 @@ bool Protocol_simple::store_time(TIME *tm) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || - field_types[field_pos++] == MYSQL_TYPE_TIME); + field_types[field_pos] == MYSQL_TYPE_TIME); + field_pos++; #endif char buff[40]; uint length; @@ -1033,7 +1043,7 @@ bool Protocol_prep::store(TIME *tm) uint length; field_pos++; pos= buff+1; - + int2store(pos, tm->year); pos[2]= (uchar) tm->month; pos[3]= (uchar) tm->day; @@ -1072,7 +1082,7 @@ bool Protocol_prep::store_time(TIME *tm) field_pos++; pos= buff+1; pos[0]= tm->neg ? 1 : 0; - int4store(pos+1, tm->day); + int4store(pos+1, tm->day); pos[5]= (uchar) tm->hour; pos[6]= (uchar) tm->minute; pos[7]= (uchar) tm->second; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 517438d9203..99763d717fe 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -108,7 +108,7 @@ static bool load_db_opt(const char *path, HA_CREATE_INFO *create) { char *pos= buf+nbytes-1; /* Remove end space and control characters */ - while (pos > buf && !my_isgraph(system_charset_info, pos[-1])) + while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1])) pos--; *pos=0; if ((pos= strchr(buf, '='))) @@ -414,8 +414,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, DBUG_PRINT("info",("Examining: %s", file->name)); /* Check if file is a raid directory */ - if (my_isdigit(system_charset_info,file->name[0]) && - my_isdigit(system_charset_info,file->name[1]) && + if (my_isdigit(&my_charset_latin1,file->name[0]) && + my_isdigit(&my_charset_latin1,file->name[1]) && !file->name[2] && !level) { char newpath[FN_REFLEN]; @@ -440,7 +440,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, continue; } strxmov(filePath,org_path,"/",file->name,NullS); - if (db && !my_strcasecmp(system_charset_info, + if (db && !my_strcasecmp(&my_charset_latin1, fn_ext(file->name), reg_ext)) { /* Drop the table nicely */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index cd0a653ba86..378aa380a3c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -209,6 +209,7 @@ static char *get_text(LEX *lex) { reg1 uchar c,sep; uint found_escape=0; + CHARSET_INFO *cs= lex->thd->variables.thd_charset; sep= yyGetLast(); // String should end with this //lex->tok_start=lex->ptr-1; // Remember ' @@ -217,8 +218,8 @@ static char *get_text(LEX *lex) c = yyGet(); #ifdef USE_MB int l; - if (use_mb(system_charset_info) && - (l = my_ismbchar(system_charset_info, + if (use_mb(cs) && + (l = my_ismbchar(cs, (const char *)lex->ptr-1, (const char *)lex->end_of_query))) { lex->ptr += l-1; @@ -262,8 +263,8 @@ static char *get_text(LEX *lex) { #ifdef USE_MB int l; - if (use_mb(system_charset_info) && - (l = my_ismbchar(system_charset_info, + if (use_mb(cs) && + (l = my_ismbchar(cs, (const char *)str, (const char *)end))) { while (l--) *to++ = *str++; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a3b8ccafc11..bdbec6bc76f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -912,7 +912,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); - while (length && (my_isspace(system_charset_info, buff[length-1]) || + while (length && (my_isspace(thd->charset(), buff[length-1]) || buff[length-1] == ';')) length--; buff[length]=0; @@ -1265,7 +1265,7 @@ restore_user: ulong length= thd->query_length-(ulong)(thd->lex.found_colon-thd->query); /* Remove garbage at start of query */ - while (my_isspace(system_charset_info, *packet) && length > 0) + while (my_isspace(thd->charset(), *packet) && length > 0) { packet++; length--; @@ -1539,14 +1539,14 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) { packet_length--; // Remove end null /* Remove garbage at start and end of query */ - while (my_isspace(system_charset_info,packet[0]) && packet_length > 0) + while (my_isspace(thd->charset(),packet[0]) && packet_length > 0) { packet++; packet_length--; } char *pos=packet+packet_length; // Point at end null while (packet_length > 0 && - (pos[-1] == ';' || my_isspace(system_charset_info,pos[-1]))) + (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1]))) { pos--; packet_length--; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bf3f9a94936..3e20f21f567 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1263,7 +1263,20 @@ JOIN::cleanup(THD *thd) select_lex->join= 0; if (tmp_join) - memcpy(this, tmp_join, sizeof(tmp_join)); + { + if (join_tab != tmp_join->join_tab) + { + JOIN_TAB *tab, *end; + for (tab= join_tab, end= tab+tables ; tab != end ; tab++) + { + delete tab->select; + delete tab->quick; + x_free(tab->cache.buff); + } + } + tmp_join->tmp_join= 0; + return tmp_join->cleanup(thd); + } lock=0; // It's faster to unlock later @@ -2753,19 +2766,15 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) { // Compare against constant - store_key_item *tmp=new store_key_item(thd, - keyinfo->key_part[i].field, - (char*)key_buff + - maybe_null, - maybe_null ? - (char*) key_buff : 0, - keyinfo->key_part[i].length, - keyuse->val); + store_key_item tmp(thd, keyinfo->key_part[i].field, + (char*)key_buff + maybe_null, + maybe_null ? (char*) key_buff : 0, + keyinfo->key_part[i].length, keyuse->val); if (thd->is_fatal_error) { return TRUE; } - tmp->copy(); + tmp.copy(); } else *ref_key++= get_store_key(thd, diff --git a/sql/sql_select.h b/sql/sql_select.h index c5411a8790b..ffc98548db4 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -174,7 +174,7 @@ class JOIN :public Sql_alloc Item_sum **sum_funcs; Procedure *procedure; Item *having; - Item *tmp_having; // To store Having when processed tenporary table + Item *tmp_having; // To store Having when processed temporary table uint select_options; select_result *result; TMP_TABLE_PARAM tmp_table_param; @@ -306,7 +306,6 @@ class store_key :public Sql_alloc { protected: Field *to_field; // Store data here - Field *key_field; // Copy of key field char *null_ptr; char err; public: diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 1a0366112f4..b6425003af3 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -28,6 +28,7 @@ #include <floatingpoint.h> #endif +CHARSET_INFO *system_charset_info= &my_charset_latin1; extern gptr sql_alloc(unsigned size); extern void sql_element_free(void *ptr); static uint32 diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fac3315f5c9..7db398e7810 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1284,7 +1284,7 @@ attribute: | COMMENT_SYM text_literal { Lex->comment= $2; } | COLLATE_SYM collation_name { - if (Lex->charset && strcmp(Lex->charset->csname,$2->csname)) + if (Lex->charset && !my_charset_same(Lex->charset,$2)) { net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, $2->name,Lex->charset->csname); @@ -4250,7 +4250,7 @@ option_value: CHARSET_INFO *cs= $2 ? $2 : thd->db_charset; CHARSET_INFO *cl= $3 ? $3 : cs; - if ((cl != cs) && strcmp(cs->csname,cl->csname)) + if (!my_charset_same(cs,cl)) { net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, cl->name,cs->csname); @@ -4279,7 +4279,7 @@ option_value: YYABORT; } } - else if ((cl != cs) && strcmp(cs->csname,cl->csname)) + else if (!my_charset_same(cs,cl)) { net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, cl->name,cs->csname); |