• Alexander Barkov's avatar
    MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations · f429b5a8
    Alexander Barkov authored
    Implementing cursor%ROWTYPE variables, according to the task description.
    
    This patch includes a refactoring in how sp_instr_cpush and sp_instr_copen
    work. This is needed to implement MDEV-10598 later easier, to allow variable
    declarations go after cursor declarations (which is currently not allowed).
    
    Before this patch, sp_instr_cpush worked as a Query_arena associated with
    the cursor. sp_instr_copen::execute() switched to the sp_instr_cpush's
    Query_arena when executing the cursor SELECT statement.
    
    Now the Query_arena associated with the cursor is stored inside an instance
    of a new class sp_lex_cursor (a LEX descendand) that contains the cursor SELECT
    statement.
    
    This simplifies the implementation, because:
    - It's easier to follow the code when everything related to execution
      of the cursor SELECT statement is stored inside the same sp_lex_cursor
      object (rather than distributed between LEX and sp_instr_cpush).
    - It's easier to link an sp_instr_cursor_copy_struct to
      sp_lex_cursor rather than to sp_instr_cpush.
    - Also, it allows to perform sp_instr_cursor_copy_struct::exec_core()
      without having a pointer to sp_instr_cpush, using a pointer to sp_lex_cursor
      instead. This will be important for MDEV-10598, because sp_instr_cpush will
      happen *after* sp_instr_cursor_copy_struct.
    
    After MDEV-10598 is done, this declaration:
    
    DECLARE
      CURSOR cur IS SELECT * FROM t1;
      rec cur%ROWTYPE;
    BEGIN
      OPEN cur;
      FETCH cur INTO rec;
      CLOSE cur;
    END;
    
    will generate about this code:
    
    +-----+--------------------------+
    | Pos | Instruction              |
    +-----+--------------------------+
    |   0 | cursor_copy_struct rec@0 | Points to sp_cursor_lex through m_lex_keeper
    |   1 | set rec@0 NULL           |
    |   2 | cpush cur@0              | Points to sp_cursor_lex through m_lex_keeper
    |   3 | copen cur@0              | Points to sp_cursor_lex through m_cursor
    |   4 | cfetch cur@0 rec@0       |
    |   5 | cclose cur@0             |
    |   6 | cpop 1                   |
    +-----+--------------------------+
    
    Notice, "cursor_copy_struct" and "set" will go before "cpush".
    Instructions at positions 0, 2, 3 point to the same sp_cursor_lex instance.
    f429b5a8
table.cc 245 KB