Bug #72347 | Handlers for error # 1137 don't seem to execute within stored functions | ||
---|---|---|---|
Submitted: | 14 Apr 2014 17:44 | Modified: | 17 Apr 2014 15:45 |
Reporter: | Dillon Sadofsky | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Stored Routines | Severity: | S1 (Critical) |
Version: | 5.6.14-log | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | 1137, stored function, temporary table |
[14 Apr 2014 17:44]
Dillon Sadofsky
[14 Apr 2014 19:03]
MySQL Verification Team
Verified as described ...
[17 Apr 2014 13:54]
MySQL Verification Team
After very careful analysis it was concluded that this is not a bug. The main reason is that the opening of tables occurs before the function is executed. Therefore the error is raised before the handler is activated. Simply put, the tables are opened outside the stored function, thus the handler logic is not activated. However, if the calling code is put into a stored procedure, and the handling logic is moved there too, everything works. So, here is a workaround (in a form of .test file): DELIMITER $$; DROP FUNCTION IF EXISTS f_insert_into_table$$ DROP FUNCTION IF EXISTS f_update_table$$ DROP FUNCTION IF EXISTS f_select_from_table$$ # function used to demonstrate a sub-function inserting into a temp table # without aliases CREATE FUNCTION `f_insert_into_table`() RETURNS BOOL LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA BEGIN INSERT INTO TEMP_test (id) VALUES (1); RETURN TRUE; END$$ # A function that shows a temp table CAN be reopened in a separate function # (without aliases) CREATE FUNCTION `f_update_table`() RETURNS BOOL LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA BEGIN IF (f_insert_into_table()) THEN UPDATE TEMP_test SET id = 2; RETURN TRUE; END IF; RETURN FALSE; END$$ # This function creates the temp table and calls the above 2 functions, then # selects from the table (no aliases). This works so long as the table didn't # exist beforehand CREATE FUNCTION `f_select_from_table`() RETURNS INT UNSIGNED LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA BEGIN DECLARE val INT UNSIGNED DEFAULT 0; CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_test (id INT UNSIGNED); IF (f_update_table()) THEN SELECT id INTO val FROM TEMP_test LIMIT 1; END IF; DROP TEMPORARY TABLE TEMP_test; RETURN val; END$$ CREATE PROCEDURE p1() BEGIN DECLARE CONTINUE HANDLER FOR 1137 BEGIN SET @var1 = 1; END; DECLARE CONTINUE HANDLER FOR SQLSTATE 'HY000' BEGIN SET @var1 = 1; END; # Create this table to cause an undocumented error to happen CREATE TEMPORARY TABLE TEMP_test(id INT UNSIGNED); SET @var1 = 0; SELECT f_select_from_table(); # var1 should be 1 if the HANDLER had been executed. SELECT @var1; END$$ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; DROP FUNCTION f_select_from_table; DROP FUNCTION f_update_table; DROP FUNCTION f_insert_into_table;
[17 Apr 2014 15:45]
Dillon Sadofsky
I understand what you're saying, but the distinction that some errors are thrown 'before' a function is not obvious to the user. I cannot use the suggested workaround because I need to use a stored function (I'm retrieving a single value for use in UPDATE statements). Refer to the bug that spawned this bug for more information. The fact that it is possible to put a set of functions into an unusable state due to the preexistance of a temporary table seems like undesired functionality to me. Both issues have been reported as not a bug, but taken together, the represent a situation where a connection can get into a state where a (normally working) function cannot be executed and no procedural workaround can be developed. I am disappointed that this is the case. This all seems to be based on the fact that functions pre-explore their contents when they are invoked instead of when they are executed. I noticed separately that when we upgraded from version 5.5 to 5.6, this made functions that contain other functions or views hundreds of times slower than they were before (even if the function or view is in unreachable code). It would be nice if functions (like procedures) executed line by line, as is intuitive to the user. If stored procedures could be used in more situations, I would switch to them, but our system performs some business logic at the database level, and the various restrictions on functions make this very hard.