summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2006-04-12 23:05:38 +0400
committerunknown <evgen@moonbone.local>2006-04-12 23:05:38 +0400
commita2066982f1983e2675533d2f2db28fbaf77d2c24 (patch)
treef083605a57e3ffde293d12350970584f01465821 /sql
parentc2ee905473ca0b380c3b952a27691f3411592b8c (diff)
downloadmariadb-git-a2066982f1983e2675533d2f2db28fbaf77d2c24.tar.gz
Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was
used In a simple queries a result of the GROUP_CONCAT() function was always of varchar type. But if length of GROUP_CONCAT() result is greater than 512 chars and temporary table is used during select then the result is converted to blob, due to policy to not to store fields longer than 512 chars in tmp table as varchar fields. In order to provide consistent behaviour, result of GROUP_CONCAT() now will always be converted to blob if it is longer than 512 chars. Item_func_group_concat::field_type() is modified accordingly. mysql-test/t/func_gconcat.test: Added test case for bug#14169: type of group_concat() result changed to blob if tmp_table was used mysql-test/r/func_gconcat.result: Added test case for bug#14169: type of group_concat() result changed to blob if tmp_table was used sql/unireg.h: Added the CONVERT_IF_BIGGER_TO_BLOB constant sql/sql_select.cc: Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was used The unnamed constant 255 in the create_tmp_field() and create_tmp_field_from_item() functions now defined as the CONVERT_IF_BIGGER_TO_BLOB constant. The create_tmp_field() function now converts the Item_sum string result to a blob field based on its char length. sql/item_sum.h: Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was used To the Item_func_group_concat calls added the member function field_type() which returns the BLOB or VAR_STRING type based on the items length. sql/item_func.cc: Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was used In the Item_func::tmp_table_field() function the unnamed constant 255 is changed to the CONVERT_IF_BIGGER_TO_BLOB constant. The Item_func::tmp_table_field() function now measures the result length in chars rather than bytes when converting string result to a blob.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_sum.h7
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/unireg.h1
4 files changed, 13 insertions, 3 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d0d2eca7233..174a8c55d01 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -307,7 +307,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
break;
case STRING_RESULT:
- if (max_length > 255)
+ if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation);
else
res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation);
diff --git a/sql/item_sum.h b/sql/item_sum.h
index c972240fcba..0cc2a20faa3 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -729,6 +729,13 @@ class Item_func_group_concat : public Item_sum
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; }
virtual Item_result result_type () const { return STRING_RESULT; }
+ enum_field_types field_type() const
+ {
+ if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
+ return FIELD_TYPE_BLOB;
+ else
+ return MYSQL_TYPE_VAR_STRING;
+ }
void clear();
bool add();
void reset_field();
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d7aa617cffd..91fc808058f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4925,7 +4925,8 @@ static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
new_field= item->tmp_table_field_from_field_type(table);
- else if (item->max_length/item->collation.collation->mbmaxlen > 255)
+ else if (item->max_length/item->collation.collation->mbmaxlen >
+ CONVERT_IF_BIGGER_TO_BLOB)
{
if (convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null,
@@ -5028,7 +5029,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
return new Field_longlong(item_sum->max_length,maybe_null,
item->name,table,item->unsigned_flag);
case STRING_RESULT:
- if (item_sum->max_length > 255)
+ if (item_sum->max_length/item_sum->collation.collation->mbmaxlen >
+ CONVERT_IF_BIGGER_TO_BLOB)
{
if (convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null,
diff --git a/sql/unireg.h b/sql/unireg.h
index 70df9a89c8f..3fb30315c81 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -60,6 +60,7 @@
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FIELD_CHARLENGTH 255
+#define CONVERT_IF_BIGGER_TO_BLOB 255
/* Max column width +1 */
#define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1)