Bug #36677 | TRADITIONAL sql_mode not honored in stored procedures | ||
---|---|---|---|
Submitted: | 12 May 2008 22:09 | Modified: | 29 May 2009 19:59 |
Reporter: | Tim Soderstrom | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S2 (Serious) |
Version: | 5.1.24-rc, 5.0.51a, 5.0.60 | OS: | MacOS (Leopard) |
Assigned to: | Paul DuBois | CPU Architecture: | Any |
Tags: | sql_mode stored procedures |
[12 May 2008 22:09]
Tim Soderstrom
[12 May 2008 22:33]
Tim Soderstrom
Also verified in 5.0.51a: # mysql moocowproductions_dev < testcase.sql *************************** 1. row *************************** ROUTINE_NAME: AddLensTestProc SQL_MODE: STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER Variable_name Value sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER lensID lensName minZoom maxZoom minAperture maxAperture hasED hasVR 1 proctest9 0 1 1.000 1.000 Yes No ERROR 1264 (22003) at line 68: Out of range value adjusted for column 'inMinZoom' at row 1
[12 May 2008 22:37]
Tim Soderstrom
Here is the test-script (included in the how to reproduce section as well)
Attachment: testcase.sql (, text), 2.23 KiB.
[13 May 2008 4:47]
Valeriy Kravchuk
Thank you for a problem report. Verified just as described with 5.0.60 also. This is in clear contradition with the manual, http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html, that says: "MySQL stores the sql_mode system variable setting that is in effect at the time a routine is created, and always executes the routine with this setting in force, regardless of the current server SQL mode."
[28 May 2009 14:18]
Konstantin Osipov
The bug is apparently that the SQL mode of a stored procedure doesn't apply to assignment of IN parameters of the procedure. There is no reason for that, however, it would be an incompatible change. A test case: mysql> set sql_mode='ERROR_FOR_DIVISION_BY_ZERO'; Query OK, 0 rows affected (0.00 sec) mysql> create procedure p1 (a int) select a; Query OK, 0 rows affected (0.02 sec) mysql> call p1(1/0); +------+ | a | +------+ | NULL | +------+ 1 row in set (0.00 sec) Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show warnings; +---------+------+---------------+ | Level | Code | Message | +---------+------+---------------+ | Warning | 1365 | Division by 0 | +---------+------+---------------+ 1 row in set (0.00 sec) mysql> set sql_mode=''; Query OK, 0 rows affected (0.01 sec) mysql> call p1(1/0); +------+ | a | +------+ | NULL | +------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
[28 May 2009 17:35]
Peter Gulutzan
I do not believe that we should consider this a bug. If I understand correctly, the point is that MySQL, for an IN parameter, evaluates the expression and makes an assignment before changing the sql_mode. But that is by design. Looking at the standard-SQL specification (SQL/Foundation, <routine invocation>) I gather that one should evaluate and assign before changing the routine execution context, before starting to execute the routine. And, although sql_mode is of course not standard, I believe it fits in routine execution context better than anywhere else. Therefore the routine's sql_mode does not have effect until the routine starts to execute. There is no contradiction with the manual. It says "always executes the routine with this setting in force", and that is the case. The only possible difficulty is that a user might not realize the routine execution does not begin until after the IN evaluation + assignment is over. Therefore I am setting this to "Documenting".
[28 May 2009 17:37]
Konstantin Osipov
Workarounds: - assign IN parameters to declared stored procedure variables - wrap invocation of a procedure into another CALL. - run consistently in the intended SQL mode.
[29 May 2009 19:59]
Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products. Added to manual: "The switch from the SQL mode of the invoker to that of the routine occurs after evaluation of arguments and assignment of the resulting values to routine parameters. If you define a routine in strict SQL mode but invoke it in non-strict mode, assignment of arguments to routine parameters does not take place in strict mode. If you require that expressions passed to a routine be assigned in strict SQL mode, you should invoke the routine with strict mode in effect." Note: The workaround of assigning parameters to local routine variables does not work. By then it's too late. For example, truncation of 9999 assigned to a TINYINT will already have occurred at parameter assignment.