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#30245 | eugene | 17 Aug |