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