MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:eugene Date:August 17 2007 2:30pm
Subject:bk commit into 5.0 tree (evgen:1.2495) BUG#30245
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of evgen. When evgen 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-08-17 18:30:41+04:00, evgen@stripped +3 -0
  Bug#30245: A wrong type of a BIT field is reported when grouped by it.
  
  HEAP tables can't index BIT fields. Due to this when grouping by such fields is
  needed they are converted to a fields of the LONG type when temporary table
  is being created. But a side effect of this is that a wrong type of BIT
  fields is returned to a client.
  
  Now the JOIN::prepare and the create_distinct_group functions are create
  additional hidden copy of BIT fields to preserve original fields untouched.
  New hidden fields are used for grouping instead.

  mysql-test/r/type_bit.result@stripped, 2007-08-17 18:29:10+04:00, evgen@stripped +15 -0
    Added a test case for the bug#30245: A wrong type of a BIT field is reported when grouped by it.

  mysql-test/t/type_bit.test@stripped, 2007-08-17 18:28:48+04:00, evgen@stripped +13 -0
    Added a test case for the bug#30245: A wrong type of a BIT field is reported when grouped by it.

  sql/sql_select.cc@stripped, 2007-08-17 18:29:30+04:00, evgen@stripped +53 -9
    Bug#30245: A wrong type of a BIT field is reported when grouped by it.
    Now the JOIN::prepare and the create_distinct_group functions are create
    additional hidden copy of BIT fields to preserve original fields untouched.
    New hidden fields are used for grouping instead.

diff -Nrup a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
--- a/mysql-test/r/type_bit.result	2007-08-06 12:01:16 +04:00
+++ b/mysql-test/r/type_bit.result	2007-08-17 18:29:10 +04:00
@@ -642,4 +642,19 @@ b+0	COUNT(DISTINCT a)
 1	1
 3	2
 DROP TABLE t1;
+CREATE TABLE t1 (b BIT);
+INSERT INTO t1 (b) VALUES (1), (0);
+SELECT DISTINCT b FROM t1;
+Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+def	test	t1	t1	b	b	16	1	1	Y	32	0	63
+b
+#
+#
+SELECT b FROM t1 GROUP BY b;
+Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+def	test	t1	t1	b	b	16	1	1	Y	32	0	63
+b
+#
+#
+DROP TABLE t1;
 End of 5.0 tests
diff -Nrup a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
--- a/mysql-test/t/type_bit.test	2007-08-06 12:01:17 +04:00
+++ b/mysql-test/t/type_bit.test	2007-08-17 18:28:48 +04:00
@@ -291,4 +291,17 @@ INSERT INTO t1 (b, a) VALUES (1, 1), (3,
 SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
 DROP TABLE t1;
 
+#
+# Bug#30245: A wrong type of a BIT field is reported when grouped by it.
+#
+CREATE TABLE t1 (b BIT);
+INSERT INTO t1 (b) VALUES (1), (0);
+--enable_metadata
+--replace_column 1 #
+SELECT DISTINCT b FROM t1;
+--replace_column 1 #
+SELECT b FROM t1 GROUP BY b;
+--disable_metadata
+DROP TABLE t1;
+
 --echo End of 5.0 tests
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc	2007-07-31 15:24:13 +04:00
+++ b/sql/sql_select.cc	2007-08-17 18:29:30 +04:00
@@ -189,6 +189,7 @@ static bool setup_new_fields(THD *thd, L
 			     List<Item> &all_fields, ORDER *new_order);
 static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
                                     ORDER *order, List<Item> &fields,
+                                    List<Item> &all_fields,
 				    bool *all_order_by_fields_used);
 static bool test_if_subpart(ORDER *a,ORDER *b);
 static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
@@ -537,6 +538,28 @@ JOIN::prepare(Item ***rref_pointer_array
       fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
     DBUG_RETURN(-1);
 
+  if (group)
+  {
+    /*
+      Because HEAP tables can't index BIT fields we need to use an
+      additional hidden field for grouping because later it will be
+      converted to a LONG field. Original field will remain of the
+      BIT type and will be returned to a client.
+    */
+    for (ORDER *ord= group_list; ord; ord= ord->next)
+    {
+      if ((*ord->item)->type() == Item::FIELD_ITEM &&
+          (*ord->item)->field_type() == MYSQL_TYPE_BIT)
+      {
+        Item_field *field= new Item_field(thd, *(Item_field**)ord->item);
+        int el= all_fields.elements;
+        ref_pointer_array[el]= field;
+        all_fields.push_front(field);
+        ord->item= ref_pointer_array + el;
+      }
+    }
+  }
+
   if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
     DBUG_RETURN(-1);
   
@@ -1068,12 +1091,13 @@ JOIN::optimize()
     if (order)
       skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
     if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
-                                          order, fields_list,
+                                          order, fields_list, all_fields,
 				          &all_order_fields_used)))
     {
       bool skip_group= (skip_sort_order &&
 			test_if_skip_sort_order(tab, group_list, select_limit,
 						1) != 0);
+      count_field_types(select_lex, &tmp_table_param, all_fields, 0);
       if ((skip_group && all_order_fields_used) ||
 	  select_limit == HA_POS_ERROR ||
 	  (order && !skip_sort_order))
@@ -13646,11 +13670,12 @@ setup_new_fields(THD *thd, List<Item> &f
 
 static ORDER *
 create_distinct_group(THD *thd, Item **ref_pointer_array,
-                      ORDER *order_list, List<Item> &fields, 
+                      ORDER *order_list, List<Item> &fields,
+                      List<Item> &all_fields,
 		      bool *all_order_by_fields_used)
 {
   List_iterator<Item> li(fields);
-  Item *item;
+  Item *item, **orig_ref_pointer_array= ref_pointer_array;
   ORDER *order,*group,**prev;
 
   *all_order_by_fields_used= 1;
@@ -13690,12 +13715,31 @@ create_distinct_group(THD *thd, Item **r
       ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
       if (!ord)
 	return 0;
-      /*
-        We have here only field_list (not all_field_list), so we can use
-        simple indexing of ref_pointer_array (order in the array and in the
-        list are same)
-      */
-      ord->item= ref_pointer_array;
+
+      if (item->type() == Item::FIELD_ITEM &&
+          item->field_type() == MYSQL_TYPE_BIT)
+      {
+        /*
+          Because HEAP tables can't index BIT fields we need to use an
+          additional hidden field for grouping because later it will be
+          converted to a LONG field. Original field will remain of the
+          BIT type and will be returned to a client.
+        */
+        Item_field *new_item= new Item_field(thd, (Item_field*)item);
+        int el= all_fields.elements;
+        orig_ref_pointer_array[el]= new_item;
+        all_fields.push_front(new_item);
+        ord->item= orig_ref_pointer_array + el;
+      }
+      else
+      {
+        /*
+          We have here only field_list (not all_field_list), so we can use
+          simple indexing of ref_pointer_array (order in the array and in the
+          list are same)
+        */
+        ord->item= ref_pointer_array;
+      }
       ord->asc=1;
       *prev=ord;
       prev= &ord->next;
Thread
bk commit into 5.0 tree (evgen:1.2495) BUG#30245eugene17 Aug