Skip to content
Permalink
Browse files
MDEV-11297: Add support for LIMIT clause in GROUP_CONCAT()
  • Loading branch information
varunraiko committed Dec 8, 2017
1 parent 3aa618a commit 6d63a03
Show file tree
Hide file tree
Showing 9 changed files with 6,287 additions and 12 deletions.
@@ -1254,3 +1254,129 @@ DROP TABLE t1;
#
# 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 # End of 10.2 tests
--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,13 +3533,26 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
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)
item->no_appended= FALSE;
else
result->append(*item->separator);

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++)
{
String *res;
@@ -3569,6 +3582,8 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
result->append(*res);
}

if (item->limit_clause)
(*row_limit)--;
item->row_count++;

/* 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,
bool distinct_arg, List<Item> *select_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),
unique_filter(NULL), table(0),
order(0), context(context_arg),
@@ -3626,7 +3642,9 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
row_count(0),
distinct(distinct_arg),
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 **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= (Item**) (order + arg_count_order);
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),
always_null(item->always_null),
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;
result.set_charset(collation.collation);
@@ -3782,6 +3807,10 @@ void Item_func_group_concat::clear()
null_value= TRUE;
warning_for_row= FALSE;
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)
reset_tree(tree);
if (unique_filter)
@@ -4036,6 +4065,12 @@ bool Item_func_group_concat::setup(THD *thd)
(void*)this,
tree_key_length,
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);
}

0 comments on commit 6d63a03

Please sign in to comment.