List:Internals« Previous MessageNext Message »
From:bar Date:November 21 2005 1:34pm
Subject:bk commit into 4.1 tree (bar:1.2467) BUG#10446
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2467 05/11/21 17:26:31 bar@stripped +5 -0
    Bug#10446 Illegal mix of collations:
  item_strfunc.h, item_strfunc.cc, item.cc:
    Try to convert a const item into destination 
    character set. If conversion happens without
    data loss, then cache the converted value
    and return it during val_str().
    Otherwise, if conversion loses data, return
    Illeral mix of collations error, as it happened
    previously.
  ctype_recoding.result, ctype_recoding.test:
    Fixing tests accordingly.

  mysql-test/r/ctype_recoding.result
    1.25 05/11/21 17:23:50 bar@stripped +8 -1
    Fixing tests accordingly.

  mysql-test/t/ctype_recoding.test
    1.21 05/11/21 17:23:41 bar@stripped +9 -2
    Fixing tests accordingly.

  sql/item_strfunc.cc
    1.238 05/11/21 17:23:08 bar@stripped +2 -0
    Return cached value when it's possible.

  sql/item_strfunc.h
    1.99 05/11/21 17:22:56 bar@stripped +32 -2

  sql/item.cc
    1.229 05/11/21 17:20:38 bar@stripped +2 -10
    Bug#10446 Illegal mix of collations
    Try to convert a const item into destination 
    character set. If conversion happens without
    data loss, then cache the converted value
    and return it during val_str().
    Otherwise, if conversion loses data, return
    Illeral mix of collations error, as it happened
    previously.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	bar
# Host:	bar.intranet.mysql.r18.ru
# Root:	/usr/home/bar/mysql-4.1.b10446

--- 1.228/sql/item.cc	2005-10-25 21:01:39 +05:00
+++ 1.229/sql/item.cc	2005-11-21 17:20:38 +04:00
@@ -211,16 +211,8 @@
 
 Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
 {
-  /*
-    Allow conversion from and to "binary".
-    Don't allow automatic conversion to non-Unicode charsets,
-    as it potentially loses data.
-  */
-  if (collation.collation != &my_charset_bin &&
-      tocs != &my_charset_bin &&
-      !(tocs->state & MY_CS_UNICODE))
-    return NULL; // safe conversion is not possible
-  return new Item_func_conv_charset(this, tocs);
+  Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1);
+  return conv->safe ? conv : NULL;
 }
 
 

--- 1.237/sql/item_strfunc.cc	2005-10-07 04:15:50 +05:00
+++ 1.238/sql/item_strfunc.cc	2005-11-21 17:23:08 +04:00
@@ -2252,6 +2252,8 @@
 String *Item_func_conv_charset::val_str(String *str)
 {
   DBUG_ASSERT(fixed == 1);
+  if (use_cached_value)
+    return null_value ? 0 : &str_value;
   String *arg= args[0]->val_str(str);
   uint dummy_errors;
   if (!arg)

--- 1.98/sql/item_strfunc.h	2005-11-10 18:12:18 +04:00
+++ 1.99/sql/item_strfunc.h	2005-11-21 17:22:56 +04:00
@@ -614,10 +614,40 @@
 
 class Item_func_conv_charset :public Item_str_func
 {
+  bool use_cached_value;
 public:
+  bool safe;
   CHARSET_INFO *conv_charset; // keep it public
-  Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
-  { conv_charset=cs; }
+  Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) 
+  { conv_charset= cs; use_cached_value= 0; safe= 0; }
+  Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) 
+    :Item_str_func(a) 
+  {
+    DBUG_ASSERT(args[0]->fixed);
+    conv_charset= cs;
+    if (cache_if_const && args[0]->const_item())
+    {
+      uint errors= 0;
+      String tmp, *str= args[0]->val_str(&tmp);
+      if (!str || str_value.copy(str->ptr(), str->length(),
+                                 str->charset(), conv_charset, &errors))
+        null_value= 1;
+      use_cached_value= 1;
+      safe= (errors == 0);
+    }
+    else
+    {
+      use_cached_value= 0;
+      /*
+        Conversion from and to "binary" is safe.
+        Conversion to Unicode is safe.
+        Other kind of conversions are potentially lossy.
+      */
+      safe= (args[0]->collation.collation == &my_charset_bin ||
+             cs == &my_charset_bin ||
+             (cs->state & MY_CS_UNICODE));
+    }
+  }
   String *val_str(String *);
   void fix_length_and_dec();
   const char *func_name() const { return "convert"; }

--- 1.24/mysql-test/r/ctype_recoding.result	2004-11-02 16:01:13 +04:00
+++ 1.25/mysql-test/r/ctype_recoding.result	2005-11-21 17:23:50 +04:00
@@ -181,11 +181,18 @@
 a
-ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '='
+a
 ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
 drop table t1;
 set names latin1;
+create table t1 (a char(10) character set utf8 collate utf8_bin);
+insert into t1 values ('       xxx');
+select * from t1 where a=lpad('xxx',10,' ');
+a
+       xxx
+drop table t1;
 set names koi8r;
 create table t1 (c1 char(10) character set cp1251);

--- 1.20/mysql-test/t/ctype_recoding.test	2005-07-28 05:21:40 +05:00
+++ 1.21/mysql-test/t/ctype_recoding.test	2005-11-21 17:23:41 +04:00
@@ -144,14 +144,21 @@
 # this is possible:
-# this is not possible, because we have a function, not just a constant:
---error 1267
+# this is possible, because we have a function with constant arguments:
 --error 1267
 drop table t1;
 set names latin1;
+
+#
+# Bug#10446 Illegal mix of collations
+#
+create table t1 (a char(10) character set utf8 collate utf8_bin);
+insert into t1 values ('       xxx');
+select * from t1 where a=lpad('xxx',10,' ');
+drop table t1;
 
 #
 # Check more automatic conversion
Thread
bk commit into 4.1 tree (bar:1.2467) BUG#10446bar21 Nov