dolt icon indicating copy to clipboard operation
dolt copied to clipboard

DECLARE CONTINUE HANDLER failure in dolt

Open macneale4 opened this issue 1 year ago • 1 comments

I have a stored procedure which works fine in MySQL, but results in an infinite loop in dolt:

Setup:

mysql> create table tbl (id int auto_increment primary key, checksum varchar(40));
mysql> insert into tbl (1, sha("macneale"));

Add a stored procedure. A little convoluted, but the idea is that is calculates a new checksum from all existing values and inserts a new value

DELIMITER //

CREATE PROCEDURE calculate_and_insert_checksum()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE current_checksum VARCHAR(40);
    DECLARE concat_string VARCHAR(10000);
    DECLARE new_checksum VARCHAR(40);

    DECLARE cur CURSOR FOR SELECT checksum FROM tbl;

    -- Stop loop at end of set.
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    SET concat_string = '';
    OPEN cur;
    -- Loop through the rows and concatenate checksum values
    read_loop: LOOP
        FETCH cur INTO current_checksum;

        IF done THEN
            LEAVE read_loop;
        END IF;

        SET concat_string = CONCAT(concat_string, current_checksum);
    END LOOP;

    CLOSE cur;

    SET new_checksum = SHA1(concat_string);

    INSERT INTO tbl (checksum) VALUES (new_checksum);

    SELECT new_checksum as calculated_checksum;
END //

DELIMITER ;

This works fine in mysql:

mysql> call calculate_and_insert_checksum();
+------------------------------------------+
| calculated_checksum                      |
+------------------------------------------+
| 89fa71febbc9effd2fa58c7441ad2ed899fcdcf1 |
+------------------------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tbl;
+----+------------------------------------------+
| id | checksum                                 |
+----+------------------------------------------+
|  1 | ca530ba53d2e3b54206e62c7ab257657b7367cc7 |
|  2 | 89fa71febbc9effd2fa58c7441ad2ed899fcdcf1 |
+----+------------------------------------------+
2 rows in set (0.00 sec)

But in Dolt, it loops for ever. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; is not actually having an effect, and done always equals 0 as a result. Infinite loop!

macneale4 avatar Sep 28 '23 22:09 macneale4

I created a change which fixed this specific problem, but it's definitely not correct: https://github.com/dolthub/go-mysql-server/pull/2055/commits/f8b87e778dd5e7d335ea1ba57eb3831183d5cfe1

Going to close that PR as addressing this is not a small change. We don't support the CONTINUE keyword for any of our loops, and they current implementation would require us to run this in the planning phase, which is not a great idea.

macneale4 avatar Oct 10 '23 23:10 macneale4