Commit 70c4eb58 authored by monty@mysql.com's avatar monty@mysql.com

Portability fixes

Fixed problems with group_concat() and HAVING
Updated crash-me values
parent 472e87a4
...@@ -1120,10 +1120,10 @@ typedef union { ...@@ -1120,10 +1120,10 @@ typedef union {
*((T)+1)=(((A) >> 16));\ *((T)+1)=(((A) >> 16));\
*((T)+0)=(((A) >> 24)); } *((T)+0)=(((A) >> 24)); }
#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double)) #define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double)) #define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong)) #define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong)) #define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
#else #else
......
...@@ -88,9 +88,9 @@ libmysqld.a: libmysqld_int.a $(INC_LIB) ...@@ -88,9 +88,9 @@ libmysqld.a: libmysqld_int.a $(INC_LIB)
cd tmp ; \ cd tmp ; \
for file in *.a ; do \ for file in *.a ; do \
bfile=`basename $$file .a` ; \ bfile=`basename $$file .a` ; \
ar x $$file; \ $(AR) x $$file; \
for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \ for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
ar q ../libmysqld_int2.a *.o ; \ $(AR) q ../libmysqld_int2.a *.o ; \
rm -f *.o ; \ rm -f *.o ; \
done done
mv libmysqld_int2.a libmysqld.a mv libmysqld_int2.a libmysqld.a
......
...@@ -59,11 +59,16 @@ grp group_concat(d order by a desc) ...@@ -59,11 +59,16 @@ grp group_concat(d order by a desc)
1 a 1 a
2 b,a 2 b,a
3 c,d,d,b,b,a 3 c,d,d,b,b,a
select grp,group_concat(a order by a,d+c) from t1 group by grp; select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp;
grp group_concat(a order by a,d+c) grp group_concat(a order by a,d+c-ascii(c)-a)
1 1 1 1
2 2,3 2 2,3
3 4,5,6,7,8,9 3 4,5,6,7,8,9
select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp;
grp group_concat(a order by d+c-ascii(c),a)
1 1
2 3,2
3 7,8,4,6,9,5
select grp,group_concat(c order by 1) from t1 group by grp; select grp,group_concat(c order by 1) from t1 group by grp;
grp group_concat(c order by 1) grp group_concat(c order by 1)
1 a 1 a
...@@ -197,9 +202,21 @@ NULL ...@@ -197,9 +202,21 @@ NULL
drop table t1; drop table t1;
drop table t2; drop table t2;
create table t1 (bar varchar(32)); create table t1 (bar varchar(32));
insert into t1 values('test'),('test2'); insert into t1 values('test1'),('test2');
select * from t1 having group_concat(bar)=''; select group_concat(bar order by concat(bar,bar)) from t1;
group_concat(bar order by concat(bar,bar))
test1,test2
select group_concat(bar order by concat(bar,bar) desc) from t1;
group_concat(bar order by concat(bar,bar) desc)
test2,test1
select bar from t1 having group_concat(bar)='';
bar
select bar from t1 having instr(group_concat(bar), "test") > 0;
bar
test1
select bar from t1 having instr(group_concat(bar order by concat(bar,bar) desc), "test2,test1") > 0;
bar bar
test1
drop table t1; drop table t1;
create table t1 (a int, a1 varchar(10)); create table t1 (a int, a1 varchar(10));
create table t2 (a0 int); create table t2 (a0 int);
...@@ -246,7 +263,7 @@ id1 concat_id ...@@ -246,7 +263,7 @@ id1 concat_id
drop table t1,t2; drop table t1,t2;
create table t1 (s1 char(10), s2 int not null); create table t1 (s1 char(10), s2 int not null);
insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4); insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4);
select distinct s1 from t1 order by s2; select distinct s1 from t1 order by s2,s1;
s1 s1
c c
a a
......
...@@ -29,7 +29,8 @@ select grp,group_concat(c order by c) from t1 group by grp; ...@@ -29,7 +29,8 @@ select grp,group_concat(c order by c) from t1 group by grp;
select grp,group_concat(c order by c desc) from t1 group by grp; select grp,group_concat(c order by c desc) from t1 group by grp;
select grp,group_concat(d order by a) from t1 group by grp; select grp,group_concat(d order by a) from t1 group by grp;
select grp,group_concat(d order by a desc) from t1 group by grp; select grp,group_concat(d order by a desc) from t1 group by grp;
select grp,group_concat(a order by a,d+c) from t1 group by grp; select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp;
select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp;
select grp,group_concat(c order by 1) from t1 group by grp; select grp,group_concat(c order by 1) from t1 group by grp;
select grp,group_concat(c order by "c") from t1 group by grp; select grp,group_concat(c order by "c") from t1 group by grp;
select grp,group_concat(distinct c order by c) from t1 group by grp; select grp,group_concat(distinct c order by c) from t1 group by grp;
...@@ -108,8 +109,12 @@ drop table t2; ...@@ -108,8 +109,12 @@ drop table t2;
# check having # check having
create table t1 (bar varchar(32)); create table t1 (bar varchar(32));
insert into t1 values('test'),('test2'); insert into t1 values('test1'),('test2');
select * from t1 having group_concat(bar)=''; select group_concat(bar order by concat(bar,bar)) from t1;
select group_concat(bar order by concat(bar,bar) desc) from t1;
select bar from t1 having group_concat(bar)='';
select bar from t1 having instr(group_concat(bar), "test") > 0;
select bar from t1 having instr(group_concat(bar order by concat(bar,bar) desc), "test2,test1") > 0;
drop table t1; drop table t1;
# ORDER BY fix_fields() # ORDER BY fix_fields()
...@@ -147,7 +152,7 @@ drop table t1,t2; ...@@ -147,7 +152,7 @@ drop table t1,t2;
create table t1 (s1 char(10), s2 int not null); create table t1 (s1 char(10), s2 int not null);
insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4); insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4);
select distinct s1 from t1 order by s2; select distinct s1 from t1 order by s2,s1;
select group_concat(distinct s1) from t1; select group_concat(distinct s1) from t1;
select group_concat(distinct s1 order by s2) from t1 where s2 < 4; select group_concat(distinct s1 order by s2) from t1 where s2 < 4;
# The following is wrong and needs to be fixed ASAP # The following is wrong and needs to be fixed ASAP
......
This diff is collapsed.
This diff is collapsed.
...@@ -2782,14 +2782,8 @@ int Field_double::cmp(const char *a_ptr, const char *b_ptr) ...@@ -2782,14 +2782,8 @@ int Field_double::cmp(const char *a_ptr, const char *b_ptr)
else else
#endif #endif
{ {
/* could this ALWAYS be 2 calls to doubleget() ?? */
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
doubleget(a, a_ptr); doubleget(a, a_ptr);
doubleget(b, b_ptr); doubleget(b, b_ptr);
#else
memcpy_fixed(&a,a_ptr,sizeof(double));
memcpy_fixed(&b,b_ptr,sizeof(double));
#endif
} }
return (a < b) ? -1 : (a > b) ? 1 : 0; return (a < b) ? -1 : (a > b) ? 1 : 0;
} }
...@@ -2809,12 +2803,7 @@ void Field_double::sort_string(char *to,uint length __attribute__((unused))) ...@@ -2809,12 +2803,7 @@ void Field_double::sort_string(char *to,uint length __attribute__((unused)))
} }
else else
#endif #endif
/* could this ALWAYS be 2 calls to doubleget() ?? */
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
doubleget(nr,ptr); doubleget(nr,ptr);
#else
memcpy_fixed(&nr,ptr,sizeof(nr));
#endif
change_double_for_sort(nr, (byte*) to); change_double_for_sort(nr, (byte*) to);
} }
......
...@@ -46,7 +46,5 @@ void unireg_init(ulong options) ...@@ -46,7 +46,5 @@ void unireg_init(ulong options)
log_10[i]= nr ; nr*= 10.0; log_10[i]= nr ; nr*= 10.0;
} }
specialflag|=options; /* Set options from argv */ specialflag|=options; /* Set options from argv */
thread_stack_min=thread_stack - STACK_MIN_SIZE;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1521,21 +1521,26 @@ String *Item_sum_udf_str::val_str(String *str) ...@@ -1521,21 +1521,26 @@ String *Item_sum_udf_str::val_str(String *str)
int group_concat_key_cmp_with_distinct(void* arg, byte* key1, int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
byte* key2) byte* key2)
{ {
Item_func_group_concat* item= (Item_func_group_concat*)arg; Item_func_group_concat* grp_item= (Item_func_group_concat*)arg;
uint *offset= item->field_offsets+ item->field_list_offset;
Item **field_item, **end; Item **field_item, **end;
char *record= (char*) grp_item->table->record[0];
for (field_item= item->args, end= field_item+item->arg_count_field; for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field;
field_item < end; field_item < end;
field_item++) field_item++)
{ {
Field *field= (*field_item)->real_item()->get_tmp_table_field(); /*
We have to use get_tmp_table_field() instead of
real_item()->get_tmp_table_field() because we want the field in
the temporary table, not the original field
*/
Field *field= (*field_item)->get_tmp_table_field();
if (field) if (field)
{ {
int res; int res;
if ((res= field->key_cmp(key1 + *offset, key2 + *offset))) uint offset= (uint) (field->ptr - record);
if ((res= field->key_cmp(key1 + offset, key2 + offset)))
return res; return res;
offset++;
} }
} }
return 0; return 0;
...@@ -1549,26 +1554,33 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1, ...@@ -1549,26 +1554,33 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
{ {
Item_func_group_concat* item= (Item_func_group_concat*)arg; Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
uint *offset= item->field_offsets;
ORDER **order_item, **end; ORDER **order_item, **end;
char *record= (char*) grp_item->table->record[0];
for (order_item= item->order, end=order_item+ item->arg_count_order; for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
order_item < end; order_item < end;
order_item++) order_item++)
{ {
Item *item= *(*order_item)->item; Item *item= *(*order_item)->item;
Field *field= item->real_item()->get_tmp_table_field(); /*
We have to use get_tmp_table_field() instead of
real_item()->get_tmp_table_field() because we want the field in
the temporary table, not the original field
*/
Field *field= item->get_tmp_table_field();
if (field) if (field)
{ {
int res= field->key_cmp(key1 + *offset, key2 + *offset); int res;
if (res) uint offset= (uint) (field->ptr - record);
if ((res= field->key_cmp(key1 + offset, key2 + offset)))
return (*order_item)->asc ? res : -res; return (*order_item)->asc ? res : -res;
offset++;
} }
} }
/* /*
We can't return 0 because tree class remove this item as double value. We can't return 0 because in that case the tree class would remove this
item as double value. This would cause problems for case-changes and
if the the returned values are not the same we do the sort on.
*/ */
return 1; return 1;
} }
...@@ -1601,10 +1613,10 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), ...@@ -1601,10 +1613,10 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
Item_func_group_concat *item) Item_func_group_concat *item)
{ {
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp((char *)&buff,sizeof(buff),default_charset_info); String tmp((char*) &buff, sizeof(buff), default_charset_info);
String tmp2((char *)&buff,sizeof(buff),default_charset_info); String tmp2((char *) &buff, sizeof(buff), default_charset_info);
uint *field_offsets= (item->field_offsets + char *record= (char*) item->table->record[0];
item->field_list_offset);
tmp.length(0); tmp.length(0);
for (uint i= 0; i < item->arg_count_field; i++) for (uint i= 0; i < item->arg_count_field; i++)
...@@ -1612,12 +1624,20 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), ...@@ -1612,12 +1624,20 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
Item *show_item= item->args[i]; Item *show_item= item->args[i];
if (!show_item->const_item()) if (!show_item->const_item())
{ {
Field *f= show_item->real_item()->get_tmp_table_field(); /*
char *sv= f->ptr; We have to use get_tmp_table_field() instead of
f->ptr= (char *) key + *(field_offsets++); real_item()->get_tmp_table_field() because we want the field in
String *res= f->val_str(&tmp,&tmp2); the temporary table, not the original field
*/
Field *field= show_item->get_tmp_table_field();
String *res;
char *save_ptr= field->ptr;
uint offset= (uint) (save_ptr - record);
DBUG_ASSERT(offset < item->table->reclength);
field->ptr= (char *) key + offset;
res= field->val_str(&tmp,&tmp2);
item->result.append(*res); item->result.append(*res);
f->ptr= sv; field->ptr= save_ptr;
} }
else else
{ {
...@@ -1660,7 +1680,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, ...@@ -1660,7 +1680,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
SQL_LIST *is_order, SQL_LIST *is_order,
String *is_separator) String *is_separator)
:Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0), :Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0),
warning_available(0), key_length(0), rec_offset(0), warning_available(0), key_length(0),
tree_mode(0), distinct(is_distinct), warning_for_row(0), tree_mode(0), distinct(is_distinct), warning_for_row(0),
separator(is_separator), tree(&tree_base), table(0), separator(is_separator), tree(&tree_base), table(0),
order(0), tables_list(0), order(0), tables_list(0),
...@@ -1685,14 +1705,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, ...@@ -1685,14 +1705,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
args - arg_count_field+arg_count_order args - arg_count_field+arg_count_order
(for possible order items in temporare tables) (for possible order items in temporare tables)
order - arg_count_order order - arg_count_order
field_offset For offset withing the key
*/ */
if (!(args= (Item**) sql_alloc((sizeof(Item*) + sizeof(uint)) * arg_count + if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
sizeof(ORDER*)*arg_count_order))) sizeof(ORDER*)*arg_count_order)))
return; return;
order= (ORDER**)(args + arg_count); order= (ORDER**)(args + arg_count);
field_offsets= (uint*) (order+ arg_count_order);
/* fill args items of show and sort */ /* fill args items of show and sort */
List_iterator_fast<Item> li(*is_select); List_iterator_fast<Item> li(*is_select);
...@@ -1723,7 +1741,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, ...@@ -1723,7 +1741,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
warning(item->warning), warning(item->warning),
warning_available(item->warning_available), warning_available(item->warning_available),
key_length(item->key_length), key_length(item->key_length),
rec_offset(item->rec_offset),
tree_mode(item->tree_mode), tree_mode(item->tree_mode),
distinct(item->distinct), distinct(item->distinct),
warning_for_row(item->warning_for_row), warning_for_row(item->warning_for_row),
...@@ -1731,7 +1748,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, ...@@ -1731,7 +1748,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
tree(item->tree), tree(item->tree),
table(item->table), table(item->table),
order(item->order), order(item->order),
field_offsets(item->field_offsets),
tables_list(item->tables_list), tables_list(item->tables_list),
group_concat_max_len(item->group_concat_max_len), group_concat_max_len(item->group_concat_max_len),
show_elements(item->show_elements), show_elements(item->show_elements),
...@@ -1817,39 +1833,36 @@ void Item_func_group_concat::clear() ...@@ -1817,39 +1833,36 @@ void Item_func_group_concat::clear()
bool Item_func_group_concat::add() bool Item_func_group_concat::add()
{ {
bool record_is_null;
if (always_null) if (always_null)
return 0; return 0;
copy_fields(tmp_table_param); copy_fields(tmp_table_param);
copy_funcs(tmp_table_param->items_to_copy); copy_funcs(tmp_table_param->items_to_copy);
record_is_null= TRUE;
for (uint i= 0; i < arg_count_field; i++) for (uint i= 0; i < arg_count_field; i++)
{ {
Item *show_item= args[i]; Item *show_item= args[i];
if (!show_item->const_item()) if (!show_item->const_item())
{ {
/*
Here we use real_item as we want the original field data that should
be written to table->record[0]
*/
Field *f= show_item->real_item()->get_tmp_table_field(); Field *f= show_item->real_item()->get_tmp_table_field();
if (!f->is_null()) if (f->is_null())
{ return 0; // Skip row if it contains null
record_is_null= FALSE;
break;
}
} }
} }
if (record_is_null)
return 0;
null_value= FALSE; null_value= FALSE;
if (tree_mode) if (tree_mode)
{ {
if (!tree_insert(tree, table->record[0] + rec_offset, 0, tree->custom_arg)) if (!tree_insert(tree, table->record[0], 0, tree->custom_arg))
return 1; return 1;
} }
else else
{ {
if (result.length() <= group_concat_max_len && !warning_for_row) if (result.length() <= group_concat_max_len && !warning_for_row)
dump_leaf_key(table->record[0] + rec_offset, 1, this); dump_leaf_key(table->record[0], 1, this);
} }
return 0; return 0;
} }
...@@ -1906,8 +1919,8 @@ bool Item_func_group_concat::setup(THD *thd) ...@@ -1906,8 +1919,8 @@ bool Item_func_group_concat::setup(THD *thd)
{ {
List<Item> list; List<Item> list;
SELECT_LEX *select_lex= thd->lex->current_select; SELECT_LEX *select_lex= thd->lex->current_select;
Field **field, **field_end; uint const_fields;
uint offset, *offsets, const_fields; byte *record;
qsort_cmp2 compare_key; qsort_cmp2 compare_key;
DBUG_ENTER("Item_func_group_concat::setup"); DBUG_ENTER("Item_func_group_concat::setup");
...@@ -1967,21 +1980,11 @@ bool Item_func_group_concat::setup(THD *thd) ...@@ -1967,21 +1980,11 @@ bool Item_func_group_concat::setup(THD *thd)
table->file->extra(HA_EXTRA_NO_ROWS); table->file->extra(HA_EXTRA_NO_ROWS);
table->no_rows= 1; table->no_rows= 1;
field_end= (field= table->field) + table->fields; key_length= table->reclength;
offsets= field_offsets; record= table->record[0];
offset= 0;
for (key_length= 0; field < field_end; field++)
{
uint32 length= (*field)->pack_length();
(*offsets++)= offset;
offset+= length;
key_length += length;
}
/* Offset to first result field in table */ /* Offset to first result field in table */
field_list_offset= table->fields - (list.elements - const_fields); field_list_offset= table->fields - (list.elements - const_fields);
/* Offset to first field */
rec_offset= (uint) (table->field[0]->ptr - table->record[0]);
if (tree_mode) if (tree_mode)
delete_tree(tree); delete_tree(tree);
......
...@@ -681,7 +681,6 @@ class Item_func_group_concat : public Item_sum ...@@ -681,7 +681,6 @@ class Item_func_group_concat : public Item_sum
MYSQL_ERROR *warning; MYSQL_ERROR *warning;
bool warning_available; bool warning_available;
uint key_length; uint key_length;
int rec_offset;
bool tree_mode; bool tree_mode;
bool distinct; bool distinct;
bool warning_for_row; bool warning_for_row;
...@@ -704,7 +703,6 @@ class Item_func_group_concat : public Item_sum ...@@ -704,7 +703,6 @@ class Item_func_group_concat : public Item_sum
TREE *tree; TREE *tree;
TABLE *table; TABLE *table;
ORDER **order; ORDER **order;
uint *field_offsets;
TABLE_LIST *tables_list; TABLE_LIST *tables_list;
ulong group_concat_max_len; ulong group_concat_max_len;
uint show_elements; uint show_elements;
......
...@@ -2527,6 +2527,8 @@ int main(int argc, char **argv) ...@@ -2527,6 +2527,8 @@ int main(int argc, char **argv)
} }
} }
#endif #endif
thread_stack_min=thread_stack - STACK_MIN_SIZE;
(void) thr_setconcurrency(concurrency); // 10 by default (void) thr_setconcurrency(concurrency); // 10 by default
/* /*
......
...@@ -3717,6 +3717,10 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) ...@@ -3717,6 +3717,10 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables)
#define used_stack(A,B) (long) (B - A) #define used_stack(A,B) (long) (B - A)
#endif #endif
#ifndef DBUG_OFF
long max_stack_used;
#endif
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
bool check_stack_overrun(THD *thd,char *buf __attribute__((unused))) bool check_stack_overrun(THD *thd,char *buf __attribute__((unused)))
{ {
...@@ -3729,6 +3733,9 @@ bool check_stack_overrun(THD *thd,char *buf __attribute__((unused))) ...@@ -3729,6 +3733,9 @@ bool check_stack_overrun(THD *thd,char *buf __attribute__((unused)))
thd->fatal_error(); thd->fatal_error();
return 1; return 1;
} }
#ifndef DBUG_OFF
max_stack_used= max(max_stack_used, stack_used);
#endif
return 0; return 0;
} }
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
......
...@@ -8402,12 +8402,11 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, ...@@ -8402,12 +8402,11 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
Item *pos; Item *pos;
List_iterator_fast<Item> li(all_fields); List_iterator_fast<Item> li(all_fields);
Copy_field *copy; Copy_field *copy;
DBUG_ENTER("setup_copy_fields");
res_selected_fields.empty(); res_selected_fields.empty();
res_all_fields.empty(); res_all_fields.empty();
List_iterator_fast<Item> itr(res_all_fields); List_iterator_fast<Item> itr(res_all_fields);
uint i, border= all_fields.elements - elements; uint i, border= all_fields.elements - elements;
DBUG_ENTER("setup_copy_fields");
if (!(copy=param->copy_field= new Copy_field[param->field_count])) if (!(copy=param->copy_field= new Copy_field[param->field_count]))
goto err2; goto err2;
......
...@@ -3063,11 +3063,15 @@ sum_expr: ...@@ -3063,11 +3063,15 @@ sum_expr:
{ $$=new Item_sum_variance($3); } { $$=new Item_sum_variance($3); }
| SUM_SYM '(' in_sum_expr ')' | SUM_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_sum($3); } { $$=new Item_sum_sum($3); }
| GROUP_CONCAT_SYM '(' opt_distinct expr_list opt_gorder_clause | GROUP_CONCAT_SYM '(' opt_distinct
opt_gconcat_separator ')' { Select->in_sum_expr++; }
expr_list opt_gorder_clause
opt_gconcat_separator
')'
{ {
$$=new Item_func_group_concat($3,$4,Select->gorder_list,$6); Select->in_sum_expr--;
$4->empty(); $$=new Item_func_group_concat($3,$5,Select->gorder_list,$7);
$5->empty();
}; };
opt_distinct: opt_distinct:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment