Commit 0b505fb4 authored by unknown's avatar unknown

This is full commit of group_concat with support subselects


include/mysqld_error.h:
  add warning
sql/field.h:
  add friend class
sql/item_sum.cc:
  add function
sql/item_sum.h:
  add class
sql/lex.h:
  add lex
sql/mysql_priv.h:
  change push_warning
sql/mysqld.cc:
  add new option
sql/set_var.cc:
  add new system variable
sql/share/english/errmsg.txt:
  add new message text
sql/sql_class.h:
  change MY_ERROR class
sql/sql_error.cc:
  change push_warning
sql/sql_lex.h:
  add qorder_list for function
sql/sql_yacc.yy:
  add structure of group_concat
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent c312cd45
...@@ -104,6 +104,7 @@ vva@eagle.mysql.r18.ru ...@@ -104,6 +104,7 @@ vva@eagle.mysql.r18.ru
vva@genie.(none) vva@genie.(none)
walrus@kishkin.ru walrus@kishkin.ru
walrus@mysql.com walrus@mysql.com
wax@kishkin.ru
wax@mysql.com wax@mysql.com
worm@altair.is.lan worm@altair.is.lan
zak@balfor.local zak@balfor.local
......
...@@ -266,4 +266,5 @@ ...@@ -266,4 +266,5 @@
#define ER_SELECT_REDUCED 1247 #define ER_SELECT_REDUCED 1247
#define ER_TABLENAME_NOT_ALLOWED_HERE 1248 #define ER_TABLENAME_NOT_ALLOWED_HERE 1248
#define ER_NOT_SUPPORTED_AUTH_MODE 1249 #define ER_NOT_SUPPORTED_AUTH_MODE 1249
#define ER_ERROR_MESSAGES 250 #define ER_CUT_VALUE_GROUP_CONCAT 1250
#define ER_ERROR_MESSAGES 251
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
create table t1 (grp int, a bigint unsigned, c char(10) not null, d char(10) not null);
insert into t1 values (1,1,"a","a");
insert into t1 values (2,2,"b","a");
insert into t1 values (2,3,"c","b");
insert into t1 values (3,4,"E","a");
insert into t1 values (3,5,"C","b");
insert into t1 values (3,6,"D","b");
insert into t1 values (3,7,"d","d");
insert into t1 values (3,8,"d","d");
insert into t1 values (3,9,"D","c");
select grp,group_concat(c) from t1 group by grp;
grp group_concat(c)
1 a
2 b c
3 E C D d d D
select grp,group_concat(a,c) from t1 group by grp;
grp group_concat(a,c)
1 1a
2 2b 3c
3 4E 5C 6D 7d 8d 9D
select grp,group_concat("(",a,":",c,")") from t1 group by grp;
grp group_concat("(",a,":",c,")")
1 (1:a)
2 (2:b) (3:c)
3 (4:E) (5:C) (6:D) (7:d) (8:d) (9:D)
select grp,group_concat(c separator ",") from t1 group by grp;
grp group_concat(c separator ",")
1 a
2 b,c
3 E,C,D,d,d,D
select grp,group_concat(c separator "---->") from t1 group by grp;
grp group_concat(c separator "---->")
1 a
2 b---->c
3 E---->C---->D---->d---->d---->D
select grp,group_concat(c order by c) from t1 group by grp;
grp group_concat(c order by c)
1 a
2 b c
3 C D d d D E
select grp,group_concat(c order by c desc) from t1 group by grp;
grp group_concat(c order by c desc)
1 a
2 c b
3 E D d d D C
select grp,group_concat(d order by a) from t1 group by grp;
grp group_concat(d order by a)
1 a
2 a b
3 a b b d d c
select grp,group_concat(d order by a desc) from t1 group by grp;
grp group_concat(d order by a desc)
1 a
2 b a
3 c d d b b a
select grp,group_concat(a order by a,d+c) from t1 group by grp;
grp group_concat(a order by a,d+c)
1 1
2 2 3
3 4 5 6 7 8 9
select grp,group_concat(c order by 1) from t1 group by grp;
grp group_concat(c order by 1)
1 a
2 b c
3 C D d d D E
select grp,group_concat(c order by "c") from t1 group by grp;
grp group_concat(c order by "c")
1 a
2 b c
3 C D d d D E
select grp,group_concat(distinct c order by c) from t1 group by grp;
grp group_concat(distinct c order by c)
1 a
2 b c
3 C D E
select grp,group_concat(distinct c order by c desc) from t1 group by grp;
grp group_concat(distinct c order by c desc)
1 a
2 c b
3 E D C
select grp,group_concat(c order by c separator ",") from t1 group by grp;
grp group_concat(c order by c separator ",")
1 a
2 b,c
3 C,D,d,d,D,E
select grp,group_concat(c order by c desc separator ",") from t1 group by grp;
grp group_concat(c order by c desc separator ",")
1 a
2 c,b
3 E,D,d,d,D,C
select grp,group_concat(distinct c order by c separator ",") from t1 group by grp;
grp group_concat(distinct c order by c separator ",")
1 a
2 b,c
3 C,D,E
select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp;
grp group_concat(distinct c order by c desc separator ",")
1 a
2 c,b
3 E,D,C
select grp,group_concat(c order by grp desc) from t1 group by grp order by grp;
grp group_concat(c order by grp desc)
1 a
2 c b
3 D d d D C E
select grp, group_concat(a separator "")+0 from t1 group by grp;
grp group_concat(a separator "")+0
1 1
2 23
3 456789
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
grp group_concat(a separator "")+0.0
1 1.0
2 23.0
3 456789.0
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
grp ROUND(group_concat(a separator ""))
1 1
2 23
3 456789
drop table if exists t1;
create table t1 (grp int, c char(10));
insert into t1 values (1,NULL);
insert into t1 values (2,"b");
insert into t1 values (2,NULL);
insert into t1 values (3,"E");
insert into t1 values (3,NULL);
insert into t1 values (3,"D");
insert into t1 values (3,NULL);
insert into t1 values (3,NULL);
insert into t1 values (3,"D");
select grp,group_concat(c order by c) from t1 group by grp;
grp group_concat(c order by c)
1
2 b
3 D D E
set group_concat_max_len = 5;
select grp,group_concat(c) from t1 group by grp;
grp group_concat(c)
1
2 b
3 E D
Warnings:
Warning 1250 1 line(s) was(were) cut by group_concat()
show warnings;
Level Code Message
Warning 1250 1 line(s) was(were) cut by group_concat()
select group_concat(sum(a)) from t1 group by grp;
Invalid use of group function
select grp,group_concat(c order by 2) from t1 group by grp;
Unknown column '2' in 'group statement'
drop table if exists t1;
#
# simple test of group_concat function
#
drop table if exists t1;
create table t1 (grp int, a bigint unsigned, c char(10) not null, d char(10) not null);
insert into t1 values (1,1,"a","a");
insert into t1 values (2,2,"b","a");
insert into t1 values (2,3,"c","b");
insert into t1 values (3,4,"E","a");
insert into t1 values (3,5,"C","b");
insert into t1 values (3,6,"D","b");
insert into t1 values (3,7,"d","d");
insert into t1 values (3,8,"d","d");
insert into t1 values (3,9,"D","c");
# Test of MySQL simple request
select grp,group_concat(c) from t1 group by grp;
select grp,group_concat(a,c) from t1 group by grp;
select grp,group_concat("(",a,":",c,")") from t1 group by grp;
# Test of MySQL with options
select grp,group_concat(c separator ",") from t1 group by grp;
select grp,group_concat(c separator "---->") 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 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 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(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(distinct c order by c) from t1 group by grp;
select grp,group_concat(distinct c order by c desc) from t1 group by grp;
select grp,group_concat(c order by c separator ",") from t1 group by grp;
select grp,group_concat(c order by c desc separator ",") from t1 group by grp;
select grp,group_concat(distinct c order by c separator ",") from t1 group by grp;
select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp;
# Test of SQL_LIST objects
select grp,group_concat(c order by grp desc) from t1 group by grp order by grp;
# Test transfer to real values
select grp, group_concat(a separator "")+0 from t1 group by grp;
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
# Test NULL values
drop table if exists t1;
create table t1 (grp int, c char(10));
insert into t1 values (1,NULL);
insert into t1 values (2,"b");
insert into t1 values (2,NULL);
insert into t1 values (3,"E");
insert into t1 values (3,NULL);
insert into t1 values (3,"D");
insert into t1 values (3,NULL);
insert into t1 values (3,NULL);
insert into t1 values (3,"D");
select grp,group_concat(c order by c) from t1 group by grp;
# Test warnings
set group_concat_max_len = 5;
select grp,group_concat(c) from t1 group by grp;
show warnings;
# Test errors
--error 1111
select group_concat(sum(a)) from t1 group by grp;
--error 1054
select grp,group_concat(c order by 2) from t1 group by grp;
drop table if exists t1;
...@@ -221,6 +221,7 @@ public: ...@@ -221,6 +221,7 @@ public:
friend class Item_sum_std; friend class Item_sum_std;
friend class Item_sum_min; friend class Item_sum_min;
friend class Item_sum_max; friend class Item_sum_max;
friend class Item_func_group_concat;
}; };
......
This diff is collapsed.
...@@ -28,7 +28,7 @@ class Item_sum :public Item_result_field ...@@ -28,7 +28,7 @@ class Item_sum :public Item_result_field
public: public:
enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC, enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,VARIANCE_FUNC,SUM_BIT_FUNC, MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,VARIANCE_FUNC,SUM_BIT_FUNC,
UDF_SUM_FUNC }; UDF_SUM_FUNC, GROUP_CONCAT_FUNC };
Item **args,*tmp_args[2]; Item **args,*tmp_args[2];
uint arg_count; uint arg_count;
...@@ -628,3 +628,87 @@ public: ...@@ -628,3 +628,87 @@ public:
}; };
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
class Item_func_group_concat : public Item_sum
{
THD *item_thd;
TMP_TABLE_PARAM *tmp_table_param;
uint max_elements_in_tree;
void *warning;
bool warning_available;
public:
String result;
String *separator;
uint show_elements;
TREE tree_base;
TREE *tree;
TABLE *table;
int arg_count_order;
int arg_count_field;
int arg_show_fields;
int distinct;
Item **expr;
ORDER **order;
bool tree_mode;
int count_cut_values;
ulong group_concat_max_len;
bool warning_for_row;
TABLE_LIST *tables_list;
bool always_null;
/*
Following is 0 normal object and pointer to original one for copy
(to correctly free resources)
*/
Item_func_group_concat *original;
Item_func_group_concat(int is_distinct,List<Item> *is_select,
SQL_LIST *is_order,String *is_separator);
Item_func_group_concat(THD *thd, Item_func_group_concat &item)
:Item_sum(thd, item),item_thd(thd),
tmp_table_param(item.tmp_table_param),
max_elements_in_tree(item.max_elements_in_tree),
warning(item.warning),
warning_available(item.warning_available),
separator(item.separator),
show_elements(item.show_elements),
tree(item.tree),
table(item.table),
arg_count_order(item.arg_count_order),
arg_count_field(item.arg_count_field),
arg_show_fields(item.arg_show_fields),
distinct(item.distinct),
expr(item.expr),
order(item.order),
tree_mode(0),
count_cut_values(item.count_cut_values),
group_concat_max_len(item.group_concat_max_len),
warning_for_row(item.warning_for_row),
tables_list(item.tables_list),
original(&item)
{
quick_group = 0;
};
~Item_func_group_concat();
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; }
enum Type type() const { return SUM_FUNC_ITEM; }
virtual Item_result result_type () const { return STRING_RESULT; }
void reset();
bool add();
void reset_field();
bool fix_fields(THD *, TABLE_LIST *, Item **);
bool setup(THD *thd);
virtual void update_field(int offset) {};
double val()
{
String *res; res=val_str(&str_value);
return res ? atof(res->c_ptr()) : 0.0;
}
longlong val_int()
{
String *res; res=val_str(&str_value);
return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
}
String* val_str(String* str);
};
...@@ -330,6 +330,7 @@ static SYMBOL symbols[] = { ...@@ -330,6 +330,7 @@ static SYMBOL symbols[] = {
{ "ROWS", SYM(ROWS_SYM),0,0}, { "ROWS", SYM(ROWS_SYM),0,0},
{ "RTREE", SYM(RTREE_SYM),0,0}, { "RTREE", SYM(RTREE_SYM),0,0},
{ "SECOND", SYM(SECOND_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0},
{ "SEPARATOR", SYM(SEPARATOR_SYM),0,0},
{ "SELECT", SYM(SELECT_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0},
{ "SERIAL", SYM(SERIAL_SYM),0,0}, { "SERIAL", SYM(SERIAL_SYM),0,0},
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
...@@ -490,6 +491,7 @@ static SYMBOL sql_functions[] = { ...@@ -490,6 +491,7 @@ static SYMBOL sql_functions[] = {
{ "GEOMFROMTEXT", SYM(GEOMFROMTEXT),0,0}, { "GEOMFROMTEXT", SYM(GEOMFROMTEXT),0,0},
{ "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)}, { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)},
{ "GREATEST", SYM(GREATEST_SYM),0,0}, { "GREATEST", SYM(GREATEST_SYM),0,0},
{ "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM),0,0},
{ "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0}, { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0},
{ "HEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)}, { "HEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)},
{ "IFNULL", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)}, { "IFNULL", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)},
......
...@@ -544,8 +544,8 @@ int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields, ...@@ -544,8 +544,8 @@ int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
List<Item> &values, ulong counter); List<Item> &values, ulong counter);
/* sql_error.cc */ /* sql_error.cc */
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
const char *msg); const char *msg);
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *format, ...); uint code, const char *format, ...);
void mysql_reset_errors(THD *thd); void mysql_reset_errors(THD *thd);
......
...@@ -3465,7 +3465,8 @@ enum options ...@@ -3465,7 +3465,8 @@ enum options
OPT_ERROR_LOG_FILE, OPT_ERROR_LOG_FILE,
OPT_ENABLE_SHARED_MEMORY, OPT_ENABLE_SHARED_MEMORY,
OPT_SHARED_MEMORY_BASE_NAME, OPT_SHARED_MEMORY_BASE_NAME,
OPT_OLD_PASSWORDS OPT_OLD_PASSWORDS,
OPT_GROUP_CONCAT_MAX_LEN
}; };
...@@ -3581,6 +3582,11 @@ struct my_option my_long_options[] = ...@@ -3581,6 +3582,11 @@ struct my_option my_long_options[] =
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0, {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
"The maximum length of the result of function group_concat.",
(gptr*) &global_system_variables.group_concat_max_len,
(gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0},
/* We must always support the next option to make scripts like mysqltest /* We must always support the next option to make scripts like mysqltest
easier to do */ easier to do */
{"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0, {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0,
......
...@@ -311,6 +311,8 @@ static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter ...@@ -311,6 +311,8 @@ static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter
static sys_var_rand_seed1 sys_rand_seed1("rand_seed1"); static sys_var_rand_seed1 sys_rand_seed1("rand_seed1");
static sys_var_rand_seed2 sys_rand_seed2("rand_seed2"); static sys_var_rand_seed2 sys_rand_seed2("rand_seed2");
sys_var_thd_ulong sys_group_concat_max_len("group_concat_max_len",
&SV::group_concat_max_len);
/* /*
List of all variables for initialisation and storage in hash List of all variables for initialisation and storage in hash
...@@ -340,6 +342,7 @@ sys_var *sys_variables[]= ...@@ -340,6 +342,7 @@ sys_var *sys_variables[]=
&sys_flush, &sys_flush,
&sys_flush_time, &sys_flush_time,
&sys_foreign_key_checks, &sys_foreign_key_checks,
&sys_group_concat_max_len,
&sys_identity, &sys_identity,
&sys_insert_id, &sys_insert_id,
&sys_interactive_timeout, &sys_interactive_timeout,
......
...@@ -250,4 +250,5 @@ ...@@ -250,4 +250,5 @@
"Every derived table must have it's own alias", "Every derived table must have it's own alias",
"Select %u was reduced during optimisation", "Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Table '%-.64s' from one of SELECT's can not be used in %-.32s"
"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client",
\ No newline at end of file "%d line(s) was(were) cut by group_concat()"
...@@ -327,7 +327,12 @@ public: ...@@ -327,7 +327,12 @@ public:
const char *msg_arg) const char *msg_arg)
:code(code_arg), level(level_arg) :code(code_arg), level(level_arg)
{ {
msg=sql_strdup(msg_arg); set_msg(msg_arg);
}
inline void set_msg(const char *msg_arg)
{
if (msg_arg)
msg=sql_strdup(msg_arg);
} }
}; };
...@@ -391,7 +396,7 @@ struct system_variables ...@@ -391,7 +396,7 @@ struct system_variables
ulong tmp_table_size; ulong tmp_table_size;
ulong tx_isolation; ulong tx_isolation;
ulong sql_mode; ulong sql_mode;
ulong group_concat_max_len;
/* /*
In slave thread we need to know in behalf of which In slave thread we need to know in behalf of which
thread the query is being run to replicate temp tables properly thread the query is being run to replicate temp tables properly
......
...@@ -79,14 +79,19 @@ void mysql_reset_errors(THD *thd) ...@@ -79,14 +79,19 @@ void mysql_reset_errors(THD *thd)
level Severity of warning (note, warning, error ...) level Severity of warning (note, warning, error ...)
code Error number code Error number
msg Clear error message msg Clear error message
RETURN
pointer on MYSQL_ERROR object
*/ */
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
const char *msg) uint code, const char *msg)
{ {
if (thd->query_id != thd->warn_id) if (thd->query_id != thd->warn_id)
mysql_reset_errors(thd); mysql_reset_errors(thd);
MYSQL_ERROR *err = NULL;
if (thd->warn_list.elements < thd->variables.max_error_count) if (thd->warn_list.elements < thd->variables.max_error_count)
{ {
/* /*
...@@ -95,13 +100,14 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, ...@@ -95,13 +100,14 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
*/ */
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root); my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root);
MYSQL_ERROR *err= new MYSQL_ERROR(code, level, msg); err = new MYSQL_ERROR(code, level, msg);
if (err) if (err)
thd->warn_list.push_back(err); thd->warn_list.push_back(err);
my_pthread_setspecific_ptr(THR_MALLOC, old_root); my_pthread_setspecific_ptr(THR_MALLOC, old_root);
} }
thd->warn_count[(uint) level]++; thd->warn_count[(uint) level]++;
thd->total_warn_count++; thd->total_warn_count++;
return err;
} }
/* /*
......
...@@ -477,6 +477,7 @@ typedef struct st_lex ...@@ -477,6 +477,7 @@ typedef struct st_lex
uint slave_thd_opt; uint slave_thd_opt;
CHARSET_INFO *charset; CHARSET_INFO *charset;
char *help_arg; char *help_arg;
SQL_LIST *gorder_list;
inline void uncacheable() inline void uncacheable()
{ {
......
...@@ -332,6 +332,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -332,6 +332,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ROW_SYM %token ROW_SYM
%token RTREE_SYM %token RTREE_SYM
%token SET %token SET
%token SEPARATOR_SYM
%token SERIAL_SYM %token SERIAL_SYM
%token SERIALIZABLE_SYM %token SERIALIZABLE_SYM
%token SESSION_SYM %token SESSION_SYM
...@@ -457,6 +458,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -457,6 +458,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token GEOMCOLLFROMTEXT %token GEOMCOLLFROMTEXT
%token GEOMFROMTEXT %token GEOMFROMTEXT
%token GEOMETRYCOLLECTION %token GEOMETRYCOLLECTION
%token GROUP_CONCAT_SYM
%token GROUP_UNIQUE_USERS %token GROUP_UNIQUE_USERS
%token HOUR_MINUTE_SYM %token HOUR_MINUTE_SYM
%token HOUR_SECOND_SYM %token HOUR_SECOND_SYM
...@@ -567,13 +569,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -567,13 +569,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
opt_escape opt_escape
%type <string> %type <string>
text_string text_string opt_gconcat_separator
%type <num> %type <num>
type int_type real_type order_dir opt_field_spec lock_option type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_var_type opt_var_ident_type table_option opt_if_not_exists opt_var_type opt_var_ident_type
delete_option opt_temporary all_or_any delete_option opt_temporary all_or_any opt_distinct
%type <ulong_num> %type <ulong_num>
ULONG_NUM raid_types merge_insert_types ULONG_NUM raid_types merge_insert_types
...@@ -2466,7 +2468,35 @@ sum_expr: ...@@ -2466,7 +2468,35 @@ sum_expr:
| VARIANCE_SYM '(' in_sum_expr ')' | VARIANCE_SYM '(' in_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 opt_gconcat_separator ')'
{
$$=new Item_func_group_concat($3,$4,Lex->gorder_list,$6);
$4->empty();
};
opt_distinct:
/* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; };
opt_gconcat_separator:
/* empty */ { $$ = new String(" ",1,default_charset_info); }
|SEPARATOR_SYM text_string { $$ = $2; };
opt_gorder_clause:
/* empty */
{
LEX *lex=Lex;
lex->gorder_list = NULL;
}
| order_clause
{
LEX *lex=Lex;
lex->gorder_list= (SQL_LIST*) sql_memdup((char*) &lex->current_select->order_list,sizeof(st_sql_list));
lex->current_select->order_list.empty();
};
in_sum_expr: in_sum_expr:
opt_all opt_all
......
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