From 24a567e9f6e73f4158eba43cf16d30ad1c8c86b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Oct 2007 17:20:34 +0500 Subject: Fix for bug #31154: field.h:1649: virtual int Field_bit::cmp(const uchar*, const uchar*): Assertion Problem: GROUP_CONCAT(DISTINCT BIT_FIELD...) uses a tree to store keys; which are constructed using a temporary table fields, see Item_func_group_concat::setup(). As a) we don't store null bits in the tree where the bit fields store parts of their data and b) there's no method to properly compare two table records we've got problem. Fix: convert BIT fields to INT in the temporary table used. mysql-test/r/func_gconcat.result: Fix for bug #31154: field.h:1649: virtual int Field_bit::cmp(const uchar*, const uchar*): Assertion - test result. mysql-test/t/func_gconcat.test: Fix for bug #31154: field.h:1649: virtual int Field_bit::cmp(const uchar*, const uchar*): Assertion - test case. sql/item_sum.cc: Fix for bug #31154: field.h:1649: virtual int Field_bit::cmp(const uchar*, const uchar*): Assertion - force the create_tmp_table() to convert BIT columns to INT in order to be able to compare records containing BIT fields. --- mysql-test/r/func_gconcat.result | 42 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/func_gconcat.test | 28 +++++++++++++++++++++++++++ sql/item_sum.cc | 31 +++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 35487c25ae3..73f756bc1d2 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -819,4 +819,46 @@ id group_concat(b.name) 1 óra,óra 2 óra,óra drop table t1; +create table t1(a bit not null); +insert into t1 values (), (), (); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +select group_concat(distinct a) from t1; +group_concat(distinct a) +0 +select group_concat(distinct a order by a) from t1; +group_concat(distinct a order by a) +0 +drop table t1; +create table t1(a bit(2) not null); +insert into t1 values (1), (0), (0), (3), (1); +select group_concat(distinct a) from t1; +group_concat(distinct a) +1,0,3 +select group_concat(distinct a order by a) from t1; +group_concat(distinct a order by a) +0,1,3 +select group_concat(distinct a order by a desc) from t1; +group_concat(distinct a order by a desc) +3,1,0 +drop table t1; +create table t1(a bit(2), b varchar(10), c bit); +insert into t1 values (1, 'a', 0), (0, 'b', 1), (0, 'c', 0), (3, 'd', 1), +(1, 'e', 1), (3, 'f', 1), (0, 'g', 1); +select group_concat(distinct a, c) from t1; +group_concat(distinct a, c) +10,01,00,31,11 +select group_concat(distinct a, c order by a) from t1; +group_concat(distinct a, c order by a) +00,01,11,10,31 +select group_concat(distinct a, c) from t1; +group_concat(distinct a, c) +10,01,00,31,11 +select group_concat(distinct a, c order by a, c) from t1; +group_concat(distinct a, c order by a, c) +00,01,10,11,31 +select group_concat(distinct a, c order by a desc, c desc) from t1; +group_concat(distinct a, c order by a desc, c desc) +31,11,10,01,00 +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index ff3ba951870..c415ca6c6eb 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -562,4 +562,32 @@ insert into t1 (id, name) values (2, " select b.id, group_concat(b.name) from t1 a, t1 b group by b.id; drop table t1; +# +# Bug #31154: group_concat() and bit fields; +# +create table t1(a bit not null); +insert into t1 values (), (), (); +select group_concat(distinct a) from t1; +select group_concat(distinct a order by a) from t1; +drop table t1; + +create table t1(a bit(2) not null); +insert into t1 values (1), (0), (0), (3), (1); +select group_concat(distinct a) from t1; +select group_concat(distinct a order by a) from t1; +select group_concat(distinct a order by a desc) from t1; +drop table t1; + +create table t1(a bit(2), b varchar(10), c bit); +insert into t1 values (1, 'a', 0), (0, 'b', 1), (0, 'c', 0), (3, 'd', 1), +(1, 'e', 1), (3, 'f', 1), (0, 'g', 1); +select group_concat(distinct a, c) from t1; +select group_concat(distinct a, c order by a) from t1; +select group_concat(distinct a, c) from t1; +select group_concat(distinct a, c order by a, c) from t1; +select group_concat(distinct a, c order by a desc, c desc) from t1; + +drop table t1; + + --echo End of 5.0 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index c20d3fba705..48ad53fbf75 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3307,15 +3307,34 @@ bool Item_func_group_concat::setup(THD *thd) count_field_types(select_lex, tmp_table_param, all_fields, 0); 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 - if we are to store them in TREE objects used for ORDER BY and - DISTINCT. This leads to truncation if the BLOB's size exceeds - Field_varstring::MAX_SIZE. - */ if (arg_count_order > 0 || distinct) + { + /* + Currently we have to force conversion of BLOB values to VARCHAR's + if we are to store them in TREE objects used for ORDER BY and + DISTINCT. This leads to truncation if the BLOB's size exceeds + Field_varstring::MAX_SIZE. + */ set_if_smaller(tmp_table_param->convert_blob_length, Field_varstring::MAX_SIZE); + + /* + Force the create_tmp_table() to convert BIT columns to INT + as we cannot compare two table records containg BIT fields + stored in the the tree used for distinct/order by. + Moreover we don't even save in the tree record null bits + where BIT fields store parts of their data. + */ + List_iterator_fast li(all_fields); + Item *item; + while ((item= li++)) + { + if (item->type() == Item::FIELD_ITEM && + ((Item_field*) item)->field->type() == FIELD_TYPE_BIT) + item->marker= 4; + } + } + /* We have to create a temporary table to get descriptions of fields (types, sizes and so on). -- cgit v1.2.1