mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge mysql.com:/usr/home/bar/mysql-4.1.b10201
into mysql.com:/usr/home/bar/mysql-5.0 mysql-test/r/func_gconcat.result: Auto merged mysql-test/t/func_gconcat.test: Auto merged ndb/src/mgmapi/mgmapi.cpp: Auto merged ndb/src/mgmsrv/ConfigInfo.cpp: Auto merged ndb/src/mgmsrv/ConfigInfo.hpp: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_func.h: Auto merged sql/item_sum.cc: Auto merged include/config-netware.h: auto merge fix libmysql/libmysql.def: after merge fix sql/item_func.cc: SCCS merged
This commit is contained in:
@ -46,6 +46,7 @@ extern "C" {
|
|||||||
#undef HAVE_SYS_MMAN_H
|
#undef HAVE_SYS_MMAN_H
|
||||||
#undef HAVE_SYNCH_H
|
#undef HAVE_SYNCH_H
|
||||||
#undef HAVE_MMAP
|
#undef HAVE_MMAP
|
||||||
|
#undef HAVE_RINT
|
||||||
|
|
||||||
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
|
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
|
||||||
#define HAVE_PTHREAD_SIGMASK 1
|
#define HAVE_PTHREAD_SIGMASK 1
|
||||||
|
@ -148,6 +148,7 @@ EXPORTS
|
|||||||
mysql_embedded
|
mysql_embedded
|
||||||
mysql_server_init
|
mysql_server_init
|
||||||
mysql_server_end
|
mysql_server_end
|
||||||
|
get_defaults_files
|
||||||
mysql_set_character_set
|
mysql_set_character_set
|
||||||
mysql_get_character_set_info
|
mysql_get_character_set_info
|
||||||
get_defaults_options
|
get_defaults_options
|
||||||
|
@ -445,6 +445,30 @@ group_concat(distinct b order by b)
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1260 2 line(s) were cut by GROUP_CONCAT()
|
Warning 1260 2 line(s) were cut by GROUP_CONCAT()
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci,
|
||||||
|
b varchar(255) character set koi8r);
|
||||||
|
insert into t1 values ('xxx','yyy');
|
||||||
|
select collation(a) from t1;
|
||||||
|
collation(a)
|
||||||
|
cp1250_general_ci
|
||||||
|
select collation(group_concat(a)) from t1;
|
||||||
|
collation(group_concat(a))
|
||||||
|
cp1250_general_ci
|
||||||
|
create table t2 select group_concat(a) as a from t1;
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` longtext character set cp1250
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
select collation(group_concat(a,_koi8r'test')) from t1;
|
||||||
|
collation(group_concat(a,_koi8r'test'))
|
||||||
|
cp1250_general_ci
|
||||||
|
select collation(group_concat(a,_koi8r 0xC1C2)) from t1;
|
||||||
|
ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation 'group_concat'
|
||||||
|
select collation(group_concat(a,b)) from t1;
|
||||||
|
ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,IMPLICIT) for operation 'group_concat'
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
||||||
CREATE TABLE t1 (id int);
|
CREATE TABLE t1 (id int);
|
||||||
SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL;
|
SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL;
|
||||||
gc
|
gc
|
||||||
|
@ -263,6 +263,24 @@ select group_concat(distinct b order by b) from t1 group by a;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#10201
|
||||||
|
#
|
||||||
|
create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci,
|
||||||
|
b varchar(255) character set koi8r);
|
||||||
|
insert into t1 values ('xxx','yyy');
|
||||||
|
select collation(a) from t1;
|
||||||
|
select collation(group_concat(a)) from t1;
|
||||||
|
create table t2 select group_concat(a) as a from t1;
|
||||||
|
show create table t2;
|
||||||
|
select collation(group_concat(a,_koi8r'test')) from t1;
|
||||||
|
--error 1267
|
||||||
|
select collation(group_concat(a,_koi8r 0xC1C2)) from t1;
|
||||||
|
--error 1267
|
||||||
|
select collation(group_concat(a,b)) from t1;
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
# bug #7769: group_concat returning null is checked in having
|
# bug #7769: group_concat returning null is checked in having
|
||||||
#
|
#
|
||||||
|
164
sql/item.cc
164
sql/item.cc
@ -1082,6 +1082,170 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************/
|
||||||
|
static
|
||||||
|
void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname)
|
||||||
|
{
|
||||||
|
my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
|
||||||
|
c1.collation->name,c1.derivation_name(),
|
||||||
|
c2.collation->name,c2.derivation_name(),
|
||||||
|
fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void my_coll_agg_error(DTCollation &c1, DTCollation &c2, DTCollation &c3,
|
||||||
|
const char *fname)
|
||||||
|
{
|
||||||
|
my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0),
|
||||||
|
c1.collation->name,c1.derivation_name(),
|
||||||
|
c2.collation->name,c2.derivation_name(),
|
||||||
|
c3.collation->name,c3.derivation_name(),
|
||||||
|
fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void my_coll_agg_error(Item** args, uint count, const char *fname)
|
||||||
|
{
|
||||||
|
if (count == 2)
|
||||||
|
my_coll_agg_error(args[0]->collation, args[1]->collation, fname);
|
||||||
|
else if (count == 3)
|
||||||
|
my_coll_agg_error(args[0]->collation, args[1]->collation,
|
||||||
|
args[2]->collation, fname);
|
||||||
|
else
|
||||||
|
my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool agg_item_collations(DTCollation &c, const char *fname,
|
||||||
|
Item **av, uint count, uint flags)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
c.set(av[0]->collation);
|
||||||
|
for (i= 1; i < count; i++)
|
||||||
|
{
|
||||||
|
if (c.aggregate(av[i]->collation, flags))
|
||||||
|
{
|
||||||
|
my_coll_agg_error(av, count, fname);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flags & MY_COLL_DISALLOW_NONE) &&
|
||||||
|
c.derivation == DERIVATION_NONE)
|
||||||
|
{
|
||||||
|
my_coll_agg_error(av, count, fname);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
|
||||||
|
Item **av, uint count, uint flags)
|
||||||
|
{
|
||||||
|
return (agg_item_collations(c, fname, av, count,
|
||||||
|
flags | MY_COLL_DISALLOW_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect arguments' character sets together.
|
||||||
|
We allow to apply automatic character set conversion in some cases.
|
||||||
|
The conditions when conversion is possible are:
|
||||||
|
- arguments A and B have different charsets
|
||||||
|
- A wins according to coercibility rules
|
||||||
|
(i.e. a column is stronger than a string constant,
|
||||||
|
an explicit COLLATE clause is stronger than a column)
|
||||||
|
- character set of A is either superset for character set of B,
|
||||||
|
or B is a string constant which can be converted into the
|
||||||
|
character set of A without data loss.
|
||||||
|
|
||||||
|
If all of the above is true, then it's possible to convert
|
||||||
|
B into the character set of A, and then compare according
|
||||||
|
to the collation of A.
|
||||||
|
|
||||||
|
For functions with more than two arguments:
|
||||||
|
|
||||||
|
collect(A,B,C) ::= collect(collect(A,B),C)
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool agg_item_charsets(DTCollation &coll, const char *fname,
|
||||||
|
Item **args, uint nargs, uint flags)
|
||||||
|
{
|
||||||
|
Item **arg, **last, *safe_args[2];
|
||||||
|
if (agg_item_collations(coll, fname, args, nargs, flags))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
For better error reporting: save the first and the second argument.
|
||||||
|
We need this only if the the number of args is 3 or 2:
|
||||||
|
- for a longer argument list, "Illegal mix of collations"
|
||||||
|
doesn't display each argument's characteristics.
|
||||||
|
- if nargs is 1, then this error cannot happen.
|
||||||
|
*/
|
||||||
|
if (nargs >=2 && nargs <= 3)
|
||||||
|
{
|
||||||
|
safe_args[0]= args[0];
|
||||||
|
safe_args[1]= args[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
THD *thd= current_thd;
|
||||||
|
Item_arena *arena, backup;
|
||||||
|
bool res= FALSE;
|
||||||
|
/*
|
||||||
|
In case we're in statement prepare, create conversion item
|
||||||
|
in its memory: it will be reused on each execute.
|
||||||
|
*/
|
||||||
|
arena= thd->change_arena_if_needed(&backup);
|
||||||
|
|
||||||
|
for (arg= args, last= args + nargs; arg < last; arg++)
|
||||||
|
{
|
||||||
|
Item* conv;
|
||||||
|
uint32 dummy_offset;
|
||||||
|
if (!String::needs_conversion(0, coll.collation,
|
||||||
|
(*arg)->collation.collation,
|
||||||
|
&dummy_offset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(conv= (*arg)->safe_charset_converter(coll.collation)))
|
||||||
|
{
|
||||||
|
if (nargs >=2 && nargs <= 3)
|
||||||
|
{
|
||||||
|
/* restore the original arguments for better error message */
|
||||||
|
args[0]= safe_args[0];
|
||||||
|
args[1]= safe_args[1];
|
||||||
|
}
|
||||||
|
my_coll_agg_error(args, nargs, fname);
|
||||||
|
res= TRUE;
|
||||||
|
break; // we cannot return here, we need to restore "arena".
|
||||||
|
}
|
||||||
|
conv->fix_fields(thd, 0, &conv);
|
||||||
|
/*
|
||||||
|
If in statement prepare, then we create a converter for two
|
||||||
|
constant items, do it once and then reuse it.
|
||||||
|
If we're in execution of a prepared statement, arena is NULL,
|
||||||
|
and the conv was created in runtime memory. This can be
|
||||||
|
the case only if the argument is a parameter marker ('?'),
|
||||||
|
because for all true constants the charset converter has already
|
||||||
|
been created in prepare. In this case register the change for
|
||||||
|
rollback.
|
||||||
|
*/
|
||||||
|
if (arena)
|
||||||
|
*arg= conv;
|
||||||
|
else
|
||||||
|
thd->change_item_tree(arg, conv);
|
||||||
|
}
|
||||||
|
if (arena)
|
||||||
|
thd->restore_backup_item_arena(arena, &backup);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************/
|
||||||
|
|
||||||
Item_field::Item_field(Field *f)
|
Item_field::Item_field(Field *f)
|
||||||
:Item_ident(0, NullS, *f->table_name, f->field_name),
|
:Item_ident(0, NullS, *f->table_name, f->field_name),
|
||||||
item_equal(0), no_const_subst(0),
|
item_equal(0), no_const_subst(0),
|
||||||
|
@ -767,6 +767,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool agg_item_collations(DTCollation &c, const char *name,
|
||||||
|
Item **items, uint nitems, uint flags= 0);
|
||||||
|
bool agg_item_collations_for_comparison(DTCollation &c, const char *name,
|
||||||
|
Item **items, uint nitems,
|
||||||
|
uint flags= 0);
|
||||||
|
bool agg_item_charsets(DTCollation &c, const char *name,
|
||||||
|
Item **items, uint nitems, uint flags= 0);
|
||||||
|
|
||||||
|
|
||||||
class Item_num: public Item
|
class Item_num: public Item
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
168
sql/item_func.cc
168
sql/item_func.cc
@ -42,73 +42,6 @@ bool check_reserved_words(LEX_STRING *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
|
|
||||||
const char *fname)
|
|
||||||
{
|
|
||||||
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
|
|
||||||
c1.collation->name, c1.derivation_name(),
|
|
||||||
c2.collation->name, c2.derivation_name(),
|
|
||||||
fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void my_coll_agg_error(DTCollation &c1,
|
|
||||||
DTCollation &c2,
|
|
||||||
DTCollation &c3,
|
|
||||||
const char *fname)
|
|
||||||
{
|
|
||||||
my_error(ER_CANT_AGGREGATE_3COLLATIONS, MYF(0),
|
|
||||||
c1.collation->name, c1.derivation_name(),
|
|
||||||
c2.collation->name, c2.derivation_name(),
|
|
||||||
c3.collation->name, c3.derivation_name(),
|
|
||||||
fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void my_coll_agg_error(Item** args, uint count, const char *fname)
|
|
||||||
{
|
|
||||||
if (count == 2)
|
|
||||||
my_coll_agg_error(args[0]->collation, args[1]->collation, fname);
|
|
||||||
else if (count == 3)
|
|
||||||
my_coll_agg_error(args[0]->collation,
|
|
||||||
args[1]->collation,
|
|
||||||
args[2]->collation,
|
|
||||||
fname);
|
|
||||||
else
|
|
||||||
my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count,
|
|
||||||
uint flags)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
c.set(av[0]->collation);
|
|
||||||
for (i= 1; i < count; i++)
|
|
||||||
{
|
|
||||||
if (c.aggregate(av[i]->collation, flags))
|
|
||||||
{
|
|
||||||
my_coll_agg_error(av, count, func_name());
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((flags & MY_COLL_DISALLOW_NONE) &&
|
|
||||||
c.derivation == DERIVATION_NONE)
|
|
||||||
{
|
|
||||||
my_coll_agg_error(av, count, func_name());
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
|
|
||||||
Item **av, uint count,
|
|
||||||
uint flags)
|
|
||||||
{
|
|
||||||
return (agg_arg_collations(c, av, count, flags | MY_COLL_DISALLOW_NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* return TRUE if item is a constant */
|
/* return TRUE if item is a constant */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -118,107 +51,6 @@ eval_const_cond(COND *cond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Collect arguments' character sets together.
|
|
||||||
We allow to apply automatic character set conversion in some cases.
|
|
||||||
The conditions when conversion is possible are:
|
|
||||||
- arguments A and B have different charsets
|
|
||||||
- A wins according to coercibility rules
|
|
||||||
(i.e. a column is stronger than a string constant,
|
|
||||||
an explicit COLLATE clause is stronger than a column)
|
|
||||||
- character set of A is either superset for character set of B,
|
|
||||||
or B is a string constant which can be converted into the
|
|
||||||
character set of A without data loss.
|
|
||||||
|
|
||||||
If all of the above is true, then it's possible to convert
|
|
||||||
B into the character set of A, and then compare according
|
|
||||||
to the collation of A.
|
|
||||||
|
|
||||||
For functions with more than two arguments:
|
|
||||||
|
|
||||||
collect(A,B,C) ::= collect(collect(A,B),C)
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool Item_func::agg_arg_charsets(DTCollation &coll,
|
|
||||||
Item **args, uint nargs, uint flags)
|
|
||||||
{
|
|
||||||
Item **arg, **last, *safe_args[2];
|
|
||||||
if (agg_arg_collations(coll, args, nargs, flags))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
For better error reporting: save the first and the second argument.
|
|
||||||
We need this only if the the number of args is 3 or 2:
|
|
||||||
- for a longer argument list, "Illegal mix of collations"
|
|
||||||
doesn't display each argument's characteristics.
|
|
||||||
- if nargs is 1, then this error cannot happen.
|
|
||||||
*/
|
|
||||||
if (nargs >=2 && nargs <= 3)
|
|
||||||
{
|
|
||||||
safe_args[0]= args[0];
|
|
||||||
safe_args[1]= args[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
THD *thd= current_thd;
|
|
||||||
Query_arena *arena, backup;
|
|
||||||
bool res= FALSE;
|
|
||||||
/*
|
|
||||||
In case we're in statement prepare, create conversion item
|
|
||||||
in its memory: it will be reused on each execute.
|
|
||||||
*/
|
|
||||||
arena= thd->change_arena_if_needed(&backup);
|
|
||||||
|
|
||||||
for (arg= args, last= args + nargs; arg < last; arg++)
|
|
||||||
{
|
|
||||||
Item* conv;
|
|
||||||
uint32 dummy_offset;
|
|
||||||
if (!String::needs_conversion(0, coll.collation,
|
|
||||||
(*arg)->collation.collation,
|
|
||||||
&dummy_offset))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(conv= (*arg)->safe_charset_converter(coll.collation)))
|
|
||||||
{
|
|
||||||
if (nargs >=2 && nargs <= 3)
|
|
||||||
{
|
|
||||||
/* restore the original arguments for better error message */
|
|
||||||
args[0]= safe_args[0];
|
|
||||||
args[1]= safe_args[1];
|
|
||||||
}
|
|
||||||
my_coll_agg_error(args, nargs, func_name());
|
|
||||||
res= TRUE;
|
|
||||||
break; // we cannot return here, we need to restore "arena".
|
|
||||||
}
|
|
||||||
if ((*arg)->type() == FIELD_ITEM)
|
|
||||||
((Item_field *)(*arg))->no_const_subst= 1;
|
|
||||||
/*
|
|
||||||
If in statement prepare, then we create a converter for two
|
|
||||||
constant items, do it once and then reuse it.
|
|
||||||
If we're in execution of a prepared statement, arena is NULL,
|
|
||||||
and the conv was created in runtime memory. This can be
|
|
||||||
the case only if the argument is a parameter marker ('?'),
|
|
||||||
because for all true constants the charset converter has already
|
|
||||||
been created in prepare. In this case register the change for
|
|
||||||
rollback.
|
|
||||||
*/
|
|
||||||
if (arena)
|
|
||||||
*arg= conv;
|
|
||||||
else
|
|
||||||
thd->change_item_tree(arg, conv);
|
|
||||||
/*
|
|
||||||
We do not check conv->fixed, because Item_func_conv_charset which can
|
|
||||||
be return by safe_charset_converter can't be fixed at creation
|
|
||||||
*/
|
|
||||||
conv->fix_fields(thd, arg);
|
|
||||||
}
|
|
||||||
if (arena)
|
|
||||||
thd->restore_backup_item_arena(arena, &backup);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func::set_arguments(List<Item> &list)
|
void Item_func::set_arguments(List<Item> &list)
|
||||||
{
|
{
|
||||||
allowed_arg_cols= 1;
|
allowed_arg_cols= 1;
|
||||||
|
@ -166,12 +166,22 @@ public:
|
|||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
|
|
||||||
bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
|
bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
|
||||||
uint flags= 0);
|
uint flags= 0)
|
||||||
|
{
|
||||||
|
return agg_item_collations(c, func_name(), items, nitems, flags);
|
||||||
|
}
|
||||||
bool agg_arg_collations_for_comparison(DTCollation &c,
|
bool agg_arg_collations_for_comparison(DTCollation &c,
|
||||||
Item **items, uint nitems,
|
Item **items, uint nitems,
|
||||||
uint flags= 0);
|
uint flags= 0)
|
||||||
|
{
|
||||||
|
return agg_item_collations_for_comparison(c, func_name(),
|
||||||
|
items, nitems, flags);
|
||||||
|
}
|
||||||
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
|
||||||
uint flags= 0);
|
uint flags= 0)
|
||||||
|
{
|
||||||
|
return agg_item_charsets(c, func_name(), items, nitems, flags);
|
||||||
|
}
|
||||||
bool walk(Item_processor processor, byte *arg);
|
bool walk(Item_processor processor, byte *arg);
|
||||||
Item *transform(Item_transformer transformer, byte *arg);
|
Item *transform(Item_transformer transformer, byte *arg);
|
||||||
void traverse_cond(Cond_traverser traverser,
|
void traverse_cond(Cond_traverser traverser,
|
||||||
|
@ -2976,6 +2976,10 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
|
|||||||
maybe_null|= args[i]->maybe_null;
|
maybe_null|= args[i]->maybe_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (agg_item_charsets(collation, func_name(),
|
||||||
|
args, arg_count, MY_COLL_ALLOW_CONV))
|
||||||
|
return 1;
|
||||||
|
|
||||||
result_field= 0;
|
result_field= 0;
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
thd->allow_sum_func= 1;
|
thd->allow_sum_func= 1;
|
||||||
|
Reference in New Issue
Block a user