Commit e7d138ec authored by unknown's avatar unknown

Fix for bug in WHERE key='j' or key='J'


Docs/manual.texi:
  Changelog
myisam/myisampack.c:
  Delete tmp file on error.
mysql-test/r/range.result:
  Updated test case
mysql-test/t/range.test:
  Updated test case
parent bb4c1bf5
......@@ -46897,6 +46897,8 @@ not yet 100% confident in this code.
@appendixsubsec Changes in release 3.23.50
@itemize @bullet
@item
Fixed bug when using @code{WHERE key_column = 'J' or key_column='j'}.
@item
Fixed core-dump bug when using @code{--log-bin} with @code{LOAD DATA
INFILE} without an active database.
@item
......@@ -46934,7 +46936,7 @@ Don't give warning for statement that is only a comment; This is needed for
@code{mysqldump --disable-keys} to work.
@item
Fixed unlikely caching bug when doing a join without keys. In this case
the last used field for a table always returned @code{NULL}.
the last used column for a table always returned @code{NULL}.
@item
Added options to make @code{LOAD DATA LOCAL INFILE} more secure.
@item
......@@ -251,7 +251,7 @@ static struct option long_options[] =
static void print_version(void)
{
printf("%s Ver 1.11 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
printf("%s Ver 1.12 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
}
static void usage(void)
......@@ -594,10 +594,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
else
{
if (tmp_dir[0])
{
if (!(error=my_copy(new_name,org_name,MYF(MY_WME))))
VOID(my_delete(new_name,MYF(MY_WME)));
}
error=my_copy(new_name,org_name,MYF(MY_WME));
else
error=my_rename(new_name,org_name,MYF(MY_WME));
if (!error)
......@@ -607,13 +604,8 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
else
{
if (tmp_dir[0])
{
if (!(error=my_copy(new_name,org_name,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES
| MY_COPYTIME))))
VOID(my_delete(new_name,MYF(MY_WME)));
}
error=my_copy(new_name,org_name,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_COPYTIME));
else
error=my_redel(org_name,new_name,MYF(MY_WME | MY_COPYTIME));
}
......@@ -627,6 +619,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
if (error)
{
VOID(fprintf(stderr,"Aborting: %s is not compressed\n",org_name));
VOID(my_delete(new_name,MYF(MY_WME)));
DBUG_RETURN(-1);
}
if (write_loop || verbose)
......
......@@ -55,3 +55,13 @@ believe
believe in love
aString
believe in myself
count(*)
602
count(*)
602
count(*)
602
count(*)
389
count(*)
213
......@@ -105,7 +105,6 @@ drop table t1;
# Problem with binary strings
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
t1ID int(10) unsigned NOT NULL auto_increment,
art char(1) binary NOT NULL default '',
......@@ -161,4 +160,6 @@ INSERT INTO t1 (art) VALUES ('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'
select count(*) from t1 where upper(art) = 'J';
select count(*) from t1 where art = 'J' or art = 'j';
select count(*) from t1 where art = 'j' or art = 'J';
select count(*) from t1 where art = 'j';
select count(*) from t1 where art = 'J';
drop table t1;
......@@ -59,12 +59,28 @@ void Item::set_name(char *str,uint length)
}
}
bool Item::eq(const Item *item) const // Only doing this on conds
/*
This function is only called when comparing items in the WHERE clause
*/
bool Item::eq(const Item *item, bool binary_cmp) const
{
return type() == item->type() && name && item->name &&
!my_strcasecmp(name,item->name);
}
bool Item_string::eq(const Item *item, bool binary_cmp) const
{
if (type() == item->type())
{
if (binary_cmp)
return !stringcmp(&str_value, &item->str_value);
return !sortcmp(&str_value, &item->str_value);
}
return 0;
}
/*
Get the value of the function as a TIME structure.
As a extra convenience the time structure is reset on error!
......@@ -202,7 +218,7 @@ longlong Item_field::val_int_result()
return result_field->val_int();
}
bool Item_field::eq(const Item *item) const
bool Item_field::eq(const Item *item, bool binary_cmp) const
{
return item->type() == FIELD_ITEM && ((Item_field*) item)->field == field;
}
......@@ -245,7 +261,8 @@ void Item_string::print(String *str)
str->append('\'');
}
bool Item_null::eq(const Item *item) const { return item->type() == type(); }
bool Item_null::eq(const Item *item, bool binary_cmp) const
{ return item->type() == type(); }
double Item_null::val() { null_value=1; return 0.0; }
longlong Item_null::val_int() { null_value=1; return 0; }
/* ARGSUSED */
......
......@@ -56,7 +56,7 @@ class Item {
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); }
virtual bool send(String *str);
virtual bool eq(const Item *) const;
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0;
virtual double val()=0;
......@@ -109,7 +109,7 @@ class Item_field :public Item_ident
{}
Item_field(Field *field);
enum Type type() const { return FIELD_ITEM; }
bool eq(const Item *item) const;
bool eq(const Item *item, bool binary_cmp) const;
double val();
longlong val_int();
String *val_str(String*);
......@@ -138,7 +138,7 @@ class Item_null :public Item
Item_null(char *name_par=0)
{ maybe_null=null_value=TRUE; name= name_par ? name_par : (char*) "NULL";}
enum Type type() const { return NULL_ITEM; }
bool eq(const Item *item) const;
bool eq(const Item *item, bool binary_cmp) const;
double val();
longlong val_int();
String *val_str(String *str);
......@@ -247,6 +247,7 @@ class Item_string :public Item
void make_field(Send_field *field);
enum Item_result result_type () const { return STRING_RESULT; }
bool basic_const_item() const { return 1; }
bool eq(const Item *item, bool binary_cmp) const;
Item *new_item() { return new Item_string(name,str_value.ptr(),max_length); }
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
......@@ -306,7 +307,8 @@ class Item_ref :public Item_ident
Item_ref(Item **item, char *table_name_par,char *field_name_par)
:Item_ident(NullS,table_name_par,field_name_par),ref(item) {}
enum Type type() const { return REF_ITEM; }
bool eq(const Item *item) const { return (*ref)->eq(item); }
bool eq(const Item *item, bool binary_cmp) const
{ return (*ref)->eq(item, binary_cmp); }
~Item_ref() { if (ref) delete *ref; }
double val()
{
......
......@@ -148,7 +148,7 @@ void Item_func::print_op(String *str)
str->append(')');
}
bool Item_func::eq(const Item *item) const
bool Item_func::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
if (this == item)
......@@ -160,7 +160,7 @@ bool Item_func::eq(const Item *item) const
func_name() != item_func->func_name())
return 0;
for (uint i=0; i < arg_count ; i++)
if (!args[i]->eq(item_func->args[i]))
if (!args[i]->eq(item_func->args[i], binary_cmp))
return 0;
return 1;
}
......@@ -1882,7 +1882,7 @@ void Item_func_get_user_var::print(String *str)
str->append(')');
}
bool Item_func_get_user_var::eq(const Item *item) const
bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
if (this == item)
......@@ -2135,7 +2135,7 @@ bool Item_func_match::fix_index()
return 1;
}
bool Item_func_match::eq(const Item *item) const
bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{
if (item->type() != FUNC_ITEM)
return 0;
......@@ -2146,7 +2146,7 @@ bool Item_func_match::eq(const Item *item) const
Item_func_match *ifm=(Item_func_match*) item;
if (key == ifm->key && table == ifm->table &&
key_item()->eq(ifm->key_item()))
key_item()->eq(ifm->key_item(), binary_cmp))
return 1;
return 0;
......
......@@ -98,7 +98,7 @@ class Item_func :public Item_result_field
void make_field(Send_field *field);
table_map used_tables() const;
void update_used_tables();
bool eq(const Item *item) const;
bool eq(const Item *item, bool binary_cmp) const;
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
......@@ -842,7 +842,7 @@ class Item_func_get_user_var :public Item_func
bool const_item() const { return const_var_flag; }
table_map used_tables() const
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item) const;
bool eq(const Item *item, bool binary_cmp) const;
};
......@@ -887,7 +887,7 @@ class Item_func_match :public Item_real_func
enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist);
bool eq(const Item *) const;
bool eq(const Item *, bool binary_cmp) const;
double val();
longlong val_int() { return val()!=0.0; }
......
......@@ -1718,7 +1718,7 @@ find_item_in_list(Item *find,List<Item> &items)
{
if (found)
{
if ((*found)->eq(item))
if ((*found)->eq(item,0))
continue; // Same field twice (Access?)
if (current_thd->where)
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
......@@ -1734,7 +1734,7 @@ find_item_in_list(Item *find,List<Item> &items)
}
}
}
else if (!table_name && (item->eq(find) ||
else if (!table_name && (item->eq(find,0) ||
find->name &&
!my_strcasecmp(item->name,find->name)))
{
......@@ -2213,7 +2213,7 @@ int setup_ftfuncs(THD *thd)
lj.rewind();
while ((ftf2=lj++) != ftf)
{
if (ftf->eq(ftf2) && !ftf2->master)
if (ftf->eq(ftf2,1) && !ftf2->master)
ftf2->master=ftf;
}
}
......
......@@ -1100,14 +1100,14 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
{
if (new_fields->val->used_tables())
{
if (old->val->eq(new_fields->val))
if (old->val->eq(new_fields->val, old->field->binary()))
{
old->level=old->const_level=and_level;
old->exists_optimize&=new_fields->exists_optimize;
}
}
else if (old->val->eq(new_fields->val) && old->eq_func &&
new_fields->eq_func)
else if (old->val->eq(new_fields->val, old->field->binary()) &&
old->eq_func && new_fields->eq_func)
{
old->level=old->const_level=and_level;
old->exists_optimize&=new_fields->exists_optimize;
......@@ -2602,7 +2602,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
ORDER *order;
for (order=start_order ; order ; order=order->next)
{
if ((*ref_item)->eq(order->item[0]))
if ((*ref_item)->eq(order->item[0],0))
break;
}
if (order)
......@@ -2859,7 +2859,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
Item *right_item= func->arguments()[1];
Item_func::Functype functype= func->functype();
if (right_item->eq(field) && left_item != value)
if (right_item->eq(field,0) && left_item != value)
{
Item *tmp=value->new_item();
if (tmp)
......@@ -2878,7 +2878,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
func->arguments()[1]->result_type()));
}
}
else if (left_item->eq(field) && right_item != value)
else if (left_item->eq(field,0) && right_item != value)
{
Item *tmp=value->new_item();
if (tmp)
......@@ -3118,7 +3118,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
{ // boolan compare function
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
if (left_item->eq(right_item))
if (left_item->eq(right_item,1))
{
if (!left_item->maybe_null ||
((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
......@@ -3163,22 +3163,22 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
return 0;
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
if (left_item->eq(comp_item))
if (left_item->eq(comp_item,1))
{
if (right_item->const_item())
{
if (*const_item)
return right_item->eq(*const_item);
return right_item->eq(*const_item, 1);
*const_item=right_item;
return 1;
}
}
else if (right_item->eq(comp_item))
else if (right_item->eq(comp_item,1))
{
if (left_item->const_item())
{
if (*const_item)
return left_item->eq(*const_item);
return left_item->eq(*const_item, 1);
*const_item=left_item;
return 1;
}
......@@ -4970,7 +4970,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
if (!field->table->const_table && !field->table->maybe_null)
{
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item))
if (ref_item && ref_item->eq(right_item,1))
{
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
......@@ -6151,7 +6151,7 @@ test_if_subpart(ORDER *a,ORDER *b)
{
for (; a && b; a=a->next,b=b->next)
{
if ((*a->item)->eq(*b->item))
if ((*a->item)->eq(*b->item,1))
a->asc=b->asc;
else
return 0;
......@@ -6178,7 +6178,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
for (; a && b; a=a->next,b=b->next)
{
if (!(*a->item)->eq(*b->item))
if (!(*a->item)->eq(*b->item,1))
DBUG_RETURN(0);
map|=a->item[0]->used_tables();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment