@@ -5920,7 +5920,7 @@ Item_equal::Item_equal(THD *thd, Item *f1, Item *f2, bool with_const_item):
59205920 with_const= with_const_item;
59215921 equal_items.push_back (f1, thd->mem_root );
59225922 equal_items.push_back (f2, thd->mem_root );
5923- compare_as_dates= with_const_item && f2->cmp_type () == TIME_RESULT ;
5923+ cmp. cmp_collation . set ( f2->collation ) ;
59245924 cmp.set_compare_type (item_cmp_type (f1, f2));
59255925 upper_levels= NULL ;
59265926}
@@ -5950,7 +5950,7 @@ Item_equal::Item_equal(THD *thd, Item_equal *item_equal):
59505950 equal_items.push_back (item, thd->mem_root );
59515951 }
59525952 with_const= item_equal->with_const ;
5953- compare_as_dates= item_equal->compare_as_dates ;
5953+ cmp. cmp_collation . set ( item_equal->cmp . cmp_collation ) ;
59545954 cmp.set_compare_type (item_equal->cmp .compare_type ());
59555955 cond_false= item_equal->cond_false ;
59565956 upper_levels= item_equal->upper_levels ;
@@ -5971,41 +5971,85 @@ Item_equal::Item_equal(THD *thd, Item_equal *item_equal):
59715971 the list. Otherwise the value of c is compared with the value of the
59725972 constant item from equal_items. If they are not equal cond_false is set
59735973 to TRUE. This serves as an indicator that this Item_equal is always FALSE.
5974- The optional parameter f is used to adjust the flag compare_as_dates.
59755974*/
59765975
5977- void Item_equal::add_const (THD *thd, Item *c, Item *f )
5976+ void Item_equal::add_const (THD *thd, Item *c)
59785977{
59795978 if (cond_false)
59805979 return ;
59815980 if (!with_const)
59825981 {
59835982 with_const= TRUE ;
5984- if (f)
5985- compare_as_dates= f->cmp_type () == TIME_RESULT;
59865983 equal_items.push_front (c, thd->mem_root );
59875984 return ;
59885985 }
59895986 Item *const_item= get_const ();
5990- if (compare_as_dates)
5991- {
5992- cmp.set_datetime_cmp_func (this , &c, &const_item);
5993- cond_false= cmp.compare ();
5994- }
5995- else
5996- {
5997- Item_func_eq *func= new (thd->mem_root ) Item_func_eq (thd, c, const_item);
5998- if (func->set_cmp_func ())
5987+ switch (cmp.compare_type ()) {
5988+ case TIME_RESULT:
59995989 {
5990+ cmp.set_datetime_cmp_func (this , &c, &const_item);
5991+ cond_false= cmp.compare ();
5992+ break ;
5993+ }
5994+ case STRING_RESULT:
5995+ {
5996+ String *str1, *str2;
60005997 /*
6001- Setting a comparison function fails when trying to compare
6002- incompatible charsets. Charset compatibility is checked earlier,
6003- except for constant subqueries where we may do it here.
5998+ Suppose we have an expression (with a string type field) like this:
5999+ WHERE field=const1 AND field=const2 ...
6000+
6001+ For all pairs field=constXXX we know that:
6002+
6003+ - Item_func_eq::fix_length_and_dec() performed collation and character
6004+ set aggregation and added character set converters when needed.
6005+ Note, the case like:
6006+ WHERE field=const1 COLLATE latin1_bin AND field=const2
6007+ is not handled here, because the field would be replaced to
6008+ Item_func_set_collation, which cannot get into Item_equal.
6009+ So all constXXX that are handled by Item_equal
6010+ already have compatible character sets with "field".
6011+
6012+ - Also, Field_str::test_if_equality_guarantees_uniqueness() guarantees
6013+ that the comparison collation of all equalities handled by Item_equal
6014+ match the the collation of the field.
6015+
6016+ Therefore, at Item_equal::add_const() time all constants constXXX
6017+ should be directly comparable to each other without an additional
6018+ character set conversion.
6019+ It's safe to do val_str() for "const_item" and "c" and compare
6020+ them according to the collation of the *field*.
6021+
6022+ So in a script like this:
6023+ CREATE TABLE t1 (a VARCHAR(10) COLLATE xxx);
6024+ INSERT INTO t1 VALUES ('a'),('A');
6025+ SELECT * FROM t1 WHERE a='a' AND a='A';
6026+ Item_equal::add_const() effectively rewrites the condition to:
6027+ SELECT * FROM t1 WHERE a='a' AND 'a' COLLATE xxx='A';
6028+ and then to:
6029+ SELECT * FROM t1 WHERE a='a'; // if the two constants were equal
6030+ // e.g. in case of latin1_swedish_ci
6031+ or to:
6032+ SELECT * FROM t1 WHERE FALSE; // if the two constants were not equal
6033+ // e.g. in case of latin1_bin
6034+
6035+ Note, both "const_item" and "c" can return NULL, e.g.:
6036+ SELECT * FROM t1 WHERE a=NULL AND a='const';
6037+ SELECT * FROM t1 WHERE a='const' AND a=NULL;
6038+ SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2)
60046039 */
6005- return ;
6040+ cond_false= !(str1= const_item->val_str (&cmp.value1 )) ||
6041+ !(str2= c->val_str (&cmp.value2 )) ||
6042+ !str1->eq (str2, compare_collation ());
6043+ break ;
6044+ }
6045+ default :
6046+ {
6047+ Item_func_eq *func= new (thd->mem_root ) Item_func_eq (thd, c, const_item);
6048+ if (func->set_cmp_func ())
6049+ return ;
6050+ func->quick_fix_field ();
6051+ cond_false= !func->val_int ();
60066052 }
6007- func->quick_fix_field ();
6008- cond_false= !func->val_int ();
60096053 }
60106054 if (with_const && equal_items.elements == 1 )
60116055 cond_true= TRUE ;
@@ -6482,14 +6526,6 @@ void Item_equal::print(String *str, enum_query_type query_type)
64826526}
64836527
64846528
6485- CHARSET_INFO *Item_equal::compare_collation () const
6486- {
6487- Item_equal_fields_iterator it (*((Item_equal*) this ));
6488- Item *item= it++;
6489- return item->collation .collation ;
6490- }
6491-
6492-
64936529/*
64946530 @brief Get the first equal field of multiple equality.
64956531 @param[in] field the field to get equal field to
0 commit comments