Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-14415

Add Oracle-style FOR loop to sql_mode=DEFAULT

Details

    Description

      This MDEV is a part of MDEV-12518.
      Under terms of this task we'll add Oracle-style FOR loop (both for integer ranges and cursors) into sql_mode=DEFAULT.
      FOR loops will be a non-standard MariaDB extension.

      We won't implement the SQL-standard cursor FOR loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

      Proposed syntax:

      • Integer range FOR loop:

        [begin_label:]
        FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
        DO statement_list
        END FOR [ end_label ]
        

      • Explicit cursor FOR loop

        [begin_label:]
        FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
        DO statement_list
        END FOR [ end_label ]
        

      • Implicit cursor FOR loop

        [begin_label:]
        FOR record_name IN ( select_statement )
        DO statement_list
        END FOR [ end_label ]
        

      The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for FOR loop:

      • It generally uses Oracle style syntax
      • however, like in the SQL standard, it uses FOR..DO..END FOR (instead or Oracle's FOR..LOOP..END LOOP)

      Note, for cursor FOR loops, there is no a need to do OPEN, FETCH and CLOSE. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor FOR loop body using explicit FETCH commands.

      In sql_mode=DEFAULT, the automatic implicit FETCH which happens on FOR iterations and an explicit FETCH inside the loop body will work differently:

      • The automatic FETCH will never generate errors. On NOT FOUND, it will automatically close the cursor and leave the loop.
      • An explicit FETCH command inside the FOR loop will work like normal FETCH commands: i.e. it will generate an error on NOT FOUND, even when used with the FOR cursor.

      This script uses an extra FETCH command inside the loop body:

      DELIMITER $$
      BEGIN NOT ATOMIC
        DECLARE x INT;
        DECLARE cur CURSOR FOR SELECT 1 AS x;
        FOR rec IN cur
        DO
          FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
        END FOR;
      END;
      $$
      DELIMITER ;
      

      It will return:

      ERROR 02000: No data - zero rows fetched, selected, or processed
      

      because the explicit FETCH command returns no rows: the first record is fetched automatically in the beginning of the FOR iteration, and there are no more records.

      FETCH commands inside the FOR body will be normally handled by "NOT FOUND" handlers.
      The following script uses a FETCH command with the FOR loop cursor, in combination with a CONTINUE HANDLER FOR NOT FOUND.

      DELIMITER $$
      BEGIN NOT ATOMIC
        DECLARE done INT DEFAULT 0;
        DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                               SELECT 2,'y2' UNION
                               SELECT 3,'y3';
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
        forrec:
        FOR rec IN cur
        DO
          SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
          FETCH cur INTO rec;
          IF done THEN
            SELECT 'NO DATA' AS `Explicit FETCH`;
            LEAVE forrec;
          ELSE
            SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
          END IF;
        END FOR;
      END;
      $$
      DELIMITER ;
      

      It will return without errors, with the following output:

      Implicit FETCH
      1 y1
      Explicit FETCH
      2 y2
      Implicit FETCH
      3 y3
      Explicit FETCH
      NO DATA
      

      Notice:

      • some records are fetched using the automatic FETCH on FOR iterations
      • some records are fetched using the explicit FETCH command inside the loop body
      • the last explicit FETCH fails on NOT FOUND, which is caught by the CONTINUE handler, and the error is suppressed.

      Attachments

        Issue Links

          Activity

            bar Alexander Barkov created issue -
            bar Alexander Barkov made changes -
            Field Original Value New Value
            bar Alexander Barkov made changes -
            Sprint 10.3.3-2 [ 208 ]
            Labels Compatibility
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer range and for cursor) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer range and for cursor) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_formal_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the cursor.

            This script:
            {code:sql}
            DELIMITER $$;
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;$$
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the cursor.

            This script:
            {code:sql}
            DELIMITER $$;
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;$$
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$;
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;$$
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$;
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;$$
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            In sql_mode=DEFAULT, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically.

            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically.

            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - Explicit {{FETCH}} commands inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}}

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on "NOT FOUND", even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetches automatically in the beginning of the {{FOR}} iteration.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetches automatically in the beginning of the {{FOR}} iteration.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetches automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            issue.field.resolutiondate 2017-11-16 10:48:20.0 2017-11-16 10:48:20.556
            bar Alexander Barkov made changes -
            Fix Version/s 10.3.3 [ 22644 ]
            Fix Version/s 10.3 [ 22126 ]
            Resolution Fixed [ 1 ]
            Status Open [ 1 ] Closed [ 6 ]
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetches automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetched automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetched automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler and suppresses the error.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetched automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler, and the error is suppressed.
            bar Alexander Barkov made changes -
            Description This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetched automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler, and the error is suppressed.
            This MDEV is a part of MDEV-12518.
            Under terms of this task we'll add Oracle-style {{FOR}} loop (both for integer ranges and cursors) into {{sql_mode=DEFAULT}}.
            {{FOR}} loops will be a non-standard MariaDB extension.

            We won't implement the SQL-standard cursor {{FOR}} loop yet, because it would need to open the cursor at parse time to know column names of the cursor.

            Proposed syntax:

            - Integer range {{FOR}} loop:
            {noformat}
            [begin_label:]
            FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Explicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            - Implicit cursor {{FOR}} loop
            {noformat}
            [begin_label:]
            FOR record_name IN ( select_statement )
            DO statement_list
            END FOR [ end_label ]
            {noformat}

            The proposed syntax is a compilation of the SQL standard syntax and Oracle's syntax for {{FOR}} loop:
            - It generally uses Oracle style syntax
            - however, like in the SQL standard, it uses {{FOR}}..{{DO}}..{{END FOR}} (instead or Oracle's {{FOR}}..{{LOOP}}..{{END LOOP}})

            Note, for cursor {{FOR}} loops, there is no a need to do {{OPEN}}, {{FETCH}} and {{CLOSE}}. These commands are done automatically. However, it will still be possible to fetch extra records inside the explicit cursor {{FOR}} loop body using explicit {{FETCH}} commands.


            In {{sql_mode=DEFAULT}}, the automatic implicit {{FETCH}} which happens on {{FOR}} iterations and an explicit {{FETCH}} inside the loop body will work differently:
            - The automatic {{FETCH}} will never generate errors. On {{NOT FOUND}}, it will automatically close the cursor and leave the loop.
            - An explicit {{FETCH}} command inside the {{FOR}} loop will work like normal {{FETCH}} commands: i.e. it will generate an error on {{NOT FOUND}}, even when used with the {{FOR}} cursor.

            This script uses an extra {{FETCH}} command inside the loop body:
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE x INT;
              DECLARE cur CURSOR FOR SELECT 1 AS x;
              FOR rec IN cur
              DO
                FETCH cur INTO x; -- Notice it uses "cur" (the loop cursor)
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return:
            {noformat}
            ERROR 02000: No data - zero rows fetched, selected, or processed
            {noformat}
            because the explicit {{FETCH}} command returns no rows: the first record is fetched automatically in the beginning of the {{FOR}} iteration, and there are no more records.

            {{FETCH}} commands inside the {{FOR}} body will be normally handled by "{{NOT FOUND}}" handlers.
            The following script uses a {{FETCH}} command with the {{FOR}} loop cursor, in combination with a {{CONTINUE HANDLER FOR NOT FOUND}}.
            {code:sql}
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE done INT DEFAULT 0;
              DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
                                     SELECT 2,'y2' UNION
                                     SELECT 3,'y3';
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
              forrec:
              FOR rec IN cur
              DO
                SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
                FETCH cur INTO rec;
                IF done THEN
                  SELECT 'NO DATA' AS `Explicit FETCH`;
                  LEAVE forrec;
                ELSE
                  SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
                END IF;
              END FOR;
            END;
            $$
            DELIMITER ;
            {code}
            It will return without errors, with the following output:
            {noformat}
            Implicit FETCH
            1 y1
            Explicit FETCH
            2 y2
            Implicit FETCH
            3 y3
            Explicit FETCH
            NO DATA
            {noformat}
            Notice:
            - some records are fetched using the automatic {{FETCH}} on {{FOR}} iterations
            - some records are fetched using the explicit {{FETCH}} command inside the loop body
            - the last explicit {{FETCH}} fails on {{NOT FOUND}}, which is caught by the {{CONTINUE}} handler, and the error is suppressed.
            serg Sergei Golubchik made changes -
            serg Sergei Golubchik made changes -
            Sprint 10.3.3-2 [ 208 ]
            serg Sergei Golubchik made changes -
            Rank Ranked higher
            bar Alexander Barkov made changes -
            bar Alexander Barkov made changes -
            rdyas Robert Dyas added a comment -

            I can't find this in the MariaDB documentation... is it there and I just missed it?

            Especially useful to note in the docs that 10.3.3+ has ANSI SQL cursor FOR loop with simple cursor example. So much easier than the exiting way for 99% of my uses cases.

            rdyas Robert Dyas added a comment - I can't find this in the MariaDB documentation... is it there and I just missed it? Especially useful to note in the docs that 10.3.3+ has ANSI SQL cursor FOR loop with simple cursor example. So much easier than the exiting way for 99% of my uses cases.

            MariaDB 10.3 does not support ANSI SQL cursor FOR. It's kind-of-like-in-Oracle cursor FOR. Functionality is pretty much the same, syntax is a bit different. Still, strictly speaking, not standard.

            serg Sergei Golubchik added a comment - MariaDB 10.3 does not support ANSI SQL cursor FOR. It's kind-of-like-in-Oracle cursor FOR. Functionality is pretty much the same, syntax is a bit different. Still, strictly speaking, not standard.
            bar Alexander Barkov added a comment - - edited

            The documentation is currently in progress:
            MDEV-16674 Document FOR loop

            In the meanwhile please have a look into this MDEV-14415, as well as these test files:

            https://github.com/MariaDB/server/blob/10.3/mysql-test/main/sp-for-loop.test
            https://github.com/MariaDB/server/blob/10.3/mysql-test/main/sp-cursor.test

            bar Alexander Barkov added a comment - - edited The documentation is currently in progress: MDEV-16674 Document FOR loop In the meanwhile please have a look into this MDEV-14415 , as well as these test files: https://github.com/MariaDB/server/blob/10.3/mysql-test/main/sp-for-loop.test https://github.com/MariaDB/server/blob/10.3/mysql-test/main/sp-cursor.test
            rdyas Robert Dyas added a comment -

            In the documentation if you could clarify what happens with rec.col references if col is ambiguous from a join... is it simply rec.table.col as you would guess? Example:

            CREATE TABLE t1 (id INT, name VARCHAR(10));
            INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
            CREATE TABLE t2 (id INT, name VARCHAR(10));
            INSERT INTO t1 VALUES (1,'bob'), (2,'sam'), (3,'frank');
             
            BEGIN NOT ATOMIC
              DECLARE cur CURSOR FOR 
                 SELECT * FROM t1 JOIN t2 ON (t2.id = t1.id);
             
              FOR rec IN cur DO
                 SELECT rec.id, rec.name; -- both id and name are ambiguous ... what is correct syntax? rec.t2.name?
              END FOR;
             
            END;
            

            rdyas Robert Dyas added a comment - In the documentation if you could clarify what happens with rec.col references if col is ambiguous from a join... is it simply rec.table.col as you would guess? Example: CREATE TABLE t1 (id INT , name VARCHAR (10)); INSERT INTO t1 VALUES (1, 'b1' ), (2, 'b2' ), (3, 'b3' ); CREATE TABLE t2 (id INT , name VARCHAR (10)); INSERT INTO t1 VALUES (1, 'bob' ), (2, 'sam' ), (3, 'frank' );   BEGIN NOT ATOMIC DECLARE cur CURSOR FOR SELECT * FROM t1 JOIN t2 ON (t2.id = t1.id);   FOR rec IN cur DO SELECT rec.id, rec. name ; -- both id and name are ambiguous ... what is correct syntax? rec.t2.name? END FOR ;   END ;

            I tested this script:

            DROP TABLE IF EXISTS t1, t2;
            CREATE TABLE t1 (id INT, name VARCHAR(10));
            INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
            CREATE TABLE t2 (id INT, name VARCHAR(10));
            INSERT INTO t2 VALUES (1,'bob'), (2,'sam'), (3,'frank');
             
            DELIMITER $$
            BEGIN NOT ATOMIC
              DECLARE cur CURSOR FOR 
                 SELECT * FROM t1 JOIN t2 ON (t2.id = t1.id);
              FOR rec IN cur DO
                 SELECT rec.id, rec.name; -- both id and name are ambiguous ... what is correct syntax? rec.t2.name?
              END FOR;
            END;
            $$
            DELIMITER ;
            

            and it correctly returns this error:

            ERROR 1060 (42S21): Duplicate column name 'id'
            

            The correct syntax is to give unique names to columns using AS, e.g. like this:

            SELECT id, t1.name AS name1, t2.name AS name2 FROM t1 JOIN t2 USING (id);
            

            bar Alexander Barkov added a comment - I tested this script: DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (id INT , name VARCHAR (10)); INSERT INTO t1 VALUES (1, 'b1' ), (2, 'b2' ), (3, 'b3' ); CREATE TABLE t2 (id INT , name VARCHAR (10)); INSERT INTO t2 VALUES (1, 'bob' ), (2, 'sam' ), (3, 'frank' );   DELIMITER $$ BEGIN NOT ATOMIC DECLARE cur CURSOR FOR SELECT * FROM t1 JOIN t2 ON (t2.id = t1.id); FOR rec IN cur DO SELECT rec.id, rec. name ; -- both id and name are ambiguous ... what is correct syntax? rec.t2.name? END FOR ; END ; $$ DELIMITER ; and it correctly returns this error: ERROR 1060 (42S21): Duplicate column name 'id' The correct syntax is to give unique names to columns using AS, e.g. like this: SELECT id, t1. name AS name1, t2. name AS name2 FROM t1 JOIN t2 USING (id);
            julien.fritsch Julien Fritsch made changes -
            Comment [ test ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 83841 ] MariaDB v4 [ 133399 ]
            bar Alexander Barkov made changes -

            People

              bar Alexander Barkov
              bar Alexander Barkov
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.