mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-11297: Add support for LIMIT clause in GROUP_CONCAT()
This commit is contained in:
@ -1254,3 +1254,129 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.3 tests
|
||||||
|
#
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
create table t1 (grp int, a bigint unsigned, c char(10) , d char(10) not null);
|
||||||
|
insert into t1 values (1,1,NULL,"a");
|
||||||
|
insert into t1 values (1,10,"b","a");
|
||||||
|
insert into t1 values (1,11,"c","a");
|
||||||
|
insert into t1 values (2,2,"c","a");
|
||||||
|
insert into t1 values (2,3,"b","b");
|
||||||
|
insert into t1 values (3,4,"E","a");
|
||||||
|
insert into t1 values (3,5,"C","b");
|
||||||
|
insert into t1 values (3,6,"D","c");
|
||||||
|
insert into t1 values (3,7,"E","c");
|
||||||
|
select grp,group_concat(c) from t1 group by grp;
|
||||||
|
grp group_concat(c)
|
||||||
|
1 b,c
|
||||||
|
2 c,b
|
||||||
|
3 E,C,D,E
|
||||||
|
select grp,group_concat(c limit 1 ) from t1 group by grp;
|
||||||
|
grp group_concat(c limit 1 )
|
||||||
|
1 b
|
||||||
|
2 c
|
||||||
|
3 E
|
||||||
|
select grp,group_concat(c limit 1,1 ) from t1 group by grp;
|
||||||
|
grp group_concat(c limit 1,1 )
|
||||||
|
1 c
|
||||||
|
2 b
|
||||||
|
3 C
|
||||||
|
select grp,group_concat(c limit 1,10 ) from t1 group by grp;
|
||||||
|
grp group_concat(c limit 1,10 )
|
||||||
|
1 c
|
||||||
|
2 b
|
||||||
|
3 C,D,E
|
||||||
|
select grp,group_concat(c limit 1000) from t1 group by grp;
|
||||||
|
grp group_concat(c limit 1000)
|
||||||
|
1 b,c
|
||||||
|
2 c,b
|
||||||
|
3 E,C,D,E
|
||||||
|
select group_concat(grp limit 0) from t1;
|
||||||
|
group_concat(grp limit 0)
|
||||||
|
|
||||||
|
select group_concat(grp limit "sdjadjs") from t1
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select grp,group_concat(c limit 5.5) from t1 group by grp ;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"sdjadjs") from t1
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select grp,group_concat(c limit 5.5) f' at line 1
|
||||||
|
select grp,group_concat(distinct c limit 1,10 ) from t1 group by grp;
|
||||||
|
grp group_concat(distinct c limit 1,10 )
|
||||||
|
1 c
|
||||||
|
2 b
|
||||||
|
3 C,D
|
||||||
|
select grp,group_concat(c order by a) from t1 group by grp;
|
||||||
|
grp group_concat(c order by a)
|
||||||
|
1 b,c
|
||||||
|
2 c,b
|
||||||
|
3 E,C,D,E
|
||||||
|
select grp,group_concat(c order by a limit 2 ) from t1 group by grp;
|
||||||
|
grp group_concat(c order by a limit 2 )
|
||||||
|
1 b,c
|
||||||
|
2 c,b
|
||||||
|
3 E,C
|
||||||
|
select grp,group_concat(c order by a limit 1,1 ) from t1 group by grp;
|
||||||
|
grp group_concat(c order by a limit 1,1 )
|
||||||
|
1 c
|
||||||
|
2 b
|
||||||
|
3 C
|
||||||
|
select grp,group_concat(c order by c) from t1 group by grp;
|
||||||
|
grp group_concat(c order by c)
|
||||||
|
1 b,c
|
||||||
|
2 b,c
|
||||||
|
3 C,D,E,E
|
||||||
|
select grp,group_concat(c order by c limit 2) from t1 group by grp;
|
||||||
|
grp group_concat(c order by c limit 2)
|
||||||
|
1 b,c
|
||||||
|
2 b,c
|
||||||
|
3 C,D
|
||||||
|
select grp,group_concat(c order by c desc) from t1 group by grp;
|
||||||
|
grp group_concat(c order by c desc)
|
||||||
|
1 c,b
|
||||||
|
2 c,b
|
||||||
|
3 E,E,D,C
|
||||||
|
select grp,group_concat(c order by c desc limit 2) from t1 group by grp;
|
||||||
|
grp group_concat(c order by c desc limit 2)
|
||||||
|
1 c,b
|
||||||
|
2 c,b
|
||||||
|
3 E,E
|
||||||
|
drop table t1;
|
||||||
|
create table t2 (a int, b varchar(10));
|
||||||
|
insert into t2 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
|
||||||
|
select group_concat(a,b limit 2) from t2;
|
||||||
|
group_concat(a,b limit 2)
|
||||||
|
1a,1b
|
||||||
|
set @x=4;
|
||||||
|
prepare STMT from 'select group_concat(b limit ?) from t2';
|
||||||
|
execute STMT using @x;
|
||||||
|
group_concat(b limit ?)
|
||||||
|
a,b,c,x
|
||||||
|
set @x=2;
|
||||||
|
execute STMT using @x;
|
||||||
|
group_concat(b limit ?)
|
||||||
|
a,b
|
||||||
|
set @x=1000;
|
||||||
|
execute STMT using @x;
|
||||||
|
group_concat(b limit ?)
|
||||||
|
a,b,c,x,y
|
||||||
|
set @x=0;
|
||||||
|
execute STMT using @x;
|
||||||
|
group_concat(b limit ?)
|
||||||
|
|
||||||
|
set @x="adasfa";
|
||||||
|
execute STMT using @x;
|
||||||
|
ERROR HY000: Limit only accepts integer values
|
||||||
|
set @x=-1;
|
||||||
|
execute STMT using @x;
|
||||||
|
ERROR HY000: Incorrect arguments to EXECUTE
|
||||||
|
set @x=4;
|
||||||
|
prepare STMT from 'select group_concat(a,b limit ?) from t2';
|
||||||
|
execute STMT using @x;
|
||||||
|
group_concat(a,b limit ?)
|
||||||
|
1a,1b,2x,2y
|
||||||
|
drop table t2;
|
||||||
|
#
|
||||||
|
# End of 10.3 tests
|
||||||
|
#
|
||||||
|
@ -915,3 +915,76 @@ DROP TABLE t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-11297: Add support for LIMIT clause in GROUP_CONCAT()
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (grp int, a bigint unsigned, c char(10) , d char(10) not null);
|
||||||
|
insert into t1 values (1,1,NULL,"a");
|
||||||
|
insert into t1 values (1,10,"b","a");
|
||||||
|
insert into t1 values (1,11,"c","a");
|
||||||
|
insert into t1 values (2,2,"c","a");
|
||||||
|
insert into t1 values (2,3,"b","b");
|
||||||
|
insert into t1 values (3,4,"E","a");
|
||||||
|
insert into t1 values (3,5,"C","b");
|
||||||
|
insert into t1 values (3,6,"D","c");
|
||||||
|
insert into t1 values (3,7,"E","c");
|
||||||
|
|
||||||
|
|
||||||
|
select grp,group_concat(c) from t1 group by grp;
|
||||||
|
select grp,group_concat(c limit 1 ) from t1 group by grp;
|
||||||
|
select grp,group_concat(c limit 1,1 ) from t1 group by grp;
|
||||||
|
select grp,group_concat(c limit 1,10 ) from t1 group by grp;
|
||||||
|
select grp,group_concat(c limit 1000) from t1 group by grp;
|
||||||
|
select group_concat(grp limit 0) from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select group_concat(grp limit "sdjadjs") from t1
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select grp,group_concat(c limit 5.5) from t1 group by grp ;
|
||||||
|
select grp,group_concat(distinct c limit 1,10 ) from t1 group by grp;
|
||||||
|
select grp,group_concat(c order by a) from t1 group by grp;
|
||||||
|
select grp,group_concat(c order by a limit 2 ) from t1 group by grp;
|
||||||
|
select grp,group_concat(c order by a limit 1,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 limit 2) 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 limit 2) from t1 group by grp;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t2 (a int, b varchar(10));
|
||||||
|
insert into t2 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
|
||||||
|
select group_concat(a,b limit 2) from t2;
|
||||||
|
|
||||||
|
set @x=4;
|
||||||
|
prepare STMT from 'select group_concat(b limit ?) from t2';
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x=2;
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x=1000;
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x=0;
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x="adasfa";
|
||||||
|
--error ER_INVALID_VALUE_TO_LIMIT
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x=-1;
|
||||||
|
--error ER_WRONG_ARGUMENTS
|
||||||
|
execute STMT using @x;
|
||||||
|
set @x=4;
|
||||||
|
prepare STMT from 'select group_concat(a,b limit ?) from t2';
|
||||||
|
execute STMT using @x;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
--echo #
|
||||||
|
@ -3533,6 +3533,11 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
|
|||||||
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
|
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
|
||||||
uint old_length= result->length();
|
uint old_length= result->length();
|
||||||
|
|
||||||
|
ulonglong *offset_limit= &item->copy_offset_limit;
|
||||||
|
ulonglong *row_limit = &item->copy_row_limit;
|
||||||
|
if (item->limit_clause && !(*row_limit))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (item->no_appended)
|
if (item->no_appended)
|
||||||
item->no_appended= FALSE;
|
item->no_appended= FALSE;
|
||||||
else
|
else
|
||||||
@ -3540,6 +3545,14 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
|
|||||||
|
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
|
|
||||||
|
if (item->limit_clause && (*offset_limit))
|
||||||
|
{
|
||||||
|
item->row_count++;
|
||||||
|
item->no_appended= TRUE;
|
||||||
|
(*offset_limit)--;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (; arg < arg_end; arg++)
|
for (; arg < arg_end; arg++)
|
||||||
{
|
{
|
||||||
String *res;
|
String *res;
|
||||||
@ -3569,6 +3582,8 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
|
|||||||
result->append(*res);
|
result->append(*res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item->limit_clause)
|
||||||
|
(*row_limit)--;
|
||||||
item->row_count++;
|
item->row_count++;
|
||||||
|
|
||||||
/* stop if length of result more than max_length */
|
/* stop if length of result more than max_length */
|
||||||
@ -3617,7 +3632,8 @@ Item_func_group_concat::
|
|||||||
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
||||||
bool distinct_arg, List<Item> *select_list,
|
bool distinct_arg, List<Item> *select_list,
|
||||||
const SQL_I_List<ORDER> &order_list,
|
const SQL_I_List<ORDER> &order_list,
|
||||||
String *separator_arg)
|
String *separator_arg, bool limit_clause,
|
||||||
|
Item *row_limit_arg, Item *offset_limit_arg)
|
||||||
:Item_sum(thd), tmp_table_param(0), separator(separator_arg), tree(0),
|
:Item_sum(thd), tmp_table_param(0), separator(separator_arg), tree(0),
|
||||||
unique_filter(NULL), table(0),
|
unique_filter(NULL), table(0),
|
||||||
order(0), context(context_arg),
|
order(0), context(context_arg),
|
||||||
@ -3626,7 +3642,9 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
|||||||
row_count(0),
|
row_count(0),
|
||||||
distinct(distinct_arg),
|
distinct(distinct_arg),
|
||||||
warning_for_row(FALSE),
|
warning_for_row(FALSE),
|
||||||
force_copy_fields(0), original(0)
|
force_copy_fields(0), row_limit(NULL),
|
||||||
|
offset_limit(NULL), limit_clause(limit_clause),
|
||||||
|
copy_offset_limit(0), copy_row_limit(0), original(0)
|
||||||
{
|
{
|
||||||
Item *item_select;
|
Item *item_select;
|
||||||
Item **arg_ptr;
|
Item **arg_ptr;
|
||||||
@ -3668,6 +3686,11 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
|||||||
/* orig_args is only used for print() */
|
/* orig_args is only used for print() */
|
||||||
orig_args= (Item**) (order + arg_count_order);
|
orig_args= (Item**) (order + arg_count_order);
|
||||||
memcpy(orig_args, args, sizeof(Item*) * arg_count);
|
memcpy(orig_args, args, sizeof(Item*) * arg_count);
|
||||||
|
if (limit_clause)
|
||||||
|
{
|
||||||
|
row_limit= row_limit_arg;
|
||||||
|
offset_limit= offset_limit_arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3687,7 +3710,9 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
|
|||||||
warning_for_row(item->warning_for_row),
|
warning_for_row(item->warning_for_row),
|
||||||
always_null(item->always_null),
|
always_null(item->always_null),
|
||||||
force_copy_fields(item->force_copy_fields),
|
force_copy_fields(item->force_copy_fields),
|
||||||
original(item)
|
row_limit(item->row_limit), offset_limit(item->offset_limit),
|
||||||
|
limit_clause(item->limit_clause),copy_offset_limit(item->copy_offset_limit),
|
||||||
|
copy_row_limit(item->copy_row_limit), original(item)
|
||||||
{
|
{
|
||||||
quick_group= item->quick_group;
|
quick_group= item->quick_group;
|
||||||
result.set_charset(collation.collation);
|
result.set_charset(collation.collation);
|
||||||
@ -3782,6 +3807,10 @@ void Item_func_group_concat::clear()
|
|||||||
null_value= TRUE;
|
null_value= TRUE;
|
||||||
warning_for_row= FALSE;
|
warning_for_row= FALSE;
|
||||||
no_appended= TRUE;
|
no_appended= TRUE;
|
||||||
|
if (offset_limit)
|
||||||
|
copy_offset_limit= offset_limit->val_int();
|
||||||
|
if (row_limit)
|
||||||
|
copy_row_limit= row_limit->val_int();
|
||||||
if (tree)
|
if (tree)
|
||||||
reset_tree(tree);
|
reset_tree(tree);
|
||||||
if (unique_filter)
|
if (unique_filter)
|
||||||
@ -4036,6 +4065,12 @@ bool Item_func_group_concat::setup(THD *thd)
|
|||||||
(void*)this,
|
(void*)this,
|
||||||
tree_key_length,
|
tree_key_length,
|
||||||
ram_limitation(thd));
|
ram_limitation(thd));
|
||||||
|
if ((row_limit && row_limit->cmp_type() != INT_RESULT) ||
|
||||||
|
(offset_limit && offset_limit->cmp_type() != INT_RESULT))
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_VALUE_TO_LIMIT, MYF(0));
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
4113
sql/item_sum.cc.orig
Normal file
4113
sql/item_sum.cc.orig
Normal file
File diff suppressed because it is too large
Load Diff
@ -1747,6 +1747,16 @@ class Item_func_group_concat : public Item_sum
|
|||||||
bool always_null;
|
bool always_null;
|
||||||
bool force_copy_fields;
|
bool force_copy_fields;
|
||||||
bool no_appended;
|
bool no_appended;
|
||||||
|
/** Limits the rows in the result */
|
||||||
|
Item *row_limit;
|
||||||
|
/** Skips a particular number of rows in from the result*/
|
||||||
|
Item *offset_limit;
|
||||||
|
bool limit_clause;
|
||||||
|
/* copy of the offset limit */
|
||||||
|
ulonglong copy_offset_limit;
|
||||||
|
/*copy of the row limit */
|
||||||
|
ulonglong copy_row_limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Following is 0 normal object and pointer to original one for copy
|
Following is 0 normal object and pointer to original one for copy
|
||||||
(to correctly free resources)
|
(to correctly free resources)
|
||||||
@ -1763,7 +1773,8 @@ class Item_func_group_concat : public Item_sum
|
|||||||
public:
|
public:
|
||||||
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
||||||
bool is_distinct, List<Item> *is_select,
|
bool is_distinct, List<Item> *is_select,
|
||||||
const SQL_I_List<ORDER> &is_order, String *is_separator);
|
const SQL_I_List<ORDER> &is_order, String *is_separator,
|
||||||
|
bool limit_clause, Item *row_limit, Item *offset_limit);
|
||||||
|
|
||||||
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
|
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
|
||||||
~Item_func_group_concat();
|
~Item_func_group_concat();
|
||||||
|
1821
sql/item_sum.h.orig
Normal file
1821
sql/item_sum.h.orig
Normal file
File diff suppressed because it is too large
Load Diff
@ -7807,3 +7807,5 @@ ER_NOT_AGGREGATE_FUNCTION
|
|||||||
eng "Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)"
|
eng "Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)"
|
||||||
ER_INVALID_AGGREGATE_FUNCTION
|
ER_INVALID_AGGREGATE_FUNCTION
|
||||||
eng "Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function"
|
eng "Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function"
|
||||||
|
ER_INVALID_VALUE_TO_LIMIT
|
||||||
|
eng "Limit only accepts integer values"
|
||||||
|
@ -1679,7 +1679,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <num>
|
%type <num>
|
||||||
order_dir lock_option
|
order_dir lock_option
|
||||||
udf_type opt_local opt_no_write_to_binlog
|
udf_type opt_local opt_no_write_to_binlog
|
||||||
opt_temporary all_or_any opt_distinct
|
opt_temporary all_or_any opt_distinct opt_glimit_clause
|
||||||
opt_ignore_leaves fulltext_options union_option
|
opt_ignore_leaves fulltext_options union_option
|
||||||
opt_not
|
opt_not
|
||||||
select_derived_init transaction_access_mode_types
|
select_derived_init transaction_access_mode_types
|
||||||
@ -10754,16 +10754,22 @@ sum_expr:
|
|||||||
| GROUP_CONCAT_SYM '(' opt_distinct
|
| GROUP_CONCAT_SYM '(' opt_distinct
|
||||||
{ Select->in_sum_expr++; }
|
{ Select->in_sum_expr++; }
|
||||||
expr_list opt_gorder_clause
|
expr_list opt_gorder_clause
|
||||||
opt_gconcat_separator
|
opt_gconcat_separator opt_glimit_clause
|
||||||
')'
|
')'
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->in_sum_expr--;
|
sel->in_sum_expr--;
|
||||||
$$= new (thd->mem_root)
|
$$= new (thd->mem_root)
|
||||||
Item_func_group_concat(thd, Lex->current_context(), $3, $5,
|
Item_func_group_concat(thd, Lex->current_context(),
|
||||||
sel->gorder_list, $7);
|
$3, $5,
|
||||||
|
sel->gorder_list, $7, $8,
|
||||||
|
sel->select_limit,
|
||||||
|
sel->offset_limit);
|
||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
sel->select_limit= NULL;
|
||||||
|
sel->offset_limit= NULL;
|
||||||
|
sel->explicit_limit= 0;
|
||||||
$5->empty();
|
$5->empty();
|
||||||
sel->gorder_list.empty();
|
sel->gorder_list.empty();
|
||||||
}
|
}
|
||||||
@ -11053,6 +11059,48 @@ gorder_list:
|
|||||||
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
|
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_glimit_clause:
|
||||||
|
/* empty */ { $$ = 0; }
|
||||||
|
| glimit_clause { $$ = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_clause_init:
|
||||||
|
LIMIT{}
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_clause:
|
||||||
|
glimit_clause_init glimit_options
|
||||||
|
{
|
||||||
|
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_options:
|
||||||
|
limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $1;
|
||||||
|
sel->offset_limit= 0;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
| limit_option ',' limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $3;
|
||||||
|
sel->offset_limit= $1;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
| limit_option OFFSET_SYM limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $1;
|
||||||
|
sel->offset_limit= $3;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
in_sum_expr:
|
in_sum_expr:
|
||||||
opt_all
|
opt_all
|
||||||
{
|
{
|
||||||
|
@ -1092,7 +1092,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <num>
|
%type <num>
|
||||||
order_dir lock_option
|
order_dir lock_option
|
||||||
udf_type opt_local opt_no_write_to_binlog
|
udf_type opt_local opt_no_write_to_binlog
|
||||||
opt_temporary all_or_any opt_distinct
|
opt_temporary all_or_any opt_distinct opt_glimit_clause
|
||||||
opt_ignore_leaves fulltext_options union_option
|
opt_ignore_leaves fulltext_options union_option
|
||||||
opt_not
|
opt_not
|
||||||
select_derived_init transaction_access_mode_types
|
select_derived_init transaction_access_mode_types
|
||||||
@ -10571,16 +10571,22 @@ sum_expr:
|
|||||||
| GROUP_CONCAT_SYM '(' opt_distinct
|
| GROUP_CONCAT_SYM '(' opt_distinct
|
||||||
{ Select->in_sum_expr++; }
|
{ Select->in_sum_expr++; }
|
||||||
expr_list opt_gorder_clause
|
expr_list opt_gorder_clause
|
||||||
opt_gconcat_separator
|
opt_gconcat_separator opt_glimit_clause
|
||||||
')'
|
')'
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->in_sum_expr--;
|
sel->in_sum_expr--;
|
||||||
$$= new (thd->mem_root)
|
$$= new (thd->mem_root)
|
||||||
Item_func_group_concat(thd, Lex->current_context(), $3, $5,
|
Item_func_group_concat(thd, Lex->current_context(),
|
||||||
sel->gorder_list, $7);
|
$3, $5,
|
||||||
|
sel->gorder_list, $7, $8,
|
||||||
|
sel->select_limit,
|
||||||
|
sel->offset_limit);
|
||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
sel->select_limit= NULL;
|
||||||
|
sel->offset_limit= NULL;
|
||||||
|
sel->explicit_limit= 0;
|
||||||
$5->empty();
|
$5->empty();
|
||||||
sel->gorder_list.empty();
|
sel->gorder_list.empty();
|
||||||
}
|
}
|
||||||
@ -10866,6 +10872,46 @@ gorder_list:
|
|||||||
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
|
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_glimit_clause:
|
||||||
|
/* empty */ { $$ = 0; }
|
||||||
|
| glimit_clause { $$ = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_clause_init:
|
||||||
|
LIMIT{}
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_clause:
|
||||||
|
glimit_clause_init glimit_options
|
||||||
|
{
|
||||||
|
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
glimit_options:
|
||||||
|
limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $1;
|
||||||
|
sel->offset_limit= 0;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
| limit_option ',' limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $3;
|
||||||
|
sel->offset_limit= $1;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
| limit_option OFFSET_SYM limit_option
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= Select;
|
||||||
|
sel->select_limit= $1;
|
||||||
|
sel->offset_limit= $3;
|
||||||
|
sel->explicit_limit= 1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
in_sum_expr:
|
in_sum_expr:
|
||||||
opt_all
|
opt_all
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user