summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <df@pippilotta.erinye.com>2007-05-02 19:37:42 +0200
committerunknown <df@pippilotta.erinye.com>2007-05-02 19:37:42 +0200
commit42bac4a39f2b823b304b8ff600a9bcfe7064f871 (patch)
tree454f671c61db5d2de51819df9f00b5fd2355f9bc
parentb93f80411507ff8283644e3c50f5bd8c013f4493 (diff)
parent9094bead96931396daffbf00379dbef89cd6f626 (diff)
downloadmariadb-git-42bac4a39f2b823b304b8ff600a9bcfe7064f871.tar.gz
Merge pippilotta.erinye.com:/shared/home/df/mysql/build/mysql-4.1-build
into pippilotta.erinye.com:/shared/home/df/mysql/build/mysql-4.1-build-work
-rw-r--r--mysql-test/r/alter_table.result5
-rw-r--r--mysql-test/r/heap.result2
-rw-r--r--mysql-test/r/innodb_mysql.result33
-rw-r--r--mysql-test/r/olap.result61
-rw-r--r--mysql-test/t/alter_table.test11
-rw-r--r--mysql-test/t/innodb_mysql.test30
-rw-r--r--mysql-test/t/olap.test19
-rw-r--r--mysys/my_error.c13
-rw-r--r--sql/field.cc41
-rw-r--r--sql/field.h48
-rw-r--r--sql/item_func.h25
-rw-r--r--sql/key.cc23
-rw-r--r--sql/sql_select.cc28
13 files changed, 307 insertions, 32 deletions
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index da5cf688325..8957e1ee7a1 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -803,3 +803,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
alter table table_24562 order by no_such_col;
ERROR 42S22: Unknown column 'no_such_col' in 'order clause'
drop table table_24562;
+CREATE TABLE t1 (c1 CHAR(255));
+INSERT INTO t1 VALUES (REPEAT("x", 255)), (REPEAT("x", 255));
+ALTER TABLE t1 ADD UNIQUE (c1);
+ERROR 23000: Duplicate entry 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' for key 1
+DROP TABLE t1;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 6bb9d0c87ee..b19ccca2f44 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -294,7 +294,7 @@ drop table t1;
create table t1 (c char(255), primary key(c(90)));
insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
-ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1
+ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1
drop table t1;
CREATE TABLE t1 (a int, key(a)) engine=heap;
insert into t1 values (0);
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 2cd6f7826ca..12c8b414d2d 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -128,4 +128,37 @@ show /*!50002 GLOBAL */ status like 'Handler_rollback';
Variable_name Value
Handler_rollback 0
drop table t1;
+CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1 cnt
+1a 1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1 cnt
+1a 2
+DROP TABLE t1;
+CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1 cnt
+1a 1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1 cnt
+1a 2
+DROP TABLE t1;
+CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+c1 cnt
+1a 1
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+c1 cnt
+1a 2
+DROP TABLE t1;
End of 4.1 tests
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index 74b7570ea2a..0300fc1759e 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -556,3 +556,64 @@ x a sum(b)
2006-07-01 NULL 11
NULL NULL 11
drop table t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1
+VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10);
+SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
+a SUM(b)
+1 30
+2 90
+3 30
+NULL 150
+SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
+a SUM(b)
+1 30
+2 90
+3 30
+NULL 150
+SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP;
+a b COUNT(*)
+1 10 1
+1 20 1
+1 NULL 2
+2 10 2
+2 30 1
+2 40 1
+2 NULL 4
+3 30 1
+3 NULL 1
+NULL NULL 7
+SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP;
+a b COUNT(*)
+1 10 1
+1 20 1
+1 NULL 2
+2 10 2
+2 30 1
+2 40 1
+2 NULL 4
+3 30 1
+3 NULL 1
+NULL NULL 7
+SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+x a SUM(b)
+x 1 30
+x 2 90
+x 3 30
+x NULL 150
+NULL NULL 150
+SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+x a SUM(b)
+x 1 30
+x 2 90
+x 3 30
+x NULL 150
+NULL NULL 150
+SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+x a SUM(b)
+x 1 30
+x 2 90
+x 3 30
+x NULL 150
+NULL NULL 150
+DROP TABLE t1;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 52a569dfb57..874c42ac0b6 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -583,5 +583,16 @@ alter table table_24562 order by no_such_col;
drop table table_24562;
+#
+# Bug #20710: adding unique index of column with duplicated
+# long values to reproduce error message with truncated key value.
+#
+
+CREATE TABLE t1 (c1 CHAR(255));
+INSERT INTO t1 VALUES (REPEAT("x", 255)), (REPEAT("x", 255));
+--error 1062
+ALTER TABLE t1 ADD UNIQUE (c1);
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index c5a5e997775..0973385dc5b 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -161,4 +161,34 @@ show /*!50002 GLOBAL */ status like 'Handler_rollback';
connection default;
drop table t1;
disconnect con1;
+
+#
+# Bug #13191: INSERT...ON DUPLICATE KEY UPDATE of UTF-8 string fields
+# used in partial unique indices.
+#
+
+CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
+ ENGINE=INNODB CHARACTER SET UTF8;
+INSERT INTO t1 (c1) VALUES ('1a');
+SELECT * FROM t1;
+INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
--echo End of 4.1 tests
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
index 683e1402678..61c1bd45e5f 100644
--- a/mysql-test/t/olap.test
+++ b/mysql-test/t/olap.test
@@ -281,4 +281,23 @@ select left(a,10), a, sum(b) from t1 group by 1,2 with rollup;
select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
drop table t1;
+#
+# Bug #24856: ROLLUP by const item in a query with DISTINCT
+#
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1
+ VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10);
+
+SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
+SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
+SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP;
+SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP;
+
+SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP;
+
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 8a377f63c7e..0f8ffb7c05f 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -82,6 +82,11 @@ int my_error(int nr,myf MyFlags, ...)
If "%.*u" or "%.*d" are encountered, the precision number is read
from the variable argument list but its value is ignored.
*/
+ if (*tpos == '-')
+ {
+ tpos++;
+ olen--;
+ }
prec_supplied= 0;
if (*tpos== '.')
{
@@ -94,6 +99,14 @@ int my_error(int nr,myf MyFlags, ...)
prec_chars= va_arg(ap, int); /* get length parameter */
prec_supplied= 1;
}
+ else
+ {
+ for (prec_chars= 0; my_isdigit(&my_charset_latin1, *tpos); tpos++, olen--)
+ {
+ prec_supplied= 1;
+ prec_chars= prec_chars * 10 + *tpos - '0';
+ }
+ }
}
if (!prec_supplied)
diff --git a/sql/field.cc b/sql/field.cc
index acc837c1d37..1b27e12e078 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5204,6 +5204,16 @@ uint Field_string::max_packed_col_length(uint max_length)
return (max_length > 255 ? 2 : 1)+max_length;
}
+uint Field_string::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+ imagetype type_arg)
+{
+ uint bytes = my_charpos(cs, ptr, ptr + field_length,
+ length / field_charset->mbmaxlen);
+ memcpy(buff, ptr, bytes);
+ if (bytes < length)
+ bzero(buff + bytes, length - bytes);
+ return bytes;
+}
/****************************************************************************
** VARCHAR type (Not available for the end user yet)
@@ -5414,8 +5424,8 @@ uint Field_varstring::max_packed_col_length(uint max_length)
return (max_length > 255 ? 2 : 1)+max_length;
}
-void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
- imagetype type)
+uint Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+ imagetype type)
{
uint f_length=uint2korr(ptr);
if (f_length > length)
@@ -5426,6 +5436,7 @@ void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
if (f_length < length)
bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
#endif
+ return HA_KEY_BLOB_LENGTH+f_length;
}
void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
@@ -5724,8 +5735,8 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
/* The following is used only when comparing a key */
-void Field_blob::get_key_image(char *buff,uint length,
- CHARSET_INFO *cs, imagetype type)
+uint Field_blob::get_key_image(char *buff,uint length,
+ CHARSET_INFO *cs, imagetype type)
{
uint32 blob_length= get_length(ptr);
char *blob;
@@ -5737,16 +5748,17 @@ void Field_blob::get_key_image(char *buff,uint length,
MBR mbr;
Geometry_buffer buffer;
Geometry *gobj;
+ const uint image_length= SIZEOF_STORED_DOUBLE*4;
if (blob_length < SRID_SIZE)
{
- bzero(buff, SIZEOF_STORED_DOUBLE*4);
- return;
+ bzero(buff, image_length);
+ return image_length;
}
get_ptr(&blob);
gobj= Geometry::construct(&buffer, blob, blob_length);
if (gobj->get_mbr(&mbr, &dummy))
- bzero(buff, SIZEOF_STORED_DOUBLE*4);
+ bzero(buff, image_length);
else
{
float8store(buff, mbr.xmin);
@@ -5754,7 +5766,7 @@ void Field_blob::get_key_image(char *buff,uint length,
float8store(buff+16, mbr.ymin);
float8store(buff+24, mbr.ymax);
}
- return;
+ return image_length;
}
#endif /*HAVE_SPATIAL*/
@@ -5774,6 +5786,7 @@ void Field_blob::get_key_image(char *buff,uint length,
}
int2store(buff,length);
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
+ return HA_KEY_BLOB_LENGTH+length;
}
void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
@@ -6021,8 +6034,8 @@ uint Field_blob::max_packed_col_length(uint max_length)
#ifdef HAVE_SPATIAL
-void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
- imagetype type)
+uint Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+ imagetype type)
{
char *blob;
const char *dummy;
@@ -6030,16 +6043,17 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
ulong blob_length= get_length(ptr);
Geometry_buffer buffer;
Geometry *gobj;
+ const uint image_length= SIZEOF_STORED_DOUBLE*4;
if (blob_length < SRID_SIZE)
{
- bzero(buff, SIZEOF_STORED_DOUBLE*4);
- return;
+ bzero(buff, image_length);
+ return image_length;
}
get_ptr(&blob);
gobj= Geometry::construct(&buffer, blob, blob_length);
if (gobj->get_mbr(&mbr, &dummy))
- bzero(buff, SIZEOF_STORED_DOUBLE*4);
+ bzero(buff, image_length);
else
{
float8store(buff, mbr.xmin);
@@ -6047,6 +6061,7 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
float8store(buff + 16, mbr.ymin);
float8store(buff + 24, mbr.ymax);
}
+ return image_length;
}
diff --git a/sql/field.h b/sql/field.h
index 58177747120..20f1209a439 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -228,9 +228,43 @@ public:
{ memcpy(buff,ptr,length); }
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); }
- virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
- imagetype type)
- { get_image(buff,length,cs); }
+
+
+ /*
+ Copy a field part into an output buffer.
+
+ SYNOPSIS
+ Field::get_key_image()
+ buff [out] output buffer
+ length output buffer size
+ cs charset, always same as this->charset(),
+ (to be removed in 5.x)
+ type itMBR for geometry blobs, otherwise itRAW
+
+ DESCRIPTION
+ This function makes a copy of field part of size equal to or
+ less than "length" parameter value.
+ For fields of string types (CHAR, VARCHAR, TEXT) the rest of buffer
+ is padded by zero byte.
+
+ NOTES
+ For variable length character fields (i.e. UTF-8) the "length"
+ parameter means a number of output buffer bytes as if all field
+ characters have maximal possible size (mbmaxlen). In the other words,
+ "length" parameter is a number of characters multiplied by
+ field_charset->mbmaxlen.
+
+ RETURN
+ Number of copied bytes (excluding padded zero bytes -- see above).
+ */
+
+ virtual uint get_key_image(char *buff, uint length,
+ CHARSET_INFO *cs,
+ imagetype type)
+ {
+ get_image(buff,length,cs);
+ return length;
+ }
virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{ set_image(buff,length,cs); }
inline longlong val_int_offset(uint row_offset)
@@ -947,6 +981,8 @@ public:
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
+ virtual uint get_key_image(char *buff,uint length, CHARSET_INFO *cs,
+ imagetype type);
};
@@ -981,7 +1017,7 @@ public:
String *val_str(String*,String *);
int cmp(const char *,const char*);
void sort_string(char *buff,uint length);
- void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
+ uint get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const;
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
@@ -1060,7 +1096,7 @@ public:
store_length(length);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
}
- void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
+ uint get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const;
inline bool copy()
@@ -1117,7 +1153,7 @@ public:
int store(longlong nr) { return 1; }
int reset(void) { return !maybe_null() || Field_blob::reset(); }
- void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
+ uint get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
};
#endif /*HAVE_SPATIAL*/
diff --git a/sql/item_func.h b/sql/item_func.h
index 467b88eda76..ebe3a589aa1 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -590,6 +590,31 @@ public:
};
+/*
+ Objects of this class are used for ROLLUP queries to wrap up
+ each constant item referred to in GROUP BY list.
+*/
+
+class Item_func_rollup_const :public Item_func
+{
+public:
+ Item_func_rollup_const(Item *a) :Item_func(a)
+ { name= a->name; }
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ String *val_str(String *str) { return args[0]->val_str(str); }
+ const char *func_name() const { return "rollup_const"; }
+ bool const_item() const { return 0; }
+ Item_result result_type() const { return args[0]->result_type(); }
+ void fix_length_and_dec()
+ {
+ collation= args[0]->collation;
+ max_length= args[0]->max_length;
+ decimals=args[0]->decimals;
+ }
+};
+
+
class Item_func_length :public Item_int_func
{
String value;
diff --git a/sql/key.cc b/sql/key.cc
index 7ddd40de2c9..5bb389fcb45 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -89,20 +89,21 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
}
if (key_part->key_part_flag & HA_BLOB_PART)
{
- char *pos;
- ulong blob_length=((Field_blob*) key_part->field)->get_length();
- key_length-=2;
- ((Field_blob*) key_part->field)->get_ptr(&pos);
- length=min(key_length,key_part->length);
- set_if_smaller(blob_length,length);
- int2store(key,(uint) blob_length);
- key+=2; // Skip length info
- memcpy(key,pos,blob_length);
+ key_length-= HA_KEY_BLOB_LENGTH;
+ length= min(key_length, key_part->length);
+ key_part->field->get_key_image((char *) key, length,
+ key_part->field->charset(),
+ Field::itRAW);
+ key+= HA_KEY_BLOB_LENGTH;
}
else
{
- length=min(key_length,key_part->length);
- memcpy(key,table->record[0]+key_part->offset,(size_t) length);
+ length= min(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image((char *) key, length, cs, Field::itRAW);
+ if (bytes < length)
+ cs->cset->fill(cs, (char *) key + bytes, length - bytes, ' ');
}
key+=length;
key_length-=length;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index af3ad782ee3..36a15841065 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9754,7 +9754,7 @@ bool JOIN::rollup_init()
for (j=0 ; j < fields_list.elements ; j++)
rollup.fields[i].push_back(rollup.null_items[i]);
}
- List_iterator_fast<Item> it(all_fields);
+ List_iterator<Item> it(all_fields);
Item *item;
while ((item= it++))
{
@@ -9767,6 +9767,32 @@ bool JOIN::rollup_init()
{
item->maybe_null= 1;
found_in_group= 1;
+ if (item->const_item())
+ {
+ /*
+ For ROLLUP queries each constant item referenced in GROUP BY list
+ is wrapped up into an Item_func object yielding the same value
+ as the constant item. The objects of the wrapper class are never
+ considered as constant items and besides they inherit all
+ properties of the Item_result_field class.
+ This wrapping allows us to ensure writing constant items
+ into temporary tables whenever the result of the ROLLUP
+ operation has to be written into a temporary table, e.g. when
+ ROLLUP is used together with DISTINCT in the SELECT list.
+ Usually when creating temporary tables for a intermidiate
+ result we do not include fields for constant expressions.
+ */
+ Item* new_item= new Item_func_rollup_const(item);
+ if (!new_item)
+ return 1;
+ new_item->fix_fields(thd,0, (Item **) 0);
+ thd->change_item_tree(it.ref(), new_item);
+ for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
+ {
+ if (*tmp->item == item)
+ thd->change_item_tree(tmp->item, new_item);
+ }
+ }
}
}
if (item->type() == Item::FUNC_ITEM && !found_in_group)