60

I have a function listed below. When I call it with the LIMIT set at 0,60 as seen below, it works fine. However, whenever I increase that LIMIT to 70 or higher, or even remove the LIMIT, MySQL errors when I call the function with the error: "Row 30153 was cut by GROUP_CONCAT()".

I have tried increasing the varchar values to 10 000 but that does not help. As far as I can understand from the error, their doesn't seem to be enough space i nthe variable for the contents. But like I mentioned, I have tried increasing the size but it doesn't help. Any ideas?? Thanks

DELIMITER $$

DROP FUNCTION IF EXISTS `fnAlbumGetPhotoList` $$
CREATE DEFINER=`root`@`%` FUNCTION `fnAlbumGetPhotoList`(_albumId int) RETURNS varchar(2048) CHARSET utf8
BEGIN

  DECLARE _outPhotoList VARCHAR(2048);

    SET _outPhotoList = (

                          SELECT (CAST(GROUP_CONCAT(CONCAT(photoId, '|', photoFileName) separator '~') AS CHAR(10000) CHARACTER SET utf8)) AS recentPhotoList
                              FROM
                              (
                                SELECT photoId, photoFileName
                                FROM photo
                                WHERE photoAlbumId = _albumId
                                AND photoIsDisabled = 0
                                AND photoIsActive = 1
                                ORDER BY photoId DESC
                                LIMIT 0,60
                              ) as subQuery
                            );


  RETURN _outPhotoList;

END $$

DELIMITER ;
Paolo Broccardo
  • 1,942
  • 6
  • 34
  • 51
  • I've got into this problem only after Liquibase executed stored procedure, which I had to modify. Which is more intriguing is that after doing dummy change in the procedure inside Navicat, and executing, the error disappeared. – dobrivoje Feb 04 '20 at 08:25

2 Answers2

92

You could set the group_concat_max_len variable to bigger value. Or perhaps use GROUP_CONCAT(DISTINCT ...) to shorthen the result.

ain
  • 22,394
  • 3
  • 54
  • 74
  • 4
    Thanks - The results are already distinct, so I tried adding this in my proc: `SET GLOBAL group_concat_max_len=15000;` It didn't make a difference though?? Is that the right usage? – Paolo Broccardo Aug 26 '11 at 18:23
  • See the manual (click on "group_concat_max_len", it's a link) for full description. 15 000 looks kind of small, try the maximum value of your platform :) Also read the GROUP_CONCAT topic, it too has some information about the behaviour and remark about max_allowed_packet variable. – ain Aug 26 '11 at 18:27
  • Oh, and get rid of the CHAR(10000) cast - it makes result longer and thus causes problems, not fixes them! – ain Aug 26 '11 at 18:29
  • 1
    Ah thanks Ain, the char(10000) cast was the problem. Once removed, the query works fine, even at 2000 len. I had used that code from another example so assumed the CAST to char(10000) was required. Guess nit wasn't :) Thanks – Paolo Broccardo Aug 27 '11 at 05:39
  • 37
    In case someone else has this issue, I tried `SET GLOBAL group_concat_max_len=15000;` without luck, but `SET group_concat_max_len=15000;` did work. – VenerableAgents Mar 08 '12 at 21:38
  • 3
    ... or `SET @@group_concat_max_len = 15000`, as they use it [here](http://bugs.mysql.com/bug.php?id=56473), @VenerableAgents? – Tomas Jul 08 '13 at 08:18
  • ... or `set SESSION group_concat_max_len = 10000;` as I use for current session. – Marecky Jan 28 '15 at 01:21
  • @Cheeky would appreciate if you tell me whether you got it resolved or not? – Danyal Sandeelo Jun 23 '16 at 05:22
27

1) Increase the limit on the number of characters from the resultant query

SET global group_concat_max_len=15000;
OR
SET session group_concat_max_len=15000;

Use the former if you want the setting to be the new global default (sticky).
Use the latter if you want to use this setting during the current session only.
(Note also that some have reported trouble when using the global option. In that case, try leaving it off, as in SET group_concat_max_len=15000;.)

2) Then add DISTINCT as first param to GROUP_CONCAT() to remove duplicates from the result query. GROUP_CONCAT(DISTINCT ..).

Your query will look more like this:

SET session group_concat_max_len=15000;
...
    ... GROUP_CONCAT(DISTINCT CONCAT(photoId, ...)
...
)      

Function Group Concat, from MySQL docs:

SET [GLOBAL | SESSION] group_concat_max_len = val;

In MySQL, you can get the concatenated values of expression combinations. To eliminate duplicate values, use the DISTINCT clause.

...

The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. The value can be set higher, although the effective maximum length of the return value is constrained by the value of max_allowed_packet. The syntax to change the value of group_concat_max_len at runtime is as follows, where val is an unsigned integer:

SET [GLOBAL | SESSION] group_concat_max_len = val;

The return value is a nonbinary or binary string, depending on whether the arguments are nonbinary or binary strings. The result type is TEXT or BLOB unless group_concat_max_len is less than or equal to 512, in which case the result type is VARCHAR or VARBINARY.

Presumably not specifying an optional alternative (GLOBAL or SESSION) will default to the first listed alternative (GLOBAL in this case), though I could not find this explicitly stated in the documentation.

About syntax used in the MySQL docs:

When a syntax element consists of a number of alternatives, the alternatives are separated by vertical bars (“|”).

When one member from a set of choices may be chosen, the alternatives are listed within square brackets (“[” and “]”):

When one member from a set of choices must be chosen, the alternatives are listed within braces (“{” and “}”)

SherylHohman
  • 16,580
  • 17
  • 88
  • 94
  • Sorry, @morha13, I initially misunderstood your edit and rejected it. I now see what you were trying to indicate. I should have selected `"Improve Edit"` to accept, but re-word and re-format your edits so it was clearer, and better matched the formatting and text of the post. You are correct that I left off the `global` in the first command, and could have made clearer what the differences between the 2 commands are and when/why one should be chosen over the other. Thanks for pointing out the improvement. – SherylHohman Apr 21 '19 at 19:42
  • As per [docs](https://dev.mysql.com/doc/refman/5.7/en/manual-conventions.html) alternatives listed within square brackets are optional'. So, `..[ global | session ]..`: the `global` or `session` quantifier is *optional*. However, I could not find definitive documentation indicating what the behavior is, if neither is specified. Likely, the first listed option would be the default - and that's what my original version of this answer implied: not specifying `session` is equivalent to specifying `global`. That said, for clarity, I updated to add `global`. I'd welcome an MySQL expert to weigh in. – SherylHohman Apr 22 '19 at 14:53
  • Session is more specific, and this is what is used as a default. https://dev.mysql.com/doc/refman/5.7/en/set-variable.html#set-variable-system-variables « To assign a value to a session system variable, precede the variable name by the SESSION or LOCAL keyword, by the @@SESSION., @@LOCAL., or @@ qualifier, *or by no keyword or no modifier at all* » – Pierre-Olivier Vares Feb 25 '21 at 08:13
  • Another thing about GLOBAL and SESSION : GLOBAL is only used for new sessions. So if you want to set a variable for this session, and also for nxt sessions, you have to do BOTH calls, with GLOBAL, and then with SESSION (or without GLOBAL) – Pierre-Olivier Vares Feb 25 '21 at 13:39