[MDEV-10426] ANY_VALUE function as a workaround for ONLY_FULL_GROUP_BY mode, SQL-2023-T626, and compatibility with MySQL 5.7 Created: 2016-07-24  Updated: 2023-12-22

Status: Open
Project: MariaDB Server
Component/s: None
Fix Version/s: 11.5

Type: Task Priority: Major
Reporter: Wim Roffel Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 14
Labels: Compatibility, compat57, compat80, sql2023

Issue Links:
Duplicate
duplicates MDEV-12481 The ANY_VALUE() function is not yet i... Closed
PartOf
is part of MDEV-28906 MySQL 8.0 desired compatibility Open
Relates
relates to MDEV-30766 Issue with NOT IN (subquery that viol... Closed

 Description   

Since version 5.7.5 Mysql has the "ONLY_FULL_GROUP_BY" flag by default enabled and I am trying to make some software that I maintain to be compatible with that.

The most clean way to achieve that is with the ANY_VALUE() function. If you give a query like

SELECT ANY_VALUE(var1), ANY_VALUE(var2), color FROM mybase GROUP BY color

Mysql will not complain that var1 and var2 are not determined.

Unfortunately when I use this under MariaDb I get the following error:

MySQL error 1728: Cannot load from mysql.proc. The table is probably corrupted

As soon as you remove the ANY_VALUE the error disappears - so it must be related to this function.


See also MDEV-30766 where this function is needed for the query to return correct results



 Comments   
Comment by Elena Stepanova [ 2016-07-25 ]

MariaDB does not have ANY_VALUE() function.

For the error, please run CHECK TABLE mysql.proc, most likely it is actually corrupted. Since MariaDB does not have the internal function, it attempts to read mysql.proc to see if there is one in there, and hits the error. When you remove ANY_VALUE, the query does not make server read from mysql.proc, hence no error.

Comment by Wim Roffel [ 2016-07-30 ]

I ran check table mysql.proc and it tests ok.

I wonder if there is some way to get around this problem. I know nothing about managing mysql functions but I was wondering whether it is possible to define some code that checks whether this function is defined and - if not - defines it as a function that just returns its input.

Comment by Elena Stepanova [ 2016-07-30 ]

For mysql.proc problem, try also CHECK TABLE mysql.proc EXTENDED. If it doesn't reveal anything, please upload mysql/proc.frm, mysql/proc.MYD and mysql/proc.MYI to ftp.askmonty.org/private.

For the question about a function, you'll obviously need to learn something about managing MySQL functions in order to do that. Documentation is a good start.
MariaDB KB: https://mariadb.com/kb/en/mariadb/user-defined-functions/
MySQL manual: http://dev.mysql.com/doc/refman/5.6/en/adding-functions.html
You can also discuss the question on a mailing list.

Comment by Wim Roffel [ 2016-07-30 ]

CHECK TABLE mysql.proc EXTENDED doesn't give an error either.

I tried to upload the files but it is denied. I tried other directories on this server too - but with the same result.

I will have a look at the links.

Comment by Elena Stepanova [ 2016-07-30 ]

Actually, files got uploaded just fine, maybe you tried to do it twice, then the second attempt would fail.
You are getting the error because apparently you didn't run mysql_upgrade after upgrading the server from whatever version you had before. Running mysql_upgrade fixes this problem (and is highly recommended, because there might be other problems).

I'll convert this bug report to a feature request to consider porting ANY_VALUE function from MySQL 5.7 to new versions of MariaDB. This is not a guarantee it will actually happen.

Comment by Bradley Weston [ 2017-01-23 ]

Any update on this? Makes having to code for 2 separate database back-ends for basic querying.

Comment by Chris Wilson [ 2018-08-14 ]

MariaDB 10.3 brings custom aggregate functions - so you can (sort of) do this for yourself:

DROP FUNCTION IF EXISTS ANY_VALUE;
DELIMITER //
CREATE AGGREGATE FUNCTION ANY_VALUE (x LONGBLOB) RETURNS LONGBLOB
BEGIN
 LOOP
  FETCH GROUP NEXT ROW;
  RETURN x;
 END LOOP; 
END //
DELIMITER ;

...assuming that any type can be safely cast to longblob and back again (right? & yes, "ewww....") then I think this should do what you need! Be warned that this always acts like an aggregate function so using it in queries without a GROUP BY will not give the same result as MySQL 5.7.

Generated at Thu Feb 08 07:42:08 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.