• Alexander Barkov's avatar
    MDEV-32275 getting error 'Illegal parameter data types row and bigint for... · 534a2bf1
    Alexander Barkov authored
    MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO
    
    An "ITERATE innerLoop" did not work properly inside
    a WHILE loop, which itself is inside an outer FOR loop:
    
    outerLoop:
      FOR
       ...
       innerLoop:
        WHILE
          ...
          ITERATE innerLoop;
          ...
        END WHILE;
        ...
      END FOR;
    
    It erroneously generated an integer increment code for the outer FOR loop.
    There were two problems:
    1. "ITERATE innerLoop" worked like "ITERATE outerLoop"
    2. It was always integer increment, even in case of FOR cursor loops.
    
    Background:
    - A FOR loop automatically creates a dedicated sp_pcontext stack entry,
      to put the iteration and bound variables on it.
    
    - Other loop types (LOOP, WHILE, REPEAT), do not generate a dedicated
      slack entry.
    
      The old code erroneously assumed that sp_pcontext::m_for_loop
      either describes the most inner loop (in case the inner loop is FOR),
      or is empty (in case the inner loop is not FOR).
    
      But in fact, sp_pcontext::m_for_loop is never empty inside a FOR loop:
      it describes the closest FOR loop, even if this FOR loop has nested
      non-FOR loops inside.
    
      So when we're near the ITERATE statement in the above script,
      sp_pcontext::m_for_loop is not empty - it stores information about
      the FOR loop labeled as "outrLoop:".
    
    Fix:
    - Adding a new member sp_pcontext::Lex_for_loop::m_start_label,
      to remember the explicit or the auto-generated label correspoding
      to the start of the FOR body. It's used during generation
      of "ITERATE loop_label" code to check if "loop_label" belongs
      to the current FOR loop pointed by sp_pcontext::m_for_loop,
      or belongs to a non-FOR nested loop.
    
    - Adding LEX methods sp_for_loop_intrange_iterate() and
      sp_for_loop_cursor_iterate() to reuse the code between
      methods handling:
      * ITERATE
      * END FOR
    
    - Adding a test for Lex_for_loop::is_for_loop_cursor()
      and generate a code either a cursor fetch, or for an integer increment.
      Before this change, it always erroneously generated an integer increment
      version.
    
    - Cleanup: Initialize Lex_for_loop_st::m_cursor_offset inside
      Lex_for_loop_st::init(), to avoid not initialized members.
    
    - Cleanup: Removing a redundant method:
        Lex_for_loop_st::init(const Lex_for_loop_st &other)
      Using Lex_for_loop_st::operator(const Lex_for_loop_st &other) instead.
    534a2bf1
structs.h 25.2 KB