List:Commits« Previous MessageNext Message »
From:mhansson Date:April 25 2007 2:56pm
Subject:bk commit into 5.0 tree (mhansson:1.2443) BUG#23856
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of martin. When martin 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@stripped, 2007-04-25 15:56:26+03:00, mhansson@stripped +6 -0
  Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
  
  Item_func_group_concat::setup, responsible for initalizing placeholder fields to
represent
  the group column for GROUP_CONCAT, had misunderstood the save_sum_fields argument to 
  create_tmp_table:
  
      "We need to set set_sum_field in true for storing value of blob in buffer
       of a record instead of a pointer of one."
  
  This is not true, it's currently not possible to get this behavior out of blobs.
  It would be desirable, though, since if we could do this we could keep 
  using the TREE data structure that does the ORDER BY sorting. At the present state of
MySQL,
  blob fields can't be stored in this way since always keep a pointer to the actual data.
So
  the fix is to use VARCHAR for the placeholder field instead. This 
  will lead to results being cut if they exceed the maximum VARCHAR length (65535 bytes),
but 
  doing more is beyond a simple bug fix.
  
  There is still one problem, there is no warning about this cutting. Consider:
  
  create table t20b(a text character set utf8, b int);
  insert into t20b values (repeat('a', 0xffff+1), 0); 
  
  mysql> select length(group_concat(a)) from t20b;
  +-------------------------+
  | length(group_concat(a)) |
  +-------------------------+
  |                   32768 |
  +-------------------------+
  1 row in set, 1 warning (0.00 sec)
  
  mysql> show warnings;
  +---------+------+--------------------------------------+
  | Level   | Code | Message                              |
  +---------+------+--------------------------------------+
  | Warning | 1260 | 1 line(s) were cut by GROUP_CONCAT() |
  +---------+------+--------------------------------------+
  1 row in set (0.00 sec)
  
  mysql> select length(group_concat(a order by b)) from t20b;
  +------------------------------------+
  | length(group_concat(a order by b)) |
  +------------------------------------+
  |                              32768 |
  +------------------------------------+
  1 row in set (0.00 sec)
  
  Notice there's no warnings. This has nothing to do with our conversion to VARCHAR,
though:
  
  create table t20v(a varchar(65528), b int);
  insert into t20v values (repeat('a', 0xffff), 0); 
  
  mysql> select length(group_concat(a)) from t20v;
  +-------------------------+
  | length(group_concat(a)) |
  +-------------------------+
  |                   32768 |
  +-------------------------+
  1 row in set, 1 warning (0.00 sec)
  
  mysql> show warnings;
  +---------+------+--------------------------------------+
  | Level   | Code | Message                              |
  +---------+------+--------------------------------------+
  | Warning | 1260 | 1 line(s) were cut by GROUP_CONCAT() |
  +---------+------+--------------------------------------+
  1 row in set (0.00 sec)
  
  mysql> select length(group_concat(a order by b)) from t20v;
  +------------------------------------+
  | length(group_concat(a order by b)) |
  +------------------------------------+
  |                              32768 |
  +------------------------------------+
  1 row in set (0.00 sec)
  
  This seems to be a bug in its own respect.

  mysql-test/r/func_gconcat.result@stripped, 2007-04-25 15:56:23+03:00,
mhansson@stripped +7 -0
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    correct result.

  mysql-test/t/func_gconcat.test@stripped, 2007-04-25 15:56:23+03:00, mhansson@stripped
+9 -0
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    test case

  sql/field.h@stripped, 2007-04-25 15:56:23+03:00, mhansson@stripped +1 -0
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    Intruduced new field in Field_varstring. Basically just putting a name for the concept
of
    maximum length for VARCHARs.

  sql/item_sum.cc@stripped, 2007-04-25 15:56:24+03:00, mhansson@stripped +9 -3
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    The fix for the bug and motivation.
    Removed the erroneous conclusion that caused the bug.

  sql/sql_select.cc@stripped, 2007-04-25 15:56:24+03:00, mhansson@stripped +5 -3
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    Fixed a comment that is simply not true. 
    Using the new field MAX_VALUE. Using UINT_MAX16 here is unclear.

  sql/sql_string.cc@stripped, 2007-04-25 15:56:24+03:00, mhansson@stripped +2 -2
    Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
    
    Fixed typo.

# 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:	mhansson
# Host:	linux-st28.site
# Root:	/home/martin/mysql/src/5.0o-bug23856

--- 1.200/sql/field.h	2007-04-02 11:50:16 +03:00
+++ 1.201/sql/field.h	2007-04-25 15:56:23 +03:00
@@ -1076,6 +1076,7 @@ public:
 
 class Field_varstring :public Field_longstr {
 public:
+  static const int MAX_SIZE= UINT_MAX16;
   /* Store number of bytes used to store length (1 or 2) */
   uint32 length_bytes;
   Field_varstring(char *ptr_arg,

--- 1.205/sql/item_sum.cc	2007-04-02 11:50:17 +03:00
+++ 1.206/sql/item_sum.cc	2007-04-25 15:56:24 +03:00
@@ -3257,14 +3257,20 @@ bool Item_func_group_concat::setup(THD *
   tmp_table_param->force_copy_fields= force_copy_fields;
   DBUG_ASSERT(table == 0);
   /*
+    Currently we have to force conversion of BLOB values to VARCHAR's
+    for GROUP_CONCAT if we have a GROUP CONCAT( x ORDER BY y ), since
+    BLOB's cannot be stored inside the TREE objects used for
+    sorting. This leads to truncation if the BLOB's size exceeds
+    Field_varstring::MAX_SIZE.
+  */
+  if (arg_count_order > 0)
+    tmp_table_param->convert_blob_length= Field_varstring::MAX_SIZE - 1;
+  /*
     We have to create a temporary table to get descriptions of fields
     (types, sizes and so on).
 
     Note that in the table, we first have the ORDER BY fields, then the
     field list.
-
-    We need to set set_sum_field in true for storing value of blob in buffer
-    of a record instead of a pointer of one.
   */
   if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
                                 (ORDER*) 0, 0, TRUE,

--- 1.507/sql/sql_select.cc	2007-04-02 04:56:34 +03:00
+++ 1.508/sql/sql_select.cc	2007-04-25 15:56:24 +03:00
@@ -8711,7 +8711,8 @@ const_expression_in_where(COND *cond, It
 			the record in the original table.
 			If item == NULL then fill_record() will update
 			the temporary table
-    convert_blob_length If >0 create a varstring(convert_blob_length) field 
+    convert_blob_length If inside the interval (0, Field_varstring::MAX_SIZE)
+                        create a varstring(convert_blob_length) field 
                         instead of blob.
 
   RETURN
@@ -8729,7 +8730,7 @@ Field* create_tmp_field_from_field(THD *
     Make sure that the blob fits into a Field_varstring which has 
     2-byte lenght. 
   */
-  if (convert_blob_length && convert_blob_length < UINT_MAX16 &&
+  if (convert_blob_length && convert_blob_length < Field_varstring::MAX_SIZE
&&
       (org_field->flags & BLOB_FLAG))
     new_field= new Field_varstring(convert_blob_length,
                                    org_field->maybe_null(),
@@ -8898,7 +8899,8 @@ Field *create_tmp_field_for_schema(THD *
 			the record in the original table.
 			If modify_item is 0 then fill_record() will update
 			the temporary table
-    convert_blob_length If >0 create a varstring(convert_blob_length) field 
+    convert_blob_length If inside the interval (0, Field_varstring::MAX_SIZE)
+                        create a varstring(convert_blob_length) field 
                         instead of blob.
 
   RETURN

--- 1.97/sql/sql_string.cc	2007-01-22 14:10:41 +02:00
+++ 1.98/sql/sql_string.cc	2007-04-25 15:56:24 +03:00
@@ -858,9 +858,9 @@ outp:
   with optional left padding (for binary -> UCS2 conversion)
   
   SYNOPSIS
-    well_formed_copy_nhars()
+    well_formed_copy_nchars()
     to			     Store result here
-    to_length                Maxinum length of "to" string
+    to_length                Maximum length of "to" string
     to_cs		     Character set of "to" string
     from		     Copy from here
     from_length		     Length of from string

--- 1.68/mysql-test/r/func_gconcat.result	2007-03-29 19:20:02 +03:00
+++ 1.69/mysql-test/r/func_gconcat.result	2007-04-25 15:56:23 +03:00
@@ -737,4 +737,11 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(b)) F
 GROUP_CONCAT(DISTINCT UCASE(b))
 ONE.1,TWO.2,ONE.3
 DROP TABLE t1;
+set group_concat_max_len= 32768;
+set names utf8;
+create table t1 (a text character set utf8, b integer);
+insert into t1 values (repeat('a', 4), 0), (repeat(_utf8 0xc3b7, 4), 1);
+select group_concat(a order by b) from t1;
+group_concat(a order by b)
+aaaa,÷÷÷÷
 End of 5.0 tests

--- 1.55/mysql-test/t/func_gconcat.test	2007-03-29 19:20:02 +03:00
+++ 1.56/mysql-test/t/func_gconcat.test	2007-04-25 15:56:23 +03:00
@@ -507,4 +507,13 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(a)) F
 SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1;
 DROP TABLE t1;
 
+#
+# Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
+#
+set group_concat_max_len= 32768;
+set names utf8;
+create table t1 (a text character set utf8, b integer);
+insert into t1 values (repeat('a', 4), 0), (repeat(_utf8 0xc3b7, 4), 1);
+select group_concat(a order by b) from t1;
+
 --echo End of 5.0 tests
Thread
bk commit into 5.0 tree (mhansson:1.2443) BUG#23856mhansson25 Apr