MySQL 8.3.0
Source Code Documentation
sp_rcontext.h
Go to the documentation of this file.
1/* Copyright (c) 2002, 2023, 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 auxiliary 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
182
183 bool set_return_value(THD *thd, Item **return_value_item);
184
186
187 /////////////////////////////////////////////////////////////////////////
188 // SQL-handlers.
189 /////////////////////////////////////////////////////////////////////////
190
191 /// Create a new sp_handler_entry instance and push it to the handler call
192 /// stack.
193 ///
194 /// @param handler SQL-handler object.
195 /// @param first_ip First instruction pointer of the handler.
196 ///
197 /// @return error flag.
198 /// @retval false on success.
199 /// @retval true on error.
200 bool push_handler(sp_handler *handler, uint first_ip);
201
202 /// Pop and delete given number of sp_handler_entry instances from the handler
203 /// call stack.
204 ///
205 /// @param current_scope The current BEGIN..END block.
206 void pop_handlers(sp_pcontext *current_scope);
207
208 /// Get the Handler_call_frame representing the currently active handler.
210 return m_activated_handlers.size() ? m_activated_handlers.back() : nullptr;
211 }
212
213 /// Handle current SQL condition (if any).
214 ///
215 /// This is the public-interface function to handle SQL conditions in
216 /// stored routines.
217 ///
218 /// @param thd Thread handle.
219 /// @param [out] ip Instruction pointer to the first handler
220 /// instruction.
221 /// @param cur_spi Current SP instruction.
222 ///
223 /// @retval true if an SQL-handler has been activated. That means, all of
224 /// the following conditions are satisfied:
225 /// - the SP-instruction raised SQL-condition(s),
226 /// - and there is an SQL-handler to process at least one of those
227 /// SQL-conditions,
228 /// - and that SQL-handler has been activated.
229 /// Note, that the return value has nothing to do with "error flag"
230 /// semantics.
231 ///
232 /// @retval false otherwise.
233 bool handle_sql_condition(THD *thd, uint *ip, const sp_instr *cur_spi);
234
235 /// Handle return from SQL-handler.
236 ///
237 /// @param thd Thread handle.
238 /// @param target_scope The BEGIN..END block, containing
239 /// the target (next) instruction.
240 void exit_handler(THD *thd, sp_pcontext *target_scope);
241
242 /// @return the continue instruction pointer of the last activated CONTINUE
243 /// handler. This function must not be called for the EXIT handlers.
245 uint ip = m_activated_handlers.back()->continue_ip;
246 assert(ip != 0);
247
248 return ip;
249 }
250
251 /////////////////////////////////////////////////////////////////////////
252 // Cursors.
253 /////////////////////////////////////////////////////////////////////////
254
255 /// Create a new sp_cursor instance and push it to the cursor stack.
256 ///
257 /// @param i Cursor-push instruction.
258 ///
259 /// @return error flag.
260 /// @retval false on success.
261 /// @retval true on error.
263
264 /// Pop and delete given number of sp_cursor instance from the cursor stack.
265 ///
266 /// @param count Number of cursors to pop & delete.
267 void pop_cursors(uint count);
268
270
271 sp_cursor *get_cursor(uint i) const { return m_cstack[i]; }
272
273 /////////////////////////////////////////////////////////////////////////
274 // CASE expressions.
275 /////////////////////////////////////////////////////////////////////////
276
277 /// Set CASE expression to the specified value.
278 ///
279 /// @param thd Thread handler.
280 /// @param case_expr_id The CASE expression identifier.
281 /// @param case_expr_item_ptr The CASE expression value
282 ///
283 /// @return error flag.
284 /// @retval false on success.
285 /// @retval true on error.
286 ///
287 /// @note The idea is to reuse Item_cache for the expression of the one
288 /// CASE statement. This optimization takes place when there is CASE
289 /// statement inside of a loop. So, in other words, we will use the same
290 /// object on each iteration instead of creating a new one for each
291 /// iteration.
292 ///
293 /// TODO
294 /// Hypothetically, a type of CASE expression can be different for each
295 /// iteration. For instance, this can happen if the expression contains
296 /// a session variable (something like @@VAR) and its type is changed
297 /// from one iteration to another.
298 ///
299 /// In order to cope with this problem, we check type each time, when we
300 /// use already created object. If the type does not match, we re-create
301 /// Item. This also can (should?) be optimized.
302 bool set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
303
304 Item *get_case_expr(int case_expr_id) const {
305 return m_case_expr_holders[case_expr_id];
306 }
307
308 Item **get_case_expr_addr(int case_expr_id) const {
309 return (Item **)m_case_expr_holders.array() + case_expr_id;
310 }
311
312 private:
313 /// Internal function to allocate memory for arrays.
314 ///
315 /// @param thd Thread handle.
316 ///
317 /// @return error flag: false on success, true in case of failure.
318 bool alloc_arrays(THD *thd);
319
320 /// Create and initialize a table to store SP-variables.
321 ///
322 /// param thd Thread handle.
323 ///
324 /// @return error flag.
325 /// @retval false on success.
326 /// @retval true on error.
327 bool init_var_table(THD *thd);
328
329 /// Create and initialize an Item-adapter (Item_field) for each SP-var field.
330 ///
331 /// param thd Thread handle.
332 ///
333 /// @return error flag.
334 /// @retval false on success.
335 /// @retval true on error.
336 bool init_var_items(THD *thd);
337
338 /// Create an instance of appropriate Item_cache class depending on the
339 /// specified type in the callers arena.
340 ///
341 /// @note We should create cache items in the callers arena, as they are
342 /// used between in several instructions.
343 ///
344 /// @param thd Thread handler.
345 /// @param item Item to get the expression type.
346 ///
347 /// @return Pointer to valid object on success, or NULL in case of error.
348 Item_cache *create_case_expr_holder(THD *thd, const Item *item) const;
349
350 bool set_variable(THD *thd, Field *field, Item **value);
351
352 /// Pop the Handler_call_frame on top of the stack of active handlers.
353 /// Also pop the matching Diagnostics Area and transfer conditions.
354 void pop_handler_frame(THD *thd);
355
356 private:
357 /// Top-level (root) parsing context for this runtime context.
359
360 /// Virtual table for storing SP-variables.
362
363 /// Collection of Item_field proxies, each of them points to the
364 /// corresponding field in m_var_table.
366
367 /// This is a pointer to a field, which should contain return value for
368 /// stored functions (only). For stored procedures, this pointer is NULL.
370
371 /// Indicates whether the return value (in m_return_value_fld) has been
372 /// set during execution.
374
375 /// Flag to tell if the runtime context is created for a sub-statement.
377
378 /// Stack of visible handlers.
380
381 /// Stack of caught SQL conditions.
383
384 /// Stack of cursors.
386
387 /// Current number of cursors in m_cstack.
389
390 /// Array of CASE expression holders.
392};
393
394///////////////////////////////////////////////////////////////////////////
395// sp_cursor declaration.
396///////////////////////////////////////////////////////////////////////////
397
398/* A mediator between stored procedures and server side cursors */
399
401 private:
402 /**
403 An interceptor of cursor result set used to implement
404 FETCH @<cname@> INTO @<varlist@>.
405 */
409
410 public:
412 uint get_field_count() { return field_count; }
414
415 bool send_eof(THD *) override { return false; }
416 bool send_data(THD *thd, const mem_root_deque<Item *> &items) override;
417 bool prepare(THD *thd, const mem_root_deque<Item *> &list,
418 Query_expression *u) override;
419 };
420
421 public:
424
425 virtual ~sp_cursor() { destroy(); }
426
427 bool open(THD *thd);
428
429 bool close();
430
431 bool is_open() const { return m_server_side_cursor != nullptr; }
432
433 bool fetch(List<sp_variable> *vars);
434
436
437 private:
439
442
443 private:
444 void destroy();
445}; // class sp_cursor
446
447#endif /* _SP_RCONTEXT_H_ */
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:250
Element_type * array() const
Definition: sql_array.h:164
Stores status of the currently executed statement.
Definition: sql_error.h:268
Definition: field.h:574
Definition: item.h:6830
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:933
Definition: sql_list.h:434
A typesafe replacement for DYNAMIC_ARRAY.
Definition: prealloced_array.h:70
Definition: sql_class.h:347
This class represents a query expression (one query block or several query blocks combined with UNION...
Definition: sql_lex.h:624
Definition: query_result.h:180
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_lexer_thd.h:35
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4548
A (partial) implementation of std::deque allocating its blocks on a MEM_ROOT.
Definition: mem_root_deque.h:110
An interceptor of cursor result set used to implement FETCH <cname> INTO <varlist>.
Definition: sp_rcontext.h:406
bool send_eof(THD *) override
Definition: sp_rcontext.h:415
uint field_count
Definition: sp_rcontext.h:408
List< sp_variable > * spvar_list
Definition: sp_rcontext.h:407
void set_spvar_list(List< sp_variable > *vars)
Definition: sp_rcontext.h:413
bool send_data(THD *thd, const mem_root_deque< Item * > &items) override
Definition: sp_rcontext.cc:534
uint get_field_count()
Definition: sp_rcontext.h:412
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:524
Query_fetch_into_spvars()
Definition: sp_rcontext.h:411
Definition: sp_rcontext.h:400
sp_instr_cpush * m_push_instr
Definition: sp_rcontext.h:441
bool is_open() const
Definition: sp_rcontext.h:431
bool open(THD *thd)
Open an SP cursor.
Definition: sp_rcontext.cc:456
bool fetch(List< sp_variable > *vars)
Definition: sp_rcontext.cc:485
sp_instr_cpush * get_push_instr()
Definition: sp_rcontext.h:435
bool close()
Definition: sp_rcontext.cc:472
virtual ~sp_cursor()
Definition: sp_rcontext.h:425
sp_cursor(sp_instr_cpush *i)
Definition: sp_rcontext.h:422
Server_side_cursor * m_server_side_cursor
Definition: sp_rcontext.h:440
void destroy()
Definition: sp_rcontext.cc:483
Query_fetch_into_spvars m_result
Definition: sp_rcontext.h:438
This class represents 'DECLARE HANDLER' statement.
Definition: sp_pcontext.h:192
sp_head represents one instance of a stored program.
Definition: sp_head.h:382
sp_instr_cpush corresponds to DECLARE CURSOR, implements DECLARE CURSOR and OPEN.
Definition: sp_instr.h:1224
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 auxiliary 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:244
bool m_return_value_set
Indicates whether the return value (in m_return_value_fld) has been set during execution.
Definition: sp_rcontext.h:373
sp_cursor * get_cursor(uint i) const
Definition: sp_rcontext.h:271
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:204
bool init_var_items(THD *thd)
Create and initialize an Item-adapter (Item_field) for each SP-var field.
Definition: sp_rcontext.cc:132
Item * get_case_expr(int case_expr_id) const
Definition: sp_rcontext.h:304
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:365
bool init_var_table(THD *thd)
Create and initialize a table to store SP-variables.
Definition: sp_rcontext.cc:114
Field * get_return_field() const
Definition: sp_rcontext.h:181
~sp_rcontext()
Definition: sp_rcontext.cc:67
void pop_all_cursors()
Definition: sp_rcontext.h:269
Prealloced_array< sp_handler_entry *, 16 > m_visible_handlers
Stack of visible handlers.
Definition: sp_rcontext.h:379
bool set_return_value(THD *thd, Item **return_value_item)
Definition: sp_rcontext.cc:148
void pop_handler_frame(THD *thd)
Pop the Handler_call_frame on top of the stack of active handlers.
Definition: sp_rcontext.cc:215
bool handle_sql_condition(THD *thd, uint *ip, const sp_instr *cur_spi)
Handle current SQL condition (if any).
Definition: sp_rcontext.cc:258
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:185
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:391
void exit_handler(THD *thd, sp_pcontext *target_scope)
Handle return from SQL-handler.
Definition: sp_rcontext.cc:229
Bounds_checked_array< sp_cursor * > m_cstack
Stack of cursors.
Definition: sp_rcontext.h:385
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:209
sp_rcontext(const sp_pcontext *root_parsing_ctx, Field *return_value_fld, bool in_sub_stmt)
Definition: sp_rcontext.cc:55
bool alloc_arrays(THD *thd)
Internal function to allocate memory for arrays.
Definition: sp_rcontext.cc:97
TABLE * m_var_table
Virtual table for storing SP-variables.
Definition: sp_rcontext.h:361
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:175
uint m_ccount
Current number of cursors in m_cstack.
Definition: sp_rcontext.h:388
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:369
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:308
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:376
bool is_return_value_set() const
Definition: sp_rcontext.h:185
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:413
bool push_cursor(sp_instr_cpush *i)
Create a new sp_cursor instance and push it to the cursor stack.
Definition: sp_rcontext.cc:156
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:427
Prealloced_array< Handler_call_frame *, 16 > m_activated_handlers
Stack of caught SQL conditions.
Definition: sp_rcontext.h:382
const sp_pcontext * m_root_parsing_ctx
Top-level (root) parsing context for this runtime context.
Definition: sp_rcontext.h:358
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:81
This class represents a stored program variable or a parameter (also referenced as 'SP-variable').
Definition: sp_pcontext.h:48
Some integer typedefs for easier portability.
static int count
Definition: myisam_ftdump.cc:44
std::list< T, ut::allocator< T > > list
Specialization of list which uses ut_allocator.
Definition: ut0new.h:2877
Definition: table.h:1403
Field ** field
Definition: table.h:1446