1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations

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.
This commit is contained in:
Alexander Barkov
2017-03-08 23:20:39 +04:00
parent 1b8a0c879d
commit f429b5a834
20 changed files with 2447 additions and 85 deletions

View File

@ -1007,3 +1007,37 @@ Pos Instruction
5 set rec1.c@0["c"] rec1.d@0["d"]
DROP PROCEDURE p1;
DROP TABLE t1;
#
# MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations
#
CREATE TABLE t1 (a INT, b VARCHAR(10));
CREATE PROCEDURE p1()
AS
CURSOR cur1 IS SELECT * FROM t1;
CURSOR cur2 IS SELECT * FROM t1;
BEGIN
DECLARE
rec1,rec2 cur1%ROWTYPE;
rec3 cur2%ROWTYPE;
BEGIN
rec1.a:= 10;
rec1.b:= 'bbb';
END;
END;
$$
SHOW PROCEDURE CODE p1;
Pos Instruction
0 cpush cur1@0
1 cpush cur2@1
2 cursor_copy_struct rec1@0
3 set rec1@0 NULL
4 cursor_copy_struct rec2@1
5 set rec2@1 NULL
6 cursor_copy_struct rec3@2
7 set rec3@2 NULL
8 set rec1.a@0["a"] 10
9 set rec1.b@0["b"] 'bbb'
10 jump 11
11 cpop 2
DROP PROCEDURE p1;
DROP TABLE t1;