diff options
author | unknown <monty@hundin.mysql.fi> | 2002-03-22 14:03:42 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-03-22 14:03:42 +0200 |
commit | 8f2f1597500c4cf74d5d73a4ee04b54f440df695 (patch) | |
tree | 41557706d9a6634dd90773de01ff3d7a12fd8d5f | |
parent | 30016518c3444e92ac1e43cfd71fc335d760bc19 (diff) | |
download | mariadb-git-8f2f1597500c4cf74d5d73a4ee04b54f440df695.tar.gz |
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
-rw-r--r-- | Docs/manual.texi | 4 | ||||
-rw-r--r-- | myisam/myisampack.c | 17 | ||||
-rw-r--r-- | mysql-test/r/range.result | 10 | ||||
-rw-r--r-- | mysql-test/t/range.test | 3 | ||||
-rw-r--r-- | sql/item.cc | 23 | ||||
-rw-r--r-- | sql/item.h | 10 | ||||
-rw-r--r-- | sql/item_func.cc | 10 | ||||
-rw-r--r-- | sql/item_func.h | 6 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 28 |
10 files changed, 71 insertions, 46 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index b33da6a91d5..600ad5efe5a 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -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 diff --git a/myisam/myisampack.c b/myisam/myisampack.c index 98fa8fcb377..81ae77738ea 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -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) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index e0e43f44a4b..1a45c252b7c 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -55,3 +55,13 @@ believe believe in love aString believe in myself +count(*) +602 +count(*) +602 +count(*) +602 +count(*) +389 +count(*) +213 diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index ccb66506efd..278807eeea4 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -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; diff --git a/sql/item.cc b/sql/item.cc index b268c5eb928..0ce37cdd593 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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 */ diff --git a/sql/item.h b/sql/item.h index c868f9d3bf7..41b897956db 100644 --- a/sql/item.h +++ b/sql/item.h @@ -56,7 +56,7 @@ public: 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 @@ public: {} 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 @@ public: 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 @@ public: 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 @@ public: 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() { diff --git a/sql/item_func.cc b/sql/item_func.cc index e7e8964b07a..9f94a25cbf9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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; diff --git a/sql/item_func.h b/sql/item_func.h index 4a8f808de57..35af4540f7c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -98,7 +98,7 @@ public: 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 @@ public: 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 @@ public: 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; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 985118ee218..e4a797efaaf 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -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; } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1ee0d84e182..b7134062437 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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(); } |