summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc14
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_subselect.cc11
-rw-r--r--sql/key.cc2
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/protocol.cc30
-rw-r--r--sql/sql_db.cc8
-rw-r--r--sql/sql_lex.cc9
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_select.cc29
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_string.cc1
-rw-r--r--sql/sql_yacc.yy6
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);