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