Bug #86220 | Query returns wrong results when using UDF in view | ||
---|---|---|---|
Submitted: | 8 May 2017 16:35 | Modified: | 5 Nov 2018 21:01 |
Reporter: | Oleksii Vynnychenko | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.7.18 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[8 May 2017 16:35]
Oleksii Vynnychenko
[10 May 2017 17:01]
MySQL Verification Team
Hi! First of all, IsMemberOfTeam is not UDF, but a STORED FUNCTION. The reason why you get wrong results is that you have not set its attributes correctly. Can you please set the stored routine IsMemberOfTeam to be DETERMINISTIC and that it READS SQL DATA and then try again ??? This time you should get the same results. Please, let us know if this has helped.
[10 May 2017 17:46]
Oleksii Vynnychenko
Hi Right, SF, not UDF, my bad. It actually helped - specifying as DETERMINISTIC, so far results are as should be. Thank you very much! Although I don't understand why is it so? In manual it says: -------------------- Assessment of the nature of a routine is based on the “honesty” of the creator: MySQL does not check that a routine declared DETERMINISTIC is free of statements that produce nondeterministic results. However, misdeclaring a routine might affect results or affect performance. Declaring a nondeterministic routine as DETERMINISTIC might lead to unexpected results by causing the optimizer to make incorrect execution plan choices. Declaring a deterministic routine as NONDETERMINISTIC might diminish performance by causing available optimizations not to be used. -------------------- https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html From what is written above NOT DETERMINISTIC (default) can only harm performance if function actually is deterministic because less optimization and so on, but result will always be right. Only the other way around can produce false results. Am I understanding it wrong? Why SF needs to be specified as DETERMINISTIC to return 'right' results? Specifying READS SQL DATA alone (without DETERMINISTIC) didn't affect the execution and it returned 'wrong' results like without specifying it. Specifying DETERMINISTIC on a routine alone made that query return 'right' results.
[10 May 2017 18:33]
Oleksii Vynnychenko
To add to previous one... What if my function was like that (lets imagine that's the only change to listing from the first post): DROP FUNCTION IF EXISTS IsMemberOfTeam; CREATE FUNCTION IsMemberOfTeam(accountId INT, teamDefinitionId INT) RETURNS VARCHAR(4000) NOT DETERMINISTIC READS SQL DATA BEGIN IF exists( SELECT id FROM team_definitions_to_accounts td2a WHERE td2a.id = teamDefinitionId AND td2a.account_id = accountId AND now() < '2018-01-01' ) THEN RETURN 'true'; ELSE RETURN 'false'; END IF ; END; I've specified READS SQL DATA and it's NOT DETERMINISTIC because I've added additional condition in WHERE - { now() < '2018-01-01' }, so it's not deterministic because of NOW() function call (am I right?). And I'm getting same problem results again - sub-query returns 1,2,3 accounts (as expected) and whole query returns everything from table (1,2,3,4,5,6,7) accounts (not what I've expected). Interesting thing is that specifying that function with NOW() call as DETERMINISTIC makes the whole query return 'right' (1,2,3) accounts, but from reading manual it's not right to do that, because in 2018 year and later it won't return anything. How to make the query work now with this SF? Can you shed the light on how is it so? Thank you
[11 May 2017 12:20]
MySQL Verification Team
Hi! I actually agree with you. This requires additional explanations in the manual. Verified as a documentation bug.
[11 May 2017 12:34]
Oleksii Vynnychenko
Hi But what about my last comment? What if function uses non-deterministic features, like in my last comment I've added as an example new condition to sub-query { AND now() < '2018-01-01' } ? Are not deterministic (not marked as DETERMINISTIC) functions should not be used in views at all because it may produce unexpected results at some point? Thank you
[11 May 2017 13:54]
MySQL Verification Team
It will be explained in the manual. This is some intricate interaction between the stored routine definition and the optimizer. It will take some time to be explained.
[5 Nov 2018 14:34]
MySQL Verification Team
Hi, This has turned out to be a bug in our code. Furthermore, it is a regression bug. Thank you for your contribution.
[5 Nov 2018 15:31]
Paul DuBois
Also: Potential workaround to get correct results: set optimizer_switch='derived_merge=off';
[5 Nov 2018 21:01]
Oleksii Vynnychenko
Thank you for the info, good to know it eventually will be fixed. Internally we've abandoned the idea of using SF in views because of this and used another approach, but thank you for heads-up on the issue.