diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-03-08 23:20:39 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-05 15:02:59 +0400 |
commit | f429b5a834439e4f0c76e893487e33027d76b74b (patch) | |
tree | a06ec92dad05a2820ecd8a9afe73696b103536a3 /sql/sp_rcontext.h | |
parent | 1b8a0c879d80733e3c684080b8c7719c35642e0d (diff) | |
download | mariadb-git-f429b5a834439e4f0c76e893487e33027d76b74b.tar.gz |
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.
Diffstat (limited to 'sql/sp_rcontext.h')
-rw-r--r-- | sql/sp_rcontext.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 1c47b1caff0..98464518787 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -272,7 +272,7 @@ public: /// @return error flag. /// @retval false on success. /// @retval true on error. - bool push_cursor(THD *thd, sp_lex_keeper *lex_keeper, sp_instr_cpush *i); + bool push_cursor(THD *thd, sp_lex_keeper *lex_keeper); /// Pop and delete given number of sp_cursor instance from the cursor stack. /// @@ -434,7 +434,7 @@ private: }; public: - sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, sp_instr_cpush *i); + sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper); virtual ~sp_cursor() { destroy(); } @@ -443,6 +443,8 @@ public: int open(THD *thd); + int open_view_structure_only(THD *thd); + int close(THD *thd); my_bool is_open() @@ -459,14 +461,12 @@ public: int fetch(THD *, List<sp_variable> *vars); - sp_instr_cpush *get_instr() - { return m_i; } + bool export_structure(THD *thd, Row_definition_list *list); private: Select_fetch_into_spvars result; sp_lex_keeper *m_lex_keeper; Server_side_cursor *server_side_cursor; - sp_instr_cpush *m_i; // My push instruction ulonglong m_fetch_count; // Number of FETCH commands since last OPEN ulonglong m_row_count; // Number of successful FETCH since last OPEN bool m_found; // If last FETCH fetched a row |