MySQL 8.0.29
Source Code Documentation
sp_rcontext.h
Go to the documentation of this file.
1/* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef _SP_RCONTEXT_H_
24#define _SP_RCONTEXT_H_
25
26#include <assert.h>
27#include <stddef.h>
28#include <sys/types.h>
29
30#include "my_inttypes.h"
31#include "prealloced_array.h" // Prealloced_array
32#include "sql/item.h"
33#include "sql/query_result.h" // Query_result_interceptor
34#include "sql/sql_array.h"
35#include "sql/sql_error.h"
36#include "sql/table.h"
37
38class Field;
39class Query_arena;
42class THD;
43class sp_cursor;
44class sp_handler;
45class sp_head;
46class sp_instr;
47class sp_instr_cpush;
48class sp_pcontext;
49class sp_variable;
50template <class T>
51class List;
52
53///////////////////////////////////////////////////////////////////////////
54// sp_rcontext declaration.
55///////////////////////////////////////////////////////////////////////////
56
57/*
58 This class is a runtime context of a Stored Routine. It is used in an
59 execution and is intended to contain all dynamic objects (i.e. objects, which
60 can be changed during execution), such as:
61 - stored routine variables;
62 - cursors;
63 - handlers;
64
65 Runtime context is used with sp_head class. sp_head class is intended to
66 contain all static things, related to the stored routines (code, for example).
67 sp_head instance creates runtime context for the execution of a stored
68 routine.
69
70 There is a parsing context (an instance of sp_pcontext class), which is used
71 on parsing stage. However, now it contains some necessary for an execution
72 things, such as definition of used stored routine variables. That's why
73 runtime context needs a reference to the parsing context.
74*/
75
77 public:
78 /// Construct and properly initialize a new sp_rcontext instance. The static
79 /// create-function is needed because we need a way to return an error from
80 /// the constructor.
81 ///
82 /// @param thd Thread handle.
83 /// @param root_parsing_ctx Top-level parsing context for this stored program.
84 /// @param return_value_fld Field object to store the return value
85 /// (for stored functions only).
86 ///
87 /// @return valid sp_rcontext object or NULL in case of OOM-error.
88 static sp_rcontext *create(THD *thd, const sp_pcontext *root_parsing_ctx,
89 Field *return_value_fld);
90
92
93 private:
94 sp_rcontext(const sp_pcontext *root_parsing_ctx, Field *return_value_fld,
95 bool in_sub_stmt);
96
97 // Prevent use of copying constructor and operator.
100
101 private:
102 /// This is an auxillary class to store entering instruction pointer for an
103 /// SQL-handler.
105 public:
106 /// Handler definition (from parsing context).
108
109 /// Instruction pointer to the first instruction.
111
112 /// The constructor.
113 ///
114 /// @param _handler sp_handler object.
115 /// @param _first_ip first instruction pointer.
116 sp_handler_entry(const sp_handler *_handler, uint _first_ip)
117 : handler(_handler), first_ip(_first_ip) {}
118 };
119
120 public:
121 /// This class represents a call frame of SQL-handler (one invocation of a
122 /// handler). Basically, it's needed to store continue instruction pointer for
123 /// CONTINUE SQL-handlers.
125 public:
126 /// Handler definition (from parsing context).
128
129 /// SQL-condition, triggered handler activation.
131
132 /// Continue-instruction-pointer for CONTINUE-handlers.
133 /// The attribute contains 0 for EXIT-handlers.
135
136 /// The Diagnostics Area which will be pushed when the handler activates
137 /// and popped when the handler completes.
139
140 /// The constructor.
141 ///
142 /// @param _handler SQL-handler
143 /// @param _sql_condition SQL-condition, triggered handler activation.
144 /// @param _continue_ip Continue instruction pointer.
146 Sql_condition *_sql_condition, uint _continue_ip)
147 : handler(_handler),
148 sql_condition(_sql_condition),
149 continue_ip(_continue_ip),
150 handler_da(false) {}
151 };
152
153 public:
154 /// Arena used to (re) allocate items on. E.g. reallocate INOUT/OUT
155 /// SP-variables when they don't fit into prealloced items. This is common
156 /// situation with String items. It is used mainly in sp_eval_func_item().
158
159 /// Flag to end an open result set before start executing an SQL-handler
160 /// (if one is found). Otherwise the client will hang due to a violation
161 /// of the client/server protocol.
163
164 /// The stored program for which this runtime context is created.
166
167 /////////////////////////////////////////////////////////////////////////
168 // SP-variables.
169 /////////////////////////////////////////////////////////////////////////
170
171 bool set_variable(THD *thd, uint var_idx, Item **value) {
172 return set_variable(thd, m_var_table->field[var_idx], value);
173 }
174
175 Item *get_item(uint var_idx) const { return m_var_items[var_idx]; }
176
177 Item **get_item_addr(uint var_idx) const {
178 return m_var_items.array() + var_idx;
179 }
180
181 bool set_return_value(THD *thd, Item **return_value_item);
182
184
185 /////////////////////////////////////////////////////////////////////////
186 // SQL-handlers.
187 /////////////////////////////////////////////////////////////////////////
188
189 /// Create a new sp_handler_entry instance and push it to the handler call
190 /// stack.
191 ///
192 /// @param handler SQL-handler object.
193 /// @param first_ip First instruction pointer of the handler.
194 ///
195 /// @return error flag.
196 /// @retval false on success.
197 /// @retval true on error.
198 bool push_handler(sp_handler *handler, uint first_ip);
199
200 /// Pop and delete given number of sp_handler_entry instances from the handler
201 /// call stack.
202 ///
203 /// @param current_scope The current BEGIN..END block.
204 void pop_handlers(sp_pcontext *current_scope);
205
206 /// Get the Handler_call_frame representing the currently active handler.
208 return m_activated_handlers.size() ? m_activated_handlers.back() : NULL;
209 }
210
211 /// Handle current SQL condition (if any).
212 ///
213 /// This is the public-interface function to handle SQL conditions in
214 /// stored routines.
215 ///
216 /// @param thd Thread handle.
217 /// @param [out] ip Instruction pointer to the first handler
218 /// instruction.
219 /// @param cur_spi Current SP instruction.
220 ///
221 /// @retval true if an SQL-handler has been activated. That means, all of
222 /// the following conditions are satisfied:
223 /// - the SP-instruction raised SQL-condition(s),
224 /// - and there is an SQL-handler to process at least one of those
225 /// SQL-conditions,
226 /// - and that SQL-handler has been activated.
227 /// Note, that the return value has nothing to do with "error flag"
228 /// semantics.
229 ///
230 /// @retval false otherwise.
231 bool handle_sql_condition(THD *thd, uint *ip, const sp_instr *cur_spi);
232
233 /// Handle return from SQL-handler.
234 ///
235 /// @param thd Thread handle.
236 /// @param target_scope The BEGIN..END block, containing
237 /// the target (next) instruction.
238 void exit_handler(THD *thd, sp_pcontext *target_scope);
239
240 /// @return the continue instruction pointer of the last activated CONTINUE
241 /// handler. This function must not be called for the EXIT handlers.
243 uint ip = m_activated_handlers.back()->continue_ip;
244 assert(ip != 0);
245
246 return ip;
247 }
248
249 /////////////////////////////////////////////////////////////////////////
250 // Cursors.
251 /////////////////////////////////////////////////////////////////////////
252
253 /// Create a new sp_cursor instance and push it to the cursor stack.
254 ///
255 /// @param i Cursor-push instruction.
256 ///
257 /// @return error flag.
258 /// @retval false on success.
259 /// @retval true on error.
261
262 /// Pop and delete given number of sp_cursor instance from the cursor stack.
263 ///
264 /// @param count Number of cursors to pop & delete.
265 void pop_cursors(uint count);
266
268
269 sp_cursor *get_cursor(uint i) const { return m_cstack[i]; }
270
271 /////////////////////////////////////////////////////////////////////////
272 // CASE expressions.
273 /////////////////////////////////////////////////////////////////////////
274
275 /// Set CASE expression to the specified value.
276 ///
277 /// @param thd Thread handler.
278 /// @param case_expr_id The CASE expression identifier.
279 /// @param case_expr_item_ptr The CASE expression value
280 ///
281 /// @return error flag.
282 /// @retval false on success.
283 /// @retval true on error.
284 ///
285 /// @note The idea is to reuse Item_cache for the expression of the one
286 /// CASE statement. This optimization takes place when there is CASE
287 /// statement inside of a loop. So, in other words, we will use the same
288 /// object on each iteration instead of creating a new one for each
289 /// iteration.
290 ///
291 /// TODO
292 /// Hypothetically, a type of CASE expression can be different for each
293 /// iteration. For instance, this can happen if the expression contains
294 /// a session variable (something like @@VAR) and its type is changed
295 /// from one iteration to another.
296 ///
297 /// In order to cope with this problem, we check type each time, when we
298 /// use already created object. If the type does not match, we re-create
299 /// Item. This also can (should?) be optimized.
300 bool set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
301
302 Item *get_case_expr(int case_expr_id) const {
303 return m_case_expr_holders[case_expr_id];
304 }
305
306 Item **get_case_expr_addr(int case_expr_id) const {
307 return (Item **)m_case_expr_holders.array() + case_expr_id;
308 }
309
310 private:
311 /// Internal function to allocate memory for arrays.
312 ///
313 /// @param thd Thread handle.
314 ///
315 /// @return error flag: false on success, true in case of failure.
316 bool alloc_arrays(THD *thd);
317
318 /// Create and initialize a table to store SP-variables.
319 ///
320 /// param thd Thread handle.
321 ///
322 /// @return error flag.
323 /// @retval false on success.
324 /// @retval true on error.
325 bool init_var_table(THD *thd);
326
327 /// Create and initialize an Item-adapter (Item_field) for each SP-var field.
328 ///
329 /// param thd Thread handle.
330 ///
331 /// @return error flag.
332 /// @retval false on success.
333 /// @retval true on error.
334 bool init_var_items(THD *thd);
335
336 /// Create an instance of appropriate Item_cache class depending on the
337 /// specified type in the callers arena.
338 ///
339 /// @note We should create cache items in the callers arena, as they are
340 /// used between in several instructions.
341 ///
342 /// @param thd Thread handler.
343 /// @param item Item to get the expression type.
344 ///
345 /// @return Pointer to valid object on success, or NULL in case of error.
346 Item_cache *create_case_expr_holder(THD *thd, const Item *item) const;
347
348 bool set_variable(THD *thd, Field *field, Item **value);
349
350 /// Pop the Handler_call_frame on top of the stack of active handlers.
351 /// Also pop the matching Diagnostics Area and transfer conditions.
352 void pop_handler_frame(THD *thd);
353
354 private:
355 /// Top-level (root) parsing context for this runtime context.
357
358 /// Virtual table for storing SP-variables.
360
361 /// Collection of Item_field proxies, each of them points to the
362 /// corresponding field in m_var_table.
364
365 /// This is a pointer to a field, which should contain return value for
366 /// stored functions (only). For stored procedures, this pointer is NULL.
368
369 /// Indicates whether the return value (in m_return_value_fld) has been
370 /// set during execution.
372
373 /// Flag to tell if the runtime context is created for a sub-statement.
375
376 /// Stack of visible handlers.
378
379 /// Stack of caught SQL conditions.
381
382 /// Stack of cursors.
384
385 /// Current number of cursors in m_cstack.
387
388 /// Array of CASE expression holders.
390};
391
392///////////////////////////////////////////////////////////////////////////
393// sp_cursor declaration.
394///////////////////////////////////////////////////////////////////////////
395
396/* A mediator between stored procedures and server side cursors */
397
399 private:
400 /**
401 An interceptor of cursor result set used to implement
402 FETCH @<cname@> INTO @<varlist@>.
403 */
407
408 public:
412
413 bool send_eof(THD *) override { return false; }
414 bool send_data(THD *thd, const mem_root_deque<Item *> &items) override;
415 bool prepare(THD *thd, const mem_root_deque<Item *> &list,
416 Query_expression *u) override;
417 };
418
419 public:
422
423 virtual ~sp_cursor() { destroy(); }
424
425 bool open(THD *thd);
426
427 bool close();
428
429 bool is_open() const { return m_server_side_cursor != nullptr; }
430
431 bool fetch(List<sp_variable> *vars);
432
434
435 private:
437
440
441 private:
442 void destroy();
443}; // class sp_cursor
444
445#endif /* _SP_RCONTEXT_H_ */
Element_type * array() const
Definition: sql_array.h:142
Stores status of the currently executed statement.
Definition: sql_error.h:268
Definition: field.h:573
Definition: item.h:6492
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:802
Definition: sql_list.h:433
A typesafe replacement for DYNAMIC_ARRAY.
Definition: prealloced_array.h:70
Definition: sql_class.h:358
This class represents a query expression (one query block or several query blocks combined with UNION...
Definition: sql_lex.h:629
Definition: query_result.h:200
Server_side_cursor – an interface for materialized implementation of cursors.
Definition: sql_cursor.h:50
Representation of a SQL condition.
Definition: sql_error.h:57
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:945
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4157
A (partial) implementation of std::deque allocating its blocks on a MEM_ROOT.
Definition: mem_root_deque.h:109
An interceptor of cursor result set used to implement FETCH <cname> INTO <varlist>.
Definition: sp_rcontext.h:404
bool send_eof(THD *) override
Definition: sp_rcontext.h:413
uint field_count
Definition: sp_rcontext.h:406
List< sp_variable > * spvar_list
Definition: sp_rcontext.h:405
void set_spvar_list(List< sp_variable > *vars)
Definition: sp_rcontext.h:411
bool send_data(THD *thd, const mem_root_deque< Item * > &items) override
Definition: sp_rcontext.cc:533
uint get_field_count()
Definition: sp_rcontext.h:410
bool prepare(THD *thd, const mem_root_deque< Item * > &list, Query_expression *u) override
Perform preparation specific to the query expression or DML statement.
Definition: sp_rcontext.cc:523
Query_fetch_into_spvars()
Definition: sp_rcontext.h:409
Definition: sp_rcontext.h:398
sp_instr_cpush * m_push_instr
Definition: sp_rcontext.h:439
bool is_open() const
Definition: sp_rcontext.h:429
bool open(THD *thd)
Open an SP cursor.
Definition: sp_rcontext.cc:455
bool fetch(List< sp_variable > *vars)
Definition: sp_rcontext.cc:484
sp_instr_cpush * get_push_instr()
Definition: sp_rcontext.h:433
bool close()
Definition: sp_rcontext.cc:471
virtual ~sp_cursor()
Definition: sp_rcontext.h:423
sp_cursor(sp_instr_cpush *i)
Definition: sp_rcontext.h:420
Server_side_cursor * m_server_side_cursor
Definition: sp_rcontext.h:438
void destroy()
Definition: sp_rcontext.cc:482
Query_fetch_into_spvars m_result
Definition: sp_rcontext.h:436
This class represents 'DECLARE HANDLER' statement.
Definition: sp_pcontext.h:192
sp_head represents one instance of a stored program.
Definition: sp_head.h:379
sp_instr_cpush corresponds to DECLARE CURSOR, implements DECLARE CURSOR and OPEN.
Definition: sp_instr.h:1222
Base class for every SP-instruction.
Definition: sp_instr.h:104
The class represents parse-time context, which keeps track of declared variables/parameters,...
Definition: sp_pcontext.h:251
This class represents a call frame of SQL-handler (one invocation of a handler).
Definition: sp_rcontext.h:124
Handler_call_frame(const sp_handler *_handler, Sql_condition *_sql_condition, uint _continue_ip)
The constructor.
Definition: sp_rcontext.h:145
Diagnostics_area handler_da
The Diagnostics Area which will be pushed when the handler activates and popped when the handler comp...
Definition: sp_rcontext.h:138
uint continue_ip
Continue-instruction-pointer for CONTINUE-handlers.
Definition: sp_rcontext.h:134
Sql_condition * sql_condition
SQL-condition, triggered handler activation.
Definition: sp_rcontext.h:130
const sp_handler * handler
Handler definition (from parsing context).
Definition: sp_rcontext.h:127
This is an auxillary class to store entering instruction pointer for an SQL-handler.
Definition: sp_rcontext.h:104
uint first_ip
Instruction pointer to the first instruction.
Definition: sp_rcontext.h:110
sp_handler_entry(const sp_handler *_handler, uint _first_ip)
The constructor.
Definition: sp_rcontext.h:116
const sp_handler * handler
Handler definition (from parsing context).
Definition: sp_rcontext.h:107
Definition: sp_rcontext.h:76
Query_arena * callers_arena
Arena used to (re) allocate items on.
Definition: sp_rcontext.h:157
uint get_last_handler_continue_ip() const
Definition: sp_rcontext.h:242
bool m_return_value_set
Indicates whether the return value (in m_return_value_fld) has been set during execution.
Definition: sp_rcontext.h:371
sp_cursor * get_cursor(uint i) const
Definition: sp_rcontext.h:269
bool set_variable(THD *thd, uint var_idx, Item **value)
Definition: sp_rcontext.h:171
void pop_handlers(sp_pcontext *current_scope)
Pop and delete given number of sp_handler_entry instances from the handler call stack.
Definition: sp_rcontext.cc:203
bool init_var_items(THD *thd)
Create and initialize an Item-adapter (Item_field) for each SP-var field.
Definition: sp_rcontext.cc:131
Item * get_case_expr(int case_expr_id) const
Definition: sp_rcontext.h:302
Bounds_checked_array< Item * > m_var_items
Collection of Item_field proxies, each of them points to the corresponding field in m_var_table.
Definition: sp_rcontext.h:363
bool init_var_table(THD *thd)
Create and initialize a table to store SP-variables.
Definition: sp_rcontext.cc:113
~sp_rcontext()
Definition: sp_rcontext.cc:66
void pop_all_cursors()
Definition: sp_rcontext.h:267
Prealloced_array< sp_handler_entry *, 16 > m_visible_handlers
Stack of visible handlers.
Definition: sp_rcontext.h:377
bool set_return_value(THD *thd, Item **return_value_item)
Definition: sp_rcontext.cc:147
void pop_handler_frame(THD *thd)
Pop the Handler_call_frame on top of the stack of active handlers.
Definition: sp_rcontext.cc:214
bool handle_sql_condition(THD *thd, uint *ip, const sp_instr *cur_spi)
Handle current SQL condition (if any).
Definition: sp_rcontext.cc:257
bool push_handler(sp_handler *handler, uint first_ip)
Create a new sp_handler_entry instance and push it to the handler call stack.
Definition: sp_rcontext.cc:184
sp_head * sp
The stored program for which this runtime context is created.
Definition: sp_rcontext.h:165
Bounds_checked_array< Item_cache * > m_case_expr_holders
Array of CASE expression holders.
Definition: sp_rcontext.h:389
void exit_handler(THD *thd, sp_pcontext *target_scope)
Handle return from SQL-handler.
Definition: sp_rcontext.cc:228
Bounds_checked_array< sp_cursor * > m_cstack
Stack of cursors.
Definition: sp_rcontext.h:383
void operator=(sp_rcontext &)
Handler_call_frame * current_handler_frame() const
Get the Handler_call_frame representing the currently active handler.
Definition: sp_rcontext.h:207
sp_rcontext(const sp_pcontext *root_parsing_ctx, Field *return_value_fld, bool in_sub_stmt)
Definition: sp_rcontext.cc:54
bool alloc_arrays(THD *thd)
Internal function to allocate memory for arrays.
Definition: sp_rcontext.cc:96
TABLE * m_var_table
Virtual table for storing SP-variables.
Definition: sp_rcontext.h:359
Item ** get_item_addr(uint var_idx) const
Definition: sp_rcontext.h:177
void pop_cursors(uint count)
Pop and delete given number of sp_cursor instance from the cursor stack.
Definition: sp_rcontext.cc:174
uint m_ccount
Current number of cursors in m_cstack.
Definition: sp_rcontext.h:386
Field * m_return_value_fld
This is a pointer to a field, which should contain return value for stored functions (only).
Definition: sp_rcontext.h:367
sp_rcontext(const sp_rcontext &)
Item * get_item(uint var_idx) const
Definition: sp_rcontext.h:175
Item ** get_case_expr_addr(int case_expr_id) const
Definition: sp_rcontext.h:306
bool end_partial_result_set
Flag to end an open result set before start executing an SQL-handler (if one is found).
Definition: sp_rcontext.h:162
bool m_in_sub_stmt
Flag to tell if the runtime context is created for a sub-statement.
Definition: sp_rcontext.h:374
bool is_return_value_set() const
Definition: sp_rcontext.h:183
Item_cache * create_case_expr_holder(THD *thd, const Item *item) const
Create an instance of appropriate Item_cache class depending on the specified type in the callers are...
Definition: sp_rcontext.cc:412
bool push_cursor(sp_instr_cpush *i)
Create a new sp_cursor instance and push it to the cursor stack.
Definition: sp_rcontext.cc:155
bool set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr)
Set CASE expression to the specified value.
Definition: sp_rcontext.cc:426
Prealloced_array< Handler_call_frame *, 16 > m_activated_handlers
Stack of caught SQL conditions.
Definition: sp_rcontext.h:380
const sp_pcontext * m_root_parsing_ctx
Top-level (root) parsing context for this runtime context.
Definition: sp_rcontext.h:356
static sp_rcontext * create(THD *thd, const sp_pcontext *root_parsing_ctx, Field *return_value_fld)
Construct and properly initialize a new sp_rcontext instance.
Definition: sp_rcontext.cc:80
This class represents a stored program variable or a parameter (also referenced as 'SP-variable').
Definition: sp_pcontext.h:48
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
Some integer typedefs for easier portability.
static int count
Definition: myisam_ftdump.cc:42
Definition: table.h:1394
Field ** field
Definition: table.h:1433
#define NULL
Definition: types.h:54
unsigned int uint
Definition: uca-dump.cc:29